1/* 2** ----------------------------------------------------------------------------- 3** 4** Perle Specialix driver for Linux 5** Ported from existing RIO Driver for SCO sources. 6 * 7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22** 23** Module : rioinit.c 24** SID : 1.3 25** Last Modified : 11/6/98 10:33:43 26** Retrieved : 11/6/98 10:33:49 27** 28** ident @(#)rioinit.c 1.3 29** 30** ----------------------------------------------------------------------------- 31*/ 32 33#include <linux/module.h> 34#include <linux/errno.h> 35#include <linux/delay.h> 36#include <asm/io.h> 37#include <asm/system.h> 38#include <asm/string.h> 39#include <asm/uaccess.h> 40 41#include <linux/termios.h> 42#include <linux/serial.h> 43 44#include <linux/generic_serial.h> 45 46 47#include "linux_compat.h" 48#include "pkt.h" 49#include "daemon.h" 50#include "rio.h" 51#include "riospace.h" 52#include "cmdpkt.h" 53#include "map.h" 54#include "rup.h" 55#include "port.h" 56#include "riodrvr.h" 57#include "rioinfo.h" 58#include "func.h" 59#include "errors.h" 60#include "pci.h" 61 62#include "parmmap.h" 63#include "unixrup.h" 64#include "board.h" 65#include "host.h" 66#include "phb.h" 67#include "link.h" 68#include "cmdblk.h" 69#include "route.h" 70#include "cirrus.h" 71#include "rioioctl.h" 72#include "rio_linux.h" 73 74int RIOPCIinit(struct rio_info *p, int Mode); 75 76static int RIOScrub(int, u8 __iomem *, int); 77 78 79/** 80** RIOAssignAT : 81** 82** Fill out the fields in the p->RIOHosts structure now we know we know 83** we have a board present. 84** 85** bits < 0 indicates 8 bit operation requested, 86** bits > 0 indicates 16 bit operation. 87*/ 88 89int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode) 90{ 91 int bits; 92 struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr; 93 94 if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE)) 95 bits = BYTE_OPERATION; 96 else 97 bits = WORD_OPERATION; 98 99 /* 100 ** Board has passed its scrub test. Fill in all the 101 ** transient stuff. 102 */ 103 p->RIOHosts[p->RIONumHosts].Caddr = virtAddr; 104 p->RIOHosts[p->RIONumHosts].CardP = virtAddr; 105 106 /* 107 ** Revision 01 AT host cards don't support WORD operations, 108 */ 109 if (readb(&cardp->DpRevision) == 01) 110 bits = BYTE_OPERATION; 111 112 p->RIOHosts[p->RIONumHosts].Type = RIO_AT; 113 p->RIOHosts[p->RIONumHosts].Copy = rio_copy_to_card; 114 /* set this later */ 115 p->RIOHosts[p->RIONumHosts].Slot = -1; 116 p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits; 117 writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE , 118 &p->RIOHosts[p->RIONumHosts].Control); 119 writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); 120 writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE, 121 &p->RIOHosts[p->RIONumHosts].Control); 122 writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); 123 p->RIOHosts[p->RIONumHosts].UniqueNum = 124 ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)| 125 ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)| 126 ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)| 127 ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24); 128 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum); 129 130 p->RIONumHosts++; 131 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base); 132 return(1); 133} 134 135static u8 val[] = { 136#ifdef VERY_LONG_TEST 137 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 138 0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36, 139#endif 140 0xff, 0x00, 0x00 }; 141 142#define TEST_END sizeof(val) 143 144/* 145** RAM test a board. 146** Nothing too complicated, just enough to check it out. 147*/ 148int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot) 149{ 150 struct DpRam __iomem *DpRam = caddr; 151 void __iomem *ram[4]; 152 int size[4]; 153 int op, bank; 154 int nbanks; 155 156 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=%p, slot=%d\n", 157 type, DpRam, slot); 158 159 RIOHostReset(type, DpRam, slot); 160 161 /* 162 ** Scrub the memory. This comes in several banks: 163 ** DPsram1 - 7000h bytes 164 ** DPsram2 - 200h bytes 165 ** DPsram3 - 7000h bytes 166 ** scratch - 1000h bytes 167 */ 168 169 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n"); 170 171 size[0] = DP_SRAM1_SIZE; 172 size[1] = DP_SRAM2_SIZE; 173 size[2] = DP_SRAM3_SIZE; 174 size[3] = DP_SCRATCH_SIZE; 175 176 ram[0] = DpRam->DpSram1; 177 ram[1] = DpRam->DpSram2; 178 ram[2] = DpRam->DpSram3; 179 nbanks = (type == RIO_PCI) ? 3 : 4; 180 if (nbanks == 4) 181 ram[3] = DpRam->DpScratch; 182 183 184 if (nbanks == 3) { 185 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: %p(0x%x), %p(0x%x), %p(0x%x)\n", 186 ram[0], size[0], ram[1], size[1], ram[2], size[2]); 187 } else { 188 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: %p(0x%x), %p(0x%x), %p(0x%x), %p(0x%x)\n", 189 ram[0], size[0], ram[1], size[1], ram[2], size[2], ram[3], size[3]); 190 } 191 192 /* 193 ** This scrub operation will test for crosstalk between 194 ** banks. TEST_END is a magic number, and relates to the offset 195 ** within the 'val' array used by Scrub. 196 */ 197 for (op=0; op<TEST_END; op++) { 198 for (bank=0; bank<nbanks; bank++) { 199 if (RIOScrub(op, ram[bank], size[bank]) == RIO_FAIL) { 200 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n", 201 bank, op); 202 return RIO_FAIL; 203 } 204 } 205 } 206 207 rio_dprintk (RIO_DEBUG_INIT, "Test completed\n"); 208 return 0; 209} 210 211 212/* 213** Scrub an area of RAM. 214** Define PRETEST and POSTTEST for a more thorough checking of the 215** state of the memory. 216** Call with op set to an index into the above 'val' array to determine 217** which value will be written into memory. 218** Call with op set to zero means that the RAM will not be read and checked 219** before it is written. 220** Call with op not zero and the RAM will be read and compared with val[op-1] 221** to check that the data from the previous phase was retained. 222*/ 223 224static int RIOScrub(int op, u8 __iomem *ram, int size) 225{ 226 int off; 227 unsigned char oldbyte; 228 unsigned char newbyte; 229 unsigned char invbyte; 230 unsigned short oldword; 231 unsigned short newword; 232 unsigned short invword; 233 unsigned short swapword; 234 235 if (op) { 236 oldbyte = val[op-1]; 237 oldword = oldbyte | (oldbyte<<8); 238 } else 239 oldbyte = oldword = 0; /* Tell the compiler we've initilalized them. */ 240 newbyte = val[op]; 241 newword = newbyte | (newbyte<<8); 242 invbyte = ~newbyte; 243 invword = invbyte | (invbyte<<8); 244 245 /* 246 ** Check that the RAM contains the value that should have been left there 247 ** by the previous test (not applicable for pass zero) 248 */ 249 if (op) { 250 for (off=0; off<size; off++) { 251 if (readb(ram + off) != oldbyte) { 252 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, readb(ram + off)); 253 return RIO_FAIL; 254 } 255 } 256 for (off=0; off<size; off+=2) { 257 if (readw(ram + off) != oldword) { 258 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword, readw(ram + off)); 259 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram+off+1)); 260 return RIO_FAIL; 261 } 262 } 263 } 264 265 /* 266 ** Now write the INVERSE of the test data into every location, using 267 ** BYTE write operations, first checking before each byte is written 268 ** that the location contains the old value still, and checking after 269 ** the write that the location contains the data specified - this is 270 ** the BYTE read/write test. 271 */ 272 for (off=0; off<size; off++) { 273 if (op && (readb(ram + off) != oldbyte)) { 274 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, readb(ram + off)); 275 return RIO_FAIL; 276 } 277 writeb(invbyte, ram + off); 278 if (readb(ram + off) != invbyte) { 279 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, readb(ram + off)); 280 return RIO_FAIL; 281 } 282 } 283 284 /* 285 ** now, use WORD operations to write the test value into every location, 286 ** check as before that the location contains the previous test value 287 ** before overwriting, and that it contains the data value written 288 ** afterwards. 289 ** This is the WORD operation test. 290 */ 291 for (off=0; off<size; off+=2) { 292 if (readw(ram + off) != invword) { 293 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, readw(ram + off)); 294 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram+off+1)); 295 return RIO_FAIL; 296 } 297 298 writew(newword, ram + off); 299 if ( readw(ram + off) != newword ) { 300 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, readw(ram + off)); 301 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1)); 302 return RIO_FAIL; 303 } 304 } 305 306 /* 307 ** now run through the block of memory again, first in byte mode 308 ** then in word mode, and check that all the locations contain the 309 ** required test data. 310 */ 311 for (off=0; off<size; off++) { 312 if (readb(ram + off) != newbyte) { 313 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, readb(ram + off)); 314 return RIO_FAIL; 315 } 316 } 317 318 for (off=0; off<size; off+=2) { 319 if (readw(ram + off) != newword ) { 320 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, readw(ram + off)); 321 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1)); 322 return RIO_FAIL; 323 } 324 } 325 326 /* 327 ** time to check out byte swapping errors 328 */ 329 swapword = invbyte | (newbyte << 8); 330 331 for (off=0; off<size; off+=2) { 332 writeb(invbyte, &ram[off]); 333 writeb(newbyte, &ram[off+1]); 334 } 335 336 for ( off=0; off<size; off+=2 ) { 337 if (readw(ram + off) != swapword) { 338 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, readw(ram + off)); 339 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1)); 340 return RIO_FAIL; 341 } 342 writew(~swapword, ram + off); 343 } 344 345 for (off=0; off<size; off+=2) { 346 if (readb(ram + off) != newbyte) { 347 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, readb(ram + off)); 348 return RIO_FAIL; 349 } 350 if (readb(ram + off + 1) != invbyte) { 351 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, readb(ram + off + 1)); 352 return RIO_FAIL; 353 } 354 writew(newword, ram + off); 355 } 356 return 0; 357} 358 359 360int RIODefaultName(struct rio_info *p, struct Host *HostP, unsigned int UnitId) 361{ 362 memcpy(HostP->Mapping[UnitId].Name, "UNKNOWN RTA X-XX", 17); 363 HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts); 364 if ((UnitId+1) > 9) { 365 HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10); 366 HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10); 367 } 368 else { 369 HostP->Mapping[UnitId].Name[14]='1'+UnitId; 370 HostP->Mapping[UnitId].Name[15]=0; 371 } 372 return 0; 373} 374 375#define RIO_RELEASE "Linux" 376#define RELEASE_ID "1.0" 377 378static struct rioVersion stVersion; 379 380struct rioVersion *RIOVersid(void) 381{ 382 strlcpy(stVersion.version, "RIO driver for linux V1.0", 383 sizeof(stVersion.version)); 384 strlcpy(stVersion.buildDate, __DATE__, 385 sizeof(stVersion.buildDate)); 386 387 return &stVersion; 388} 389 390void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot) 391{ 392 /* 393 ** Reset the Tpu 394 */ 395 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type); 396 switch ( Type ) { 397 case RIO_AT: 398 rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n"); 399 writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION | 400 SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); 401 writeb(0xFF, &DpRamP->DpResetTpu); 402 udelay(3); 403 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); 404 writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | 405 BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); 406 writeb(0xFF, &DpRamP->DpResetTpu); 407 udelay(3); 408 break; 409 case RIO_PCI: 410 rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n"); 411 writeb(RIO_PCI_BOOT_FROM_RAM, &DpRamP->DpControl); 412 writeb(0xFF, &DpRamP->DpResetInt); 413 writeb(0xFF, &DpRamP->DpResetTpu); 414 udelay(100); 415 break; 416 default: 417 rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n"); 418 break; 419 } 420 return; 421} 422