epirawdma.c.orig
4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**************************************************************************
* *
* Copyright (C) 1995, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#include "osint.h"
#include "piint.h"
#include "rcp.h"
#include "assert.h"
/*
* Name: __osEPiRawStartDma
*
* Description:
* Based on the input direction (OS_READ or OS_WRITE), setup a DMA
* transfer between RDRAM and PI device address space.
* devAddr and dramAddr specifies the DMA buffer address of the device
* memory and RDRAM, respectively. size contains the number of bytes to
* transfer. Note that the ROM address needs to be 16-bit aligned and
* RDRAM address 64-bit aligned. Furthermore, the size must be a
* multiple of 2 bytes. Maximum transfer size is 16 MBytes (24-bit).
* If the interface is busy, return a "-1" and abort the operation.
*
*/
s32
__osEPiRawStartDma(OSPiHandle *pihandle, s32 direction, u32 devAddr,
void *dramAddr, u32 size)
{
u32 stat;
u32 domain;
#ifdef _DEBUG
/* Check for valid direction */
if ((direction != OS_READ) && (direction != OS_WRITE)) {
__osError(ERR_OSPIRAWSTARTDMA_DIR, 1, direction);
return(-1);
}
/* Need 16-bit alignment for ROM */
if (devAddr & 0x1) {
__osError(ERR_OSPIRAWSTARTDMA_DEVADDR, 1, devAddr);
return(-1);
}
/* Need 64-bit alignment for RDRAM */
if ((u32)dramAddr & 0x7) {
__osError(ERR_OSPIRAWSTARTDMA_ADDR, 1, dramAddr);
return(-1);
}
/* Size must be a multiple of 2 bytes */
if (size & 0x1) {
__osError(ERR_OSPIRAWSTARTDMA_SIZE, 1, size);
return(-1);
}
/* Check for valid range: 0 < size <= 16 MBytes */
if ((size == 0) || (size > (16*1024*1024))) {
__osError(ERR_OSPIRAWSTARTDMA_RANGE, 1, size);
return(-1);
}
#endif
stat = IO_READ(PI_STATUS_REG);
while (stat & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) {
stat = IO_READ(PI_STATUS_REG);
}
/* Configuring the PI if needed */
domain = (u32)pihandle->domain;
if (__osCurrentHandle[domain]->type != pihandle->type) {
OSPiHandle *cHandle = __osCurrentHandle[domain];
if (domain == PI_DOMAIN1) {
if (cHandle->latency != pihandle->latency)
IO_WRITE(PI_BSD_DOM1_LAT_REG,pihandle->latency);
if (cHandle->pageSize != pihandle->pageSize)
IO_WRITE(PI_BSD_DOM1_PGS_REG,pihandle->pageSize);
if (cHandle->relDuration != pihandle->relDuration)
IO_WRITE(PI_BSD_DOM1_RLS_REG,
pihandle->relDuration);
if (cHandle->pulse != pihandle->pulse)
IO_WRITE(PI_BSD_DOM1_PWD_REG,pihandle->pulse);
} else {
if (cHandle->latency != pihandle->latency)
IO_WRITE(PI_BSD_DOM2_LAT_REG,pihandle->latency);
if (cHandle->pageSize != pihandle->pageSize)
IO_WRITE(PI_BSD_DOM2_PGS_REG,pihandle->pageSize);
if (cHandle->relDuration != pihandle->relDuration)
IO_WRITE(PI_BSD_DOM2_RLS_REG,
pihandle->relDuration);
if (cHandle->pulse != pihandle->pulse)
IO_WRITE(PI_BSD_DOM2_PWD_REG,pihandle->pulse);
}
cHandle->type = pihandle->type;
cHandle->latency = pihandle->latency;
cHandle->pageSize = pihandle->pageSize;
cHandle->relDuration = pihandle->relDuration;
cHandle->pulse = pihandle->pulse;
}
IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS((u32)pihandle->baseAddress|devAddr));
/* Note that actual programmed size of transfer = size - 1 */
switch (direction) {
case OS_READ: { /* PI -> RDRAM */
IO_WRITE(PI_WR_LEN_REG, size-1);
break;
}
case OS_WRITE: { /* PI <- RDRAM */
IO_WRITE(PI_RD_LEN_REG, size-1);
break;
}
default: {
return(-1);
}
}
return(0);
} /* __osEPiRawStartDma */