1 /* 2 * PMC551 PCI Mezzanine Ram Device 3 * 4 * Author: 5 * Mark Ferrell <mferrell@mvista.com> 6 * Copyright 1999,2000 Nortel Networks 7 * 8 * License: 9 * As part of this driver was derived from the slram.c driver it 10 * falls under the same license, which is GNU General Public 11 * License v2 12 * 13 * Description: 14 * This driver is intended to support the PMC551 PCI Ram device 15 * from Ramix Inc. The PMC551 is a PMC Mezzanine module for 16 * cPCI embedded systems. The device contains a single SROM 17 * that initially programs the V370PDC chipset onboard the 18 * device, and various banks of DRAM/SDRAM onboard. This driver 19 * implements this PCI Ram device as an MTD (Memory Technology 20 * Device) so that it can be used to hold a file system, or for 21 * added swap space in embedded systems. Since the memory on 22 * this board isn't as fast as main memory we do not try to hook 23 * it into main memory as that would simply reduce performance 24 * on the system. Using it as a block device allows us to use 25 * it as high speed swap or for a high speed disk device of some 26 * sort. Which becomes very useful on diskless systems in the 27 * embedded market I might add. 28 * 29 * Notes: 30 * Due to what I assume is more buggy SROM, the 64M PMC551 I 31 * have available claims that all 4 of its DRAM banks have 64MiB 32 * of ram configured (making a grand total of 256MiB onboard). 33 * This is slightly annoying since the BAR0 size reflects the 34 * aperture size, not the dram size, and the V370PDC supplies no 35 * other method for memory size discovery. This problem is 36 * mostly only relevant when compiled as a module, as the 37 * unloading of the module with an aperture size smaller than 38 * the ram will cause the driver to detect the onboard memory 39 * size to be equal to the aperture size when the module is 40 * reloaded. Soooo, to help, the module supports an msize 41 * option to allow the specification of the onboard memory, and 42 * an asize option, to allow the specification of the aperture 43 * size. The aperture must be equal to or less then the memory 44 * size, the driver will correct this if you screw it up. This 45 * problem is not relevant for compiled in drivers as compiled 46 * in drivers only init once. 47 * 48 * Credits: 49 * Saeed Karamooz <saeed@ramix.com> of Ramix INC. for the 50 * initial example code of how to initialize this device and for 51 * help with questions I had concerning operation of the device. 52 * 53 * Most of the MTD code for this driver was originally written 54 * for the slram.o module in the MTD drivers package which 55 * allows the mapping of system memory into an MTD device. 56 * Since the PMC551 memory module is accessed in the same 57 * fashion as system memory, the slram.c code became a very nice 58 * fit to the needs of this driver. All we added was PCI 59 * detection/initialization to the driver and automatically figure 60 * out the size via the PCI detection.o, later changes by Corey 61 * Minyard set up the card to utilize a 1M sliding apature. 62 * 63 * Corey Minyard <minyard@nortelnetworks.com> 64 * * Modified driver to utilize a sliding aperture instead of 65 * mapping all memory into kernel space which turned out to 66 * be very wasteful. 67 * * Located a bug in the SROM's initialization sequence that 68 * made the memory unusable, added a fix to code to touch up 69 * the DRAM some. 70 * 71 * Bugs/FIXMEs: 72 * * MUST fix the init function to not spin on a register 73 * waiting for it to set .. this does not safely handle busted 74 * devices that never reset the register correctly which will 75 * cause the system to hang w/ a reboot being the only chance at 76 * recover. [sort of fixed, could be better] 77 * * Add I2C handling of the SROM so we can read the SROM's information 78 * about the aperture size. This should always accurately reflect the 79 * onboard memory size. 80 * * Comb the init routine. It's still a bit cludgy on a few things. 81 */ 82 83 #include <linux/kernel.h> 84 #include <linux/module.h> 85 #include <asm/uaccess.h> 86 #include <linux/types.h> 87 #include <linux/init.h> 88 #include <linux/ptrace.h> 89 #include <linux/slab.h> 90 #include <linux/string.h> 91 #include <linux/timer.h> 92 #include <linux/major.h> 93 #include <linux/fs.h> 94 #include <linux/ioctl.h> 95 #include <asm/io.h> 96 #include <asm/system.h> 97 #include <linux/pci.h> 98 99 #include <linux/mtd/mtd.h> 100 #include <linux/mtd/pmc551.h> 101 #include <linux/mtd/compatmac.h> 102 103 static struct mtd_info *pmc551list; 104 105 static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) 106 { 107 struct mypriv *priv = mtd->priv; 108 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 109 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 110 unsigned long end; 111 u_char *ptr; 112 size_t retlen; 113 114 #ifdef CONFIG_MTD_PMC551_DEBUG 115 printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr, 116 (long)instr->len); 117 #endif 118 119 end = instr->addr + instr->len - 1; 120 121 /* Is it past the end? */ 122 if (end > mtd->size) { 123 #ifdef CONFIG_MTD_PMC551_DEBUG 124 printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n", 125 (long)end, (long)mtd->size); 126 #endif 127 return -EINVAL; 128 } 129 130 eoff_hi = end & ~(priv->asize - 1); 131 soff_hi = instr->addr & ~(priv->asize - 1); 132 eoff_lo = end & (priv->asize - 1); 133 soff_lo = instr->addr & (priv->asize - 1); 134 135 pmc551_point(mtd, instr->addr, instr->len, &retlen, 136 (void **)&ptr, NULL); 137 138 if (soff_hi == eoff_hi || mtd->size == priv->asize) { 139 /* The whole thing fits within one access, so just one shot 140 will do it. */ 141 memset(ptr, 0xff, instr->len); 142 } else { 143 /* We have to do multiple writes to get all the data 144 written. */ 145 while (soff_hi != eoff_hi) { 146 #ifdef CONFIG_MTD_PMC551_DEBUG 147 printk(KERN_DEBUG "pmc551_erase() soff_hi: %ld, " 148 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 149 #endif 150 memset(ptr, 0xff, priv->asize); 151 if (soff_hi + priv->asize >= mtd->size) { 152 goto out; 153 } 154 soff_hi += priv->asize; 155 pmc551_point(mtd, (priv->base_map0 | soff_hi), 156 priv->asize, &retlen, 157 (void **)&ptr, NULL); 158 } 159 memset(ptr, 0xff, eoff_lo); 160 } 161 162 out: 163 instr->state = MTD_ERASE_DONE; 164 #ifdef CONFIG_MTD_PMC551_DEBUG 165 printk(KERN_DEBUG "pmc551_erase() done\n"); 166 #endif 167 168 mtd_erase_callback(instr); 169 return 0; 170 } 171 172 static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, 173 size_t *retlen, void **virt, resource_size_t *phys) 174 { 175 struct mypriv *priv = mtd->priv; 176 u32 soff_hi; 177 u32 soff_lo; 178 179 #ifdef CONFIG_MTD_PMC551_DEBUG 180 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); 181 #endif 182 183 if (from + len > mtd->size) { 184 #ifdef CONFIG_MTD_PMC551_DEBUG 185 printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n", 186 (long)from + len, (long)mtd->size); 187 #endif 188 return -EINVAL; 189 } 190 191 /* can we return a physical address with this driver? */ 192 if (phys) 193 return -EINVAL; 194 195 soff_hi = from & ~(priv->asize - 1); 196 soff_lo = from & (priv->asize - 1); 197 198 /* Cheap hack optimization */ 199 if (priv->curr_map0 != from) { 200 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0, 201 (priv->base_map0 | soff_hi)); 202 priv->curr_map0 = soff_hi; 203 } 204 205 *virt = priv->start + soff_lo; 206 *retlen = len; 207 return 0; 208 } 209 210 static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 211 { 212 #ifdef CONFIG_MTD_PMC551_DEBUG 213 printk(KERN_DEBUG "pmc551_unpoint()\n"); 214 #endif 215 } 216 217 static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, 218 size_t * retlen, u_char * buf) 219 { 220 struct mypriv *priv = mtd->priv; 221 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 222 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 223 unsigned long end; 224 u_char *ptr; 225 u_char *copyto = buf; 226 227 #ifdef CONFIG_MTD_PMC551_DEBUG 228 printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n", 229 (long)from, (long)len, (long)priv->asize); 230 #endif 231 232 end = from + len - 1; 233 234 /* Is it past the end? */ 235 if (end > mtd->size) { 236 #ifdef CONFIG_MTD_PMC551_DEBUG 237 printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n", 238 (long)end, (long)mtd->size); 239 #endif 240 return -EINVAL; 241 } 242 243 soff_hi = from & ~(priv->asize - 1); 244 eoff_hi = end & ~(priv->asize - 1); 245 soff_lo = from & (priv->asize - 1); 246 eoff_lo = end & (priv->asize - 1); 247 248 pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL); 249 250 if (soff_hi == eoff_hi) { 251 /* The whole thing fits within one access, so just one shot 252 will do it. */ 253 memcpy(copyto, ptr, len); 254 copyto += len; 255 } else { 256 /* We have to do multiple writes to get all the data 257 written. */ 258 while (soff_hi != eoff_hi) { 259 #ifdef CONFIG_MTD_PMC551_DEBUG 260 printk(KERN_DEBUG "pmc551_read() soff_hi: %ld, " 261 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 262 #endif 263 memcpy(copyto, ptr, priv->asize); 264 copyto += priv->asize; 265 if (soff_hi + priv->asize >= mtd->size) { 266 goto out; 267 } 268 soff_hi += priv->asize; 269 pmc551_point(mtd, soff_hi, priv->asize, retlen, 270 (void **)&ptr, NULL); 271 } 272 memcpy(copyto, ptr, eoff_lo); 273 copyto += eoff_lo; 274 } 275 276 out: 277 #ifdef CONFIG_MTD_PMC551_DEBUG 278 printk(KERN_DEBUG "pmc551_read() done\n"); 279 #endif 280 *retlen = copyto - buf; 281 return 0; 282 } 283 284 static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, 285 size_t * retlen, const u_char * buf) 286 { 287 struct mypriv *priv = mtd->priv; 288 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 289 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 290 unsigned long end; 291 u_char *ptr; 292 const u_char *copyfrom = buf; 293 294 #ifdef CONFIG_MTD_PMC551_DEBUG 295 printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n", 296 (long)to, (long)len, (long)priv->asize); 297 #endif 298 299 end = to + len - 1; 300 /* Is it past the end? or did the u32 wrap? */ 301 if (end > mtd->size) { 302 #ifdef CONFIG_MTD_PMC551_DEBUG 303 printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, " 304 "size: %ld, to: %ld)\n", (long)end, (long)mtd->size, 305 (long)to); 306 #endif 307 return -EINVAL; 308 } 309 310 soff_hi = to & ~(priv->asize - 1); 311 eoff_hi = end & ~(priv->asize - 1); 312 soff_lo = to & (priv->asize - 1); 313 eoff_lo = end & (priv->asize - 1); 314 315 pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL); 316 317 if (soff_hi == eoff_hi) { 318 /* The whole thing fits within one access, so just one shot 319 will do it. */ 320 memcpy(ptr, copyfrom, len); 321 copyfrom += len; 322 } else { 323 /* We have to do multiple writes to get all the data 324 written. */ 325 while (soff_hi != eoff_hi) { 326 #ifdef CONFIG_MTD_PMC551_DEBUG 327 printk(KERN_DEBUG "pmc551_write() soff_hi: %ld, " 328 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 329 #endif 330 memcpy(ptr, copyfrom, priv->asize); 331 copyfrom += priv->asize; 332 if (soff_hi >= mtd->size) { 333 goto out; 334 } 335 soff_hi += priv->asize; 336 pmc551_point(mtd, soff_hi, priv->asize, retlen, 337 (void **)&ptr, NULL); 338 } 339 memcpy(ptr, copyfrom, eoff_lo); 340 copyfrom += eoff_lo; 341 } 342 343 out: 344 #ifdef CONFIG_MTD_PMC551_DEBUG 345 printk(KERN_DEBUG "pmc551_write() done\n"); 346 #endif 347 *retlen = copyfrom - buf; 348 return 0; 349 } 350 351 /* 352 * Fixup routines for the V370PDC 353 * PCI device ID 0x020011b0 354 * 355 * This function basicly kick starts the DRAM oboard the card and gets it 356 * ready to be used. Before this is done the device reads VERY erratic, so 357 * much that it can crash the Linux 2.2.x series kernels when a user cat's 358 * /proc/pci .. though that is mainly a kernel bug in handling the PCI DEVSEL 359 * register. FIXME: stop spinning on registers .. must implement a timeout 360 * mechanism 361 * returns the size of the memory region found. 362 */ 363 static u32 fixup_pmc551(struct pci_dev *dev) 364 { 365 #ifdef CONFIG_MTD_PMC551_BUGFIX 366 u32 dram_data; 367 #endif 368 u32 size, dcmd, cfg, dtmp; 369 u16 cmd, tmp, i; 370 u8 bcmd, counter; 371 372 /* Sanity Check */ 373 if (!dev) { 374 return -ENODEV; 375 } 376 377 /* 378 * Attempt to reset the card 379 * FIXME: Stop Spinning registers 380 */ 381 counter = 0; 382 /* unlock registers */ 383 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5); 384 /* read in old data */ 385 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd); 386 /* bang the reset line up and down for a few */ 387 for (i = 0; i < 10; i++) { 388 counter = 0; 389 bcmd &= ~0x80; 390 while (counter++ < 100) { 391 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 392 } 393 counter = 0; 394 bcmd |= 0x80; 395 while (counter++ < 100) { 396 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 397 } 398 } 399 bcmd |= (0x40 | 0x20); 400 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 401 402 /* 403 * Take care and turn off the memory on the device while we 404 * tweak the configurations 405 */ 406 pci_read_config_word(dev, PCI_COMMAND, &cmd); 407 tmp = cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); 408 pci_write_config_word(dev, PCI_COMMAND, tmp); 409 410 /* 411 * Disable existing aperture before probing memory size 412 */ 413 pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd); 414 dtmp = (dcmd | PMC551_PCI_MEM_MAP_ENABLE | PMC551_PCI_MEM_MAP_REG_EN); 415 pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp); 416 /* 417 * Grab old BAR0 config so that we can figure out memory size 418 * This is another bit of kludge going on. The reason for the 419 * redundancy is I am hoping to retain the original configuration 420 * previously assigned to the card by the BIOS or some previous 421 * fixup routine in the kernel. So we read the old config into cfg, 422 * then write all 1's to the memory space, read back the result into 423 * "size", and then write back all the old config. 424 */ 425 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &cfg); 426 #ifndef CONFIG_MTD_PMC551_BUGFIX 427 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ~0); 428 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &size); 429 size = (size & PCI_BASE_ADDRESS_MEM_MASK); 430 size &= ~(size - 1); 431 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, cfg); 432 #else 433 /* 434 * Get the size of the memory by reading all the DRAM size values 435 * and adding them up. 436 * 437 * KLUDGE ALERT: the boards we are using have invalid column and 438 * row mux values. We fix them here, but this will break other 439 * memory configurations. 440 */ 441 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data); 442 size = PMC551_DRAM_BLK_GET_SIZE(dram_data); 443 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 444 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 445 pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data); 446 447 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data); 448 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 449 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 450 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 451 pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data); 452 453 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data); 454 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 455 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 456 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 457 pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data); 458 459 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data); 460 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 461 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 462 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 463 pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data); 464 465 /* 466 * Oops .. something went wrong 467 */ 468 if ((size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) { 469 return -ENODEV; 470 } 471 #endif /* CONFIG_MTD_PMC551_BUGFIX */ 472 473 if ((cfg & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) { 474 return -ENODEV; 475 } 476 477 /* 478 * Precharge Dram 479 */ 480 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0400); 481 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x00bf); 482 483 /* 484 * Wait until command has gone through 485 * FIXME: register spinning issue 486 */ 487 do { 488 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 489 if (counter++ > 100) 490 break; 491 } while ((PCI_COMMAND_IO) & cmd); 492 493 /* 494 * Turn on auto refresh 495 * The loop is taken directly from Ramix's example code. I assume that 496 * this must be held high for some duration of time, but I can find no 497 * documentation refrencing the reasons why. 498 */ 499 for (i = 1; i <= 8; i++) { 500 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0df); 501 502 /* 503 * Make certain command has gone through 504 * FIXME: register spinning issue 505 */ 506 counter = 0; 507 do { 508 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 509 if (counter++ > 100) 510 break; 511 } while ((PCI_COMMAND_IO) & cmd); 512 } 513 514 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0020); 515 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0ff); 516 517 /* 518 * Wait until command completes 519 * FIXME: register spinning issue 520 */ 521 counter = 0; 522 do { 523 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 524 if (counter++ > 100) 525 break; 526 } while ((PCI_COMMAND_IO) & cmd); 527 528 pci_read_config_dword(dev, PMC551_DRAM_CFG, &dcmd); 529 dcmd |= 0x02000000; 530 pci_write_config_dword(dev, PMC551_DRAM_CFG, dcmd); 531 532 /* 533 * Check to make certain fast back-to-back, if not 534 * then set it so 535 */ 536 pci_read_config_word(dev, PCI_STATUS, &cmd); 537 if ((cmd & PCI_COMMAND_FAST_BACK) == 0) { 538 cmd |= PCI_COMMAND_FAST_BACK; 539 pci_write_config_word(dev, PCI_STATUS, cmd); 540 } 541 542 /* 543 * Check to make certain the DEVSEL is set correctly, this device 544 * has a tendancy to assert DEVSEL and TRDY when a write is performed 545 * to the memory when memory is read-only 546 */ 547 if ((cmd & PCI_STATUS_DEVSEL_MASK) != 0x0) { 548 cmd &= ~PCI_STATUS_DEVSEL_MASK; 549 pci_write_config_word(dev, PCI_STATUS, cmd); 550 } 551 /* 552 * Set to be prefetchable and put everything back based on old cfg. 553 * it's possible that the reset of the V370PDC nuked the original 554 * setup 555 */ 556 /* 557 cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH; 558 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg ); 559 */ 560 561 /* 562 * Turn PCI memory and I/O bus access back on 563 */ 564 pci_write_config_word(dev, PCI_COMMAND, 565 PCI_COMMAND_MEMORY | PCI_COMMAND_IO); 566 #ifdef CONFIG_MTD_PMC551_DEBUG 567 /* 568 * Some screen fun 569 */ 570 printk(KERN_DEBUG "pmc551: %d%sB (0x%x) of %sprefetchable memory at " 571 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ? 572 size >> 10 : size >> 20, 573 (size < 1024) ? "" : (size < 1048576) ? "Ki" : "Mi", size, 574 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "", 575 (unsigned long long)pci_resource_start(dev, 0)); 576 577 /* 578 * Check to see the state of the memory 579 */ 580 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dcmd); 581 printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n" 582 "pmc551: DRAM_BLK0 Size: %d at %d\n" 583 "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n", 584 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 585 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 586 PMC551_DRAM_BLK_GET_SIZE(dcmd), 587 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 588 ((dcmd >> 9) & 0xF)); 589 590 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dcmd); 591 printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n" 592 "pmc551: DRAM_BLK1 Size: %d at %d\n" 593 "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n", 594 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 595 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 596 PMC551_DRAM_BLK_GET_SIZE(dcmd), 597 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 598 ((dcmd >> 9) & 0xF)); 599 600 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dcmd); 601 printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n" 602 "pmc551: DRAM_BLK2 Size: %d at %d\n" 603 "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n", 604 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 605 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 606 PMC551_DRAM_BLK_GET_SIZE(dcmd), 607 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 608 ((dcmd >> 9) & 0xF)); 609 610 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dcmd); 611 printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n" 612 "pmc551: DRAM_BLK3 Size: %d at %d\n" 613 "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n", 614 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 615 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 616 PMC551_DRAM_BLK_GET_SIZE(dcmd), 617 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 618 ((dcmd >> 9) & 0xF)); 619 620 pci_read_config_word(dev, PCI_COMMAND, &cmd); 621 printk(KERN_DEBUG "pmc551: Memory Access %s\n", 622 (((0x1 << 1) & cmd) == 0) ? "off" : "on"); 623 printk(KERN_DEBUG "pmc551: I/O Access %s\n", 624 (((0x1 << 0) & cmd) == 0) ? "off" : "on"); 625 626 pci_read_config_word(dev, PCI_STATUS, &cmd); 627 printk(KERN_DEBUG "pmc551: Devsel %s\n", 628 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x000) ? "Fast" : 629 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x200) ? "Medium" : 630 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x400) ? "Slow" : "Invalid"); 631 632 printk(KERN_DEBUG "pmc551: %sFast Back-to-Back\n", 633 ((PCI_COMMAND_FAST_BACK & cmd) == 0) ? "Not " : ""); 634 635 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd); 636 printk(KERN_DEBUG "pmc551: EEPROM is under %s control\n" 637 "pmc551: System Control Register is %slocked to PCI access\n" 638 "pmc551: System Control Register is %slocked to EEPROM access\n", 639 (bcmd & 0x1) ? "software" : "hardware", 640 (bcmd & 0x20) ? "" : "un", (bcmd & 0x40) ? "" : "un"); 641 #endif 642 return size; 643 } 644 645 /* 646 * Kernel version specific module stuffages 647 */ 648 649 MODULE_LICENSE("GPL"); 650 MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>"); 651 MODULE_DESCRIPTION(PMC551_VERSION); 652 653 /* 654 * Stuff these outside the ifdef so as to not bust compiled in driver support 655 */ 656 static int msize = 0; 657 static int asize = 0; 658 659 module_param(msize, int, 0); 660 MODULE_PARM_DESC(msize, "memory size in MiB [1 - 1024]"); 661 module_param(asize, int, 0); 662 MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]"); 663 664 /* 665 * PMC551 Card Initialization 666 */ 667 static int __init init_pmc551(void) 668 { 669 struct pci_dev *PCI_Device = NULL; 670 struct mypriv *priv; 671 int count, found = 0; 672 struct mtd_info *mtd; 673 u32 length = 0; 674 675 if (msize) { 676 msize = (1 << (ffs(msize) - 1)) << 20; 677 if (msize > (1 << 30)) { 678 printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n", 679 msize); 680 return -EINVAL; 681 } 682 } 683 684 if (asize) { 685 asize = (1 << (ffs(asize) - 1)) << 20; 686 if (asize > (1 << 30)) { 687 printk(KERN_NOTICE "pmc551: Invalid aperture size " 688 "[%d]\n", asize); 689 return -EINVAL; 690 } 691 } 692 693 printk(KERN_INFO PMC551_VERSION); 694 695 /* 696 * PCU-bus chipset probe. 697 */ 698 for (count = 0; count < MAX_MTD_DEVICES; count++) { 699 700 if ((PCI_Device = pci_get_device(PCI_VENDOR_ID_V3_SEMI, 701 PCI_DEVICE_ID_V3_SEMI_V370PDC, 702 PCI_Device)) == NULL) { 703 break; 704 } 705 706 printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n", 707 (unsigned long long)pci_resource_start(PCI_Device, 0)); 708 709 /* 710 * The PMC551 device acts VERY weird if you don't init it 711 * first. i.e. it will not correctly report devsel. If for 712 * some reason the sdram is in a wrote-protected state the 713 * device will DEVSEL when it is written to causing problems 714 * with the oldproc.c driver in 715 * some kernels (2.2.*) 716 */ 717 if ((length = fixup_pmc551(PCI_Device)) <= 0) { 718 printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n"); 719 break; 720 } 721 722 /* 723 * This is needed until the driver is capable of reading the 724 * onboard I2C SROM to discover the "real" memory size. 725 */ 726 if (msize) { 727 length = msize; 728 printk(KERN_NOTICE "pmc551: Using specified memory " 729 "size 0x%x\n", length); 730 } else { 731 msize = length; 732 } 733 734 mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); 735 if (!mtd) { 736 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD " 737 "device.\n"); 738 break; 739 } 740 741 priv = kzalloc(sizeof(struct mypriv), GFP_KERNEL); 742 if (!priv) { 743 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD " 744 "device.\n"); 745 kfree(mtd); 746 break; 747 } 748 mtd->priv = priv; 749 priv->dev = PCI_Device; 750 751 if (asize > length) { 752 printk(KERN_NOTICE "pmc551: reducing aperture size to " 753 "fit %dM\n", length >> 20); 754 priv->asize = asize = length; 755 } else if (asize == 0 || asize == length) { 756 printk(KERN_NOTICE "pmc551: Using existing aperture " 757 "size %dM\n", length >> 20); 758 priv->asize = asize = length; 759 } else { 760 printk(KERN_NOTICE "pmc551: Using specified aperture " 761 "size %dM\n", asize >> 20); 762 priv->asize = asize; 763 } 764 priv->start = pci_iomap(PCI_Device, 0, priv->asize); 765 766 if (!priv->start) { 767 printk(KERN_NOTICE "pmc551: Unable to map IO space\n"); 768 kfree(mtd->priv); 769 kfree(mtd); 770 break; 771 } 772 #ifdef CONFIG_MTD_PMC551_DEBUG 773 printk(KERN_DEBUG "pmc551: setting aperture to %d\n", 774 ffs(priv->asize >> 20) - 1); 775 #endif 776 777 priv->base_map0 = (PMC551_PCI_MEM_MAP_REG_EN 778 | PMC551_PCI_MEM_MAP_ENABLE 779 | (ffs(priv->asize >> 20) - 1) << 4); 780 priv->curr_map0 = priv->base_map0; 781 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0, 782 priv->curr_map0); 783 784 #ifdef CONFIG_MTD_PMC551_DEBUG 785 printk(KERN_DEBUG "pmc551: aperture set to %d\n", 786 (priv->base_map0 & 0xF0) >> 4); 787 #endif 788 789 mtd->size = msize; 790 mtd->flags = MTD_CAP_RAM; 791 mtd->erase = pmc551_erase; 792 mtd->read = pmc551_read; 793 mtd->write = pmc551_write; 794 mtd->point = pmc551_point; 795 mtd->unpoint = pmc551_unpoint; 796 mtd->type = MTD_RAM; 797 mtd->name = "PMC551 RAM board"; 798 mtd->erasesize = 0x10000; 799 mtd->writesize = 1; 800 mtd->owner = THIS_MODULE; 801 802 if (add_mtd_device(mtd)) { 803 printk(KERN_NOTICE "pmc551: Failed to register new device\n"); 804 pci_iounmap(PCI_Device, priv->start); 805 kfree(mtd->priv); 806 kfree(mtd); 807 break; 808 } 809 810 /* Keep a reference as the add_mtd_device worked */ 811 pci_dev_get(PCI_Device); 812 813 printk(KERN_NOTICE "Registered pmc551 memory device.\n"); 814 printk(KERN_NOTICE "Mapped %dMiB of memory from 0x%p to 0x%p\n", 815 priv->asize >> 20, 816 priv->start, priv->start + priv->asize); 817 printk(KERN_NOTICE "Total memory is %d%sB\n", 818 (length < 1024) ? length : 819 (length < 1048576) ? length >> 10 : length >> 20, 820 (length < 1024) ? "" : (length < 1048576) ? "Ki" : "Mi"); 821 priv->nextpmc551 = pmc551list; 822 pmc551list = mtd; 823 found++; 824 } 825 826 /* Exited early, reference left over */ 827 if (PCI_Device) 828 pci_dev_put(PCI_Device); 829 830 if (!pmc551list) { 831 printk(KERN_NOTICE "pmc551: not detected\n"); 832 return -ENODEV; 833 } else { 834 printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found); 835 return 0; 836 } 837 } 838 839 /* 840 * PMC551 Card Cleanup 841 */ 842 static void __exit cleanup_pmc551(void) 843 { 844 int found = 0; 845 struct mtd_info *mtd; 846 struct mypriv *priv; 847 848 while ((mtd = pmc551list)) { 849 priv = mtd->priv; 850 pmc551list = priv->nextpmc551; 851 852 if (priv->start) { 853 printk(KERN_DEBUG "pmc551: unmapping %dMiB starting at " 854 "0x%p\n", priv->asize >> 20, priv->start); 855 pci_iounmap(priv->dev, priv->start); 856 } 857 pci_dev_put(priv->dev); 858 859 kfree(mtd->priv); 860 del_mtd_device(mtd); 861 kfree(mtd); 862 found++; 863 } 864 865 printk(KERN_NOTICE "pmc551: %d pmc551 devices unloaded\n", found); 866 } 867 868 module_init(init_pmc551); 869 module_exit(cleanup_pmc551); 870