home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / DriverKit / AMDPCSCSIDriver / AMDPCSCSIDriver_reloc.tproj / AMD_Regs.h < prev    next >
Encoding:
Text File  |  1995-02-10  |  8.5 KB  |  316 lines

  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. }
  316.