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