|
|
1.1 root 1: /* Copyright (c) 1994 NeXT Computer, Inc. All rights reserved.
2: *
3: * AMD_Regs.h - register defintions for AMD 53C974/79C974 SCSI/PCI chip.
4: *
5: * HISTORY
6: * 21 Oct 94 Doug Mitchell at NeXT
7: * Created.
8: */
9:
10: #import "ioPorts.h"
11:
12: #define AMD_PCI_REGISTER_SPACE 0x60
13: #define AMD_PCI_REGISTER_OFFSET 0 /* FIXME */
14:
15: /*
16: * SCSI registers. All are byte-wide.
17: */
18: #define currXfrCntLow 0x00 // r/o
19: #define startXfrCntLow 0x00 // w/o
20: #define currXfrCntMid 0x04 // r/o
21: #define startXfrCntMid 0x04 // w/o
22: #define scsiFifo 0x08 // r/w
23: #define scsiCmd 0x0c // r/w
24: #define scsiStat 0x10 // r/o
25: #define scsiDestID 0x10 // w/o
26: #define intrStatus 0x14 // r/o
27: #define scsiTimeout 0x14 // w/o
28: #define internState 0x18 // r/o
29: #define syncPeriod 0x18 // w/o
30: #define currFifoState 0x1c // r/o
31: #define syncOffset 0x1c // w/o
32: #define control1 0x20 // r/w
33: #define clockFactor 0x24 // w/o
34: #define control2 0x2c // r/w
35: #define control3 0x30 // r/w
36: #define control4 0x34 // r/w
37: #define currXfrCntHi 0x38 // r/o
38: #define startXfrCntHi 0x38 // w/o
39:
40: /*
41: * Macros for reading and writing SCSI registers.
42: * These assume the presence of a local or instance variable ioBase.
43: */
44: #define REG_PORT(reg) (ioBase + reg)
45: #define READ_REG(reg) inb(REG_PORT(reg))
46: #define WRITE_REG(reg, data) outb(REG_PORT(reg), data)
47:
48: /*
49: * Miscellaneous commands.
50: */
51: #define SCMD_NOP 0x00
52: #define SCMD_CLEAR_FIFO 0x01
53: #define SCMD_RESET_DEVICE 0x02
54: #define SCMD_RESET_SCSI 0x03
55:
56: /*
57: * idle state commands.
58: */
59: #define SCMD_SELECT 0x41 // select w/o ATN, cdb
60: #define SCMD_SELECT_ATN 0x42 // select, ATN, 1 msg byte, cdb
61: #define SCMD_SELECT_ATN_STOP 0x43 // select, ATN, 1 msg byte, stop
62: #define SCMD_ENABLE_SELECT 0x44 // enable select/reselect
63: #define SCMD_DISABLE_SELECT 0x45 // disable select/reselect
64: #define SCMD_SELECT_ATN_3 0x46 // select, ATN, 3 msg bytes, cdb
65:
66: /*
67: * initiator mode commands.
68: */
69: #define SCMD_TRANSFER_INFO 0x10
70: #define SCMD_INIT_CMD_CMPLT 0x11
71: #define SCMD_MSG_ACCEPTED 0x12
72: #define SCMD_TRANSFER_PAD 0x18
73: #define SCMD_SET_ATN 0x1a
74: #define SCMD_CLR_ATN 0x1b
75:
76: /*
77: * OR this with command to enable DMA.
78: */
79: #define SCMD_ENABLEDMA 0x80
80:
81: /*
82: * status register (scsiStat)
83: */
84: #define SS_INTERRUPT 0x80 // interrupt pending
85: #define SS_ILLEGALOP 0x40 // illegal operation
86: #define SS_PARITYERROR 0x20 // SCSI bus parity error
87: #define SS_COUNTZERO 0x10 // transfer count == 0
88: #define SS_PHASEMASK 0x07 // SCSI bus phase mask
89:
90: /*
91: * internal state register (internState)
92: */
93: #define INS_SYNC_FULL 0x10 // sync offset buffer full
94: #define INS_STATE_MASK 0x07
95:
96: /*
97: * interrupt status register (intrStatus)
98: */
99: #define IS_SCSIRESET 0x80 // SCSI bus reset detected
100: #define IS_ILLEGALCMD 0x40 // illegal cmd issued
101: #define IS_DISCONNECT 0x20 // target disconnected
102: #define IS_SERVICE_REQ 0x10
103: #define IS_SUCCESSFUL_OP 0x08
104: #define IS_RESELECTED 0x04 // reselected as initiator
105:
106: /*
107: * FIFO state register (currFifoState)
108: */
109: #define FS_FIFO_LEVEL_MASK 0x1f
110:
111: /*
112: * Sync offset register (syncOffset)
113: * We're not messing with these RAD/RAA bits just yet...
114: */
115: #define SOR_RAD_MASK 0xc0 // req/ack deassertion
116: #define SOR_RAD_DEFAULT 0x00
117: #define SOR_RAA_MASK 0x30 // req/ack assertion
118: #define SOR_RAA_DEFAULT 0x00
119:
120: /*
121: * Control register 1 (control1)
122: */
123: #define CR1_EXTEND_TIMING 0x80 // extended timing mode
124: #define CR1_RESET_INTR_DIS 0x40 // disable SCSI reset interrupt
125: #define CR1_PERR_ENABLE 0x10 // enable parity error reporting
126: #define CR1_SCSI_ID 0x07 // SCSI ID bits
127:
128: /*
129: * Control register 2 (control2)
130: */
131: #define CR2_ENABLE_FEAT 0x40 // enable extended features
132:
133: /*
134: * Control register 3 (control3)
135: */
136: #define CR3_ADDL_ID_CHECK 0x80 // enable additional ID check
137: #define CR3_FAST_SCSI 0x10 // enable fast SCSI
138: #define CR3_FAST_CLOCK 0x08 // fast clock
139:
140: /*
141: * Control register 4 (control4)
142: */
143: #define CR4_GLITCH_MASK 0xc0 // glitch eater bits
144: #define CR4_GLITCH_12 0x00 // 12 ns
145: #define CR4_GLITCH_25 0x80 // 25 ns
146: #define CR4_GLITCH_35 0x40 // 35 ns
147: #define CR4_GLITCH_0 0xc0 // 0 ns
148: #define CR4_REDUCE_PWR 0x20 // reduced power mode
149: #define CR4_ACTIVE_NEG_MASK 0x0c // active negation control bits
150: #define CR4_ACTIVE_NEG_DISABLE 0x00 // active negation disabled
151: #define CR4_ACTIVE_NEG_RA 0x08 // active negation on REQ and ACK
152: #define CR4_ACTIVE_NEG_ALL 0x04 // active negation on REQ, ACK, data
153:
154: /*
155: * DMA registers. All are 32 bits.
156: */
157: #define dmaCommand 0x40 // r/w
158: #define dmaStartCount 0x44 // r/w
159: #define dmaStartAddrs 0x48 // r/w
160: #define dmaWorkByteCount 0x4c // r/o
161: #define dmaWorkAddrs 0x50 // r/o
162: #define dmaStatus 0x54 // r/o
163: #define dmaStartMdlAddrs 0x58 // r/w
164: #define dmaWorkMdlAddrs 0x5c // r/o
165:
166: /*
167: * Macros for reading and writing DMA registers.
168: * These assume the presence of a local or instance variable ioBase.
169: */
170: #define READ_REGL(reg) inl(REG_PORT(reg))
171: #define WRITE_REGL(reg, data) outl(REG_PORT(reg), data);
172:
173: /*
174: * DMA command register (dmaCommand)
175: */
176: #define DC_DIR 0x80 // direction
177: #define DC_DIR_READ 0x80 // scsi --> memory
178: #define DC_DIR_WRITE 0x00 // scsi <-- memory
179: #define DC_INTR_ENABLE 0x40 // enable DMA interrupts
180: #define DC_PAGE_INTR_ENABLE 0x20 // enable per-page interrupts
181: #define DC_MDL 0x10 // enable MDL
182: #define DC_DIAG 0x04 // diagnostic
183: #define DC_CMD_MASK 0x03 // command bits
184: #define DC_CMD_IDLE 0x00
185: #define DC_CMD_BLAST 0x01
186: #define DC_CMD_ABORT 0x02
187: #define DC_CMD_START 0x03
188:
189: /*
190: * DMA status register (dmaStatus)
191: */
192: #define DS_BLAST_COMPLETE 0x20 // DMA Blast command complete
193: #define DS_SCSI_INTR 0x10 // SCSI interrupt pending
194: #define DS_DMA_COMPLETE 0x08 // DMA transfer complete
195: #define DS_ABORT 0x04 // DMA transfer aborted
196: #define DS_DMA_ERROR 0x02 // DMA error occurred
197: #define DS_POWER_DOWN 0x01 // power down pin state
198:
199: /*
200: * Misc. chip constants.
201: */
202: #define AMD_DMA_PAGE_SIZE 0x1000
203: #define AMD_DMA_PAGE_MASK 0xfff
204: #define AMD_TRUNC_PAGE(x) ((vm_offset_t)(((vm_offset_t)(x)) & \
205: ~AMD_DMA_PAGE_MASK))
206: #define AMD_ROUND_PAGE(x) ((vm_offset_t)((((vm_offset_t)(x)) + \
207: AMD_DMA_PAGE_MASK) & ~AMD_DMA_PAGE_MASK))
208:
209: /*
210: * DMA alignment requirements.
211: */
212: #define AMD_READ_START_ALIGN 4
213: #define AMD_WRITE_START_ALIGN 4
214: #define AMD_READ_LENGTH_ALIGN 0
215: #define AMD_WRITE_LENGTH_ALIGN 0
216:
217: /*
218: * We are ID 7, by convention.
219: */
220: #define AMD_SCSI_ID 7
221:
222: /*
223: * Default clock rate, in MHz, in case it's not in the instance table.
224: */
225: #define AMD_DEFAULT_CLOCK 40
226:
227: /*
228: * Clock Conversion factor.
229: */
230: #define AMD_CLOCK_FACTOR(clockRate) ((clockRate + 4) / 5)
231:
232: /*
233: * Calculate select timeout register based on clock rate, select timeout,
234: * and clocking factor.
235: *
236: * The offical formula is:
237: * reg = ((select timeout in s) * (clock rate in hz)) /
238: * (8192 * clock factor)
239: *
240: * Change select timeout to ms and clock rate to MHz, amd multiply
241: * numerator by 1000...
242: *
243: * reg = ((select timeout in ms) * (clock rate in Mhz) * 1000) /
244: * (8192 * clock factor)
245: */
246: static inline unsigned amdSelectTimeout(
247: unsigned selto, // ms
248: unsigned clockRate) // MHz
249: {
250: unsigned denom; // for roundup
251: unsigned factor;
252:
253: factor = AMD_CLOCK_FACTOR(clockRate);
254: denom = 8192 * factor;
255:
256: return (((selto * clockRate * 1000) + denom - 1) / denom);
257: }
258:
259: /*
260: * 79C974 actually times out a bit faster than the official formula says it
261: * should. SCSI spec says timeout should be 250 ms; let's cut some slack...
262: */
263: #define AMD_SELECT_TO 300
264:
265: /*
266: * Sync negotiation constants and inlines.
267: */
268:
269: /*
270: * Max sync offset of 53C974.
271: */
272: #define AMD_MAX_SYNC_OFFSET 15
273:
274: /*
275: * Macros to convert the value in perTargetData.syncXferPeriod to and
276: * from the value specified in a SDTR message.
277: */
278: #define NS_PERIOD_TO_SDTR(period) (period / 4)
279: #define SDTR_TO_NS_PERIOD(sdtr) (sdtr * 4)
280:
281: /*
282: * Default (and desired) minimum clock periods in ns.
283: */
284: #define MIN_PERIOD_FASTCLK_FASTSCSI 100
285: #define MIN_PERIOD_NORM 200
286:
287: /*
288: * Routine to convert the value in perTargetData.syncXferPeriod to
289: * the value used in syncPeriod register. The value of syncPeriod
290: * rounds up to round down the frequency.
291: */
292: static inline unsigned nsPeriodToSyncPeriodReg(
293: unsigned char nsPeriod, // desired period in ns
294: unsigned fastSCSI, // value of control3.CR3_FAST_SCSI
295: unsigned clockRate) // in MHz
296: {
297: BOOL fastClock;
298: unsigned clockPeriod; // in ns
299:
300: fastClock = (clockRate > 25) ? YES : NO;
301: clockPeriod = 1000 / clockRate;
302:
303: if(fastClock && !fastSCSI) {
304: /*
305: * reg = (clocks per period) - 1.
306: */
307: return (((nsPeriod + clockPeriod - 1) / clockPeriod) - 1);
308: }
309: else {
310: /*
311: * reg = clocks per period.
312: */
313: return ((nsPeriod + clockPeriod - 1) / clockPeriod);
314: }
315: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.