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 <linux/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 <linux/pci.h> 97 #include <linux/mtd/mtd.h> 98 99 #define PMC551_VERSION \ 100 "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" 101 102 #define PCI_VENDOR_ID_V3_SEMI 0x11b0 103 #define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 104 105 #define PMC551_PCI_MEM_MAP0 0x50 106 #define PMC551_PCI_MEM_MAP1 0x54 107 #define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 108 #define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 109 #define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 110 #define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 111 112 #define PMC551_SDRAM_MA 0x60 113 #define PMC551_SDRAM_CMD 0x62 114 #define PMC551_DRAM_CFG 0x64 115 #define PMC551_SYS_CTRL_REG 0x78 116 117 #define PMC551_DRAM_BLK0 0x68 118 #define PMC551_DRAM_BLK1 0x6c 119 #define PMC551_DRAM_BLK2 0x70 120 #define PMC551_DRAM_BLK3 0x74 121 #define PMC551_DRAM_BLK_GET_SIZE(x) (524288 << ((x >> 4) & 0x0f)) 122 #define PMC551_DRAM_BLK_SET_COL_MUX(x, v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) 123 #define PMC551_DRAM_BLK_SET_ROW_MUX(x, v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) 124 125 struct mypriv { 126 struct pci_dev *dev; 127 u_char *start; 128 u32 base_map0; 129 u32 curr_map0; 130 u32 asize; 131 struct mtd_info *nextpmc551; 132 }; 133 134 static struct mtd_info *pmc551list; 135 136 static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, 137 size_t *retlen, void **virt, resource_size_t *phys); 138 139 static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) 140 { 141 struct mypriv *priv = mtd->priv; 142 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 143 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 144 unsigned long end; 145 u_char *ptr; 146 size_t retlen; 147 148 #ifdef CONFIG_MTD_PMC551_DEBUG 149 printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr, 150 (long)instr->len); 151 #endif 152 153 end = instr->addr + instr->len - 1; 154 eoff_hi = end & ~(priv->asize - 1); 155 soff_hi = instr->addr & ~(priv->asize - 1); 156 eoff_lo = end & (priv->asize - 1); 157 soff_lo = instr->addr & (priv->asize - 1); 158 159 pmc551_point(mtd, instr->addr, instr->len, &retlen, 160 (void **)&ptr, NULL); 161 162 if (soff_hi == eoff_hi || mtd->size == priv->asize) { 163 /* The whole thing fits within one access, so just one shot 164 will do it. */ 165 memset(ptr, 0xff, instr->len); 166 } else { 167 /* We have to do multiple writes to get all the data 168 written. */ 169 while (soff_hi != eoff_hi) { 170 #ifdef CONFIG_MTD_PMC551_DEBUG 171 printk(KERN_DEBUG "pmc551_erase() soff_hi: %ld, " 172 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 173 #endif 174 memset(ptr, 0xff, priv->asize); 175 if (soff_hi + priv->asize >= mtd->size) { 176 goto out; 177 } 178 soff_hi += priv->asize; 179 pmc551_point(mtd, (priv->base_map0 | soff_hi), 180 priv->asize, &retlen, 181 (void **)&ptr, NULL); 182 } 183 memset(ptr, 0xff, eoff_lo); 184 } 185 186 out: 187 #ifdef CONFIG_MTD_PMC551_DEBUG 188 printk(KERN_DEBUG "pmc551_erase() done\n"); 189 #endif 190 191 return 0; 192 } 193 194 static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, 195 size_t *retlen, void **virt, resource_size_t *phys) 196 { 197 struct mypriv *priv = mtd->priv; 198 u32 soff_hi; 199 u32 soff_lo; 200 201 #ifdef CONFIG_MTD_PMC551_DEBUG 202 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); 203 #endif 204 205 soff_hi = from & ~(priv->asize - 1); 206 soff_lo = from & (priv->asize - 1); 207 208 /* Cheap hack optimization */ 209 if (priv->curr_map0 != from) { 210 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0, 211 (priv->base_map0 | soff_hi)); 212 priv->curr_map0 = soff_hi; 213 } 214 215 *virt = priv->start + soff_lo; 216 *retlen = len; 217 return 0; 218 } 219 220 static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 221 { 222 #ifdef CONFIG_MTD_PMC551_DEBUG 223 printk(KERN_DEBUG "pmc551_unpoint()\n"); 224 #endif 225 return 0; 226 } 227 228 static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, 229 size_t * retlen, u_char * buf) 230 { 231 struct mypriv *priv = mtd->priv; 232 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 233 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 234 unsigned long end; 235 u_char *ptr; 236 u_char *copyto = buf; 237 238 #ifdef CONFIG_MTD_PMC551_DEBUG 239 printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n", 240 (long)from, (long)len, (long)priv->asize); 241 #endif 242 243 end = from + len - 1; 244 soff_hi = from & ~(priv->asize - 1); 245 eoff_hi = end & ~(priv->asize - 1); 246 soff_lo = from & (priv->asize - 1); 247 eoff_lo = end & (priv->asize - 1); 248 249 pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL); 250 251 if (soff_hi == eoff_hi) { 252 /* The whole thing fits within one access, so just one shot 253 will do it. */ 254 memcpy(copyto, ptr, len); 255 copyto += len; 256 } else { 257 /* We have to do multiple writes to get all the data 258 written. */ 259 while (soff_hi != eoff_hi) { 260 #ifdef CONFIG_MTD_PMC551_DEBUG 261 printk(KERN_DEBUG "pmc551_read() soff_hi: %ld, " 262 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 263 #endif 264 memcpy(copyto, ptr, priv->asize); 265 copyto += priv->asize; 266 if (soff_hi + priv->asize >= mtd->size) { 267 goto out; 268 } 269 soff_hi += priv->asize; 270 pmc551_point(mtd, soff_hi, priv->asize, retlen, 271 (void **)&ptr, NULL); 272 } 273 memcpy(copyto, ptr, eoff_lo); 274 copyto += eoff_lo; 275 } 276 277 out: 278 #ifdef CONFIG_MTD_PMC551_DEBUG 279 printk(KERN_DEBUG "pmc551_read() done\n"); 280 #endif 281 *retlen = copyto - buf; 282 return 0; 283 } 284 285 static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, 286 size_t * retlen, const u_char * buf) 287 { 288 struct mypriv *priv = mtd->priv; 289 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 290 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 291 unsigned long end; 292 u_char *ptr; 293 const u_char *copyfrom = buf; 294 295 #ifdef CONFIG_MTD_PMC551_DEBUG 296 printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n", 297 (long)to, (long)len, (long)priv->asize); 298 #endif 299 300 end = to + len - 1; 301 soff_hi = to & ~(priv->asize - 1); 302 eoff_hi = end & ~(priv->asize - 1); 303 soff_lo = to & (priv->asize - 1); 304 eoff_lo = end & (priv->asize - 1); 305 306 pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL); 307 308 if (soff_hi == eoff_hi) { 309 /* The whole thing fits within one access, so just one shot 310 will do it. */ 311 memcpy(ptr, copyfrom, len); 312 copyfrom += len; 313 } else { 314 /* We have to do multiple writes to get all the data 315 written. */ 316 while (soff_hi != eoff_hi) { 317 #ifdef CONFIG_MTD_PMC551_DEBUG 318 printk(KERN_DEBUG "pmc551_write() soff_hi: %ld, " 319 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 320 #endif 321 memcpy(ptr, copyfrom, priv->asize); 322 copyfrom += priv->asize; 323 if (soff_hi >= mtd->size) { 324 goto out; 325 } 326 soff_hi += priv->asize; 327 pmc551_point(mtd, soff_hi, priv->asize, retlen, 328 (void **)&ptr, NULL); 329 } 330 memcpy(ptr, copyfrom, eoff_lo); 331 copyfrom += eoff_lo; 332 } 333 334 out: 335 #ifdef CONFIG_MTD_PMC551_DEBUG 336 printk(KERN_DEBUG "pmc551_write() done\n"); 337 #endif 338 *retlen = copyfrom - buf; 339 return 0; 340 } 341 342 /* 343 * Fixup routines for the V370PDC 344 * PCI device ID 0x020011b0 345 * 346 * This function basically kick starts the DRAM oboard the card and gets it 347 * ready to be used. Before this is done the device reads VERY erratic, so 348 * much that it can crash the Linux 2.2.x series kernels when a user cat's 349 * /proc/pci .. though that is mainly a kernel bug in handling the PCI DEVSEL 350 * register. FIXME: stop spinning on registers .. must implement a timeout 351 * mechanism 352 * returns the size of the memory region found. 353 */ 354 static int __init fixup_pmc551(struct pci_dev *dev) 355 { 356 #ifdef CONFIG_MTD_PMC551_BUGFIX 357 u32 dram_data; 358 #endif 359 u32 size, dcmd, cfg, dtmp; 360 u16 cmd, tmp, i; 361 u8 bcmd, counter; 362 363 /* Sanity Check */ 364 if (!dev) { 365 return -ENODEV; 366 } 367 368 /* 369 * Attempt to reset the card 370 * FIXME: Stop Spinning registers 371 */ 372 counter = 0; 373 /* unlock registers */ 374 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5); 375 /* read in old data */ 376 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd); 377 /* bang the reset line up and down for a few */ 378 for (i = 0; i < 10; i++) { 379 counter = 0; 380 bcmd &= ~0x80; 381 while (counter++ < 100) { 382 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 383 } 384 counter = 0; 385 bcmd |= 0x80; 386 while (counter++ < 100) { 387 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 388 } 389 } 390 bcmd |= (0x40 | 0x20); 391 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 392 393 /* 394 * Take care and turn off the memory on the device while we 395 * tweak the configurations 396 */ 397 pci_read_config_word(dev, PCI_COMMAND, &cmd); 398 tmp = cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); 399 pci_write_config_word(dev, PCI_COMMAND, tmp); 400 401 /* 402 * Disable existing aperture before probing memory size 403 */ 404 pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd); 405 dtmp = (dcmd | PMC551_PCI_MEM_MAP_ENABLE | PMC551_PCI_MEM_MAP_REG_EN); 406 pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp); 407 /* 408 * Grab old BAR0 config so that we can figure out memory size 409 * This is another bit of kludge going on. The reason for the 410 * redundancy is I am hoping to retain the original configuration 411 * previously assigned to the card by the BIOS or some previous 412 * fixup routine in the kernel. So we read the old config into cfg, 413 * then write all 1's to the memory space, read back the result into 414 * "size", and then write back all the old config. 415 */ 416 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &cfg); 417 #ifndef CONFIG_MTD_PMC551_BUGFIX 418 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ~0); 419 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &size); 420 size = (size & PCI_BASE_ADDRESS_MEM_MASK); 421 size &= ~(size - 1); 422 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, cfg); 423 #else 424 /* 425 * Get the size of the memory by reading all the DRAM size values 426 * and adding them up. 427 * 428 * KLUDGE ALERT: the boards we are using have invalid column and 429 * row mux values. We fix them here, but this will break other 430 * memory configurations. 431 */ 432 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data); 433 size = PMC551_DRAM_BLK_GET_SIZE(dram_data); 434 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 435 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 436 pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data); 437 438 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data); 439 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 440 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 441 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 442 pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data); 443 444 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data); 445 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 446 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 447 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 448 pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data); 449 450 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data); 451 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 452 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 453 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 454 pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data); 455 456 /* 457 * Oops .. something went wrong 458 */ 459 if ((size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) { 460 return -ENODEV; 461 } 462 #endif /* CONFIG_MTD_PMC551_BUGFIX */ 463 464 if ((cfg & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) { 465 return -ENODEV; 466 } 467 468 /* 469 * Precharge Dram 470 */ 471 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0400); 472 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x00bf); 473 474 /* 475 * Wait until command has gone through 476 * FIXME: register spinning issue 477 */ 478 do { 479 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 480 if (counter++ > 100) 481 break; 482 } while ((PCI_COMMAND_IO) & cmd); 483 484 /* 485 * Turn on auto refresh 486 * The loop is taken directly from Ramix's example code. I assume that 487 * this must be held high for some duration of time, but I can find no 488 * documentation refrencing the reasons why. 489 */ 490 for (i = 1; i <= 8; i++) { 491 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0df); 492 493 /* 494 * Make certain command has gone through 495 * FIXME: register spinning issue 496 */ 497 counter = 0; 498 do { 499 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 500 if (counter++ > 100) 501 break; 502 } while ((PCI_COMMAND_IO) & cmd); 503 } 504 505 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0020); 506 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0ff); 507 508 /* 509 * Wait until command completes 510 * FIXME: register spinning issue 511 */ 512 counter = 0; 513 do { 514 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 515 if (counter++ > 100) 516 break; 517 } while ((PCI_COMMAND_IO) & cmd); 518 519 pci_read_config_dword(dev, PMC551_DRAM_CFG, &dcmd); 520 dcmd |= 0x02000000; 521 pci_write_config_dword(dev, PMC551_DRAM_CFG, dcmd); 522 523 /* 524 * Check to make certain fast back-to-back, if not 525 * then set it so 526 */ 527 pci_read_config_word(dev, PCI_STATUS, &cmd); 528 if ((cmd & PCI_COMMAND_FAST_BACK) == 0) { 529 cmd |= PCI_COMMAND_FAST_BACK; 530 pci_write_config_word(dev, PCI_STATUS, cmd); 531 } 532 533 /* 534 * Check to make certain the DEVSEL is set correctly, this device 535 * has a tendency to assert DEVSEL and TRDY when a write is performed 536 * to the memory when memory is read-only 537 */ 538 if ((cmd & PCI_STATUS_DEVSEL_MASK) != 0x0) { 539 cmd &= ~PCI_STATUS_DEVSEL_MASK; 540 pci_write_config_word(dev, PCI_STATUS, cmd); 541 } 542 /* 543 * Set to be prefetchable and put everything back based on old cfg. 544 * it's possible that the reset of the V370PDC nuked the original 545 * setup 546 */ 547 /* 548 cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH; 549 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg ); 550 */ 551 552 /* 553 * Turn PCI memory and I/O bus access back on 554 */ 555 pci_write_config_word(dev, PCI_COMMAND, 556 PCI_COMMAND_MEMORY | PCI_COMMAND_IO); 557 #ifdef CONFIG_MTD_PMC551_DEBUG 558 /* 559 * Some screen fun 560 */ 561 printk(KERN_DEBUG "pmc551: %d%sB (0x%x) of %sprefetchable memory at " 562 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ? 563 size >> 10 : size >> 20, 564 (size < 1024) ? "" : (size < 1048576) ? "Ki" : "Mi", size, 565 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "", 566 (unsigned long long)pci_resource_start(dev, 0)); 567 568 /* 569 * Check to see the state of the memory 570 */ 571 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dcmd); 572 printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n" 573 "pmc551: DRAM_BLK0 Size: %d at %d\n" 574 "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n", 575 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 576 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 577 PMC551_DRAM_BLK_GET_SIZE(dcmd), 578 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 579 ((dcmd >> 9) & 0xF)); 580 581 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dcmd); 582 printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n" 583 "pmc551: DRAM_BLK1 Size: %d at %d\n" 584 "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n", 585 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 586 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 587 PMC551_DRAM_BLK_GET_SIZE(dcmd), 588 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 589 ((dcmd >> 9) & 0xF)); 590 591 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dcmd); 592 printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n" 593 "pmc551: DRAM_BLK2 Size: %d at %d\n" 594 "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n", 595 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 596 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 597 PMC551_DRAM_BLK_GET_SIZE(dcmd), 598 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 599 ((dcmd >> 9) & 0xF)); 600 601 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dcmd); 602 printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n" 603 "pmc551: DRAM_BLK3 Size: %d at %d\n" 604 "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n", 605 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO", 606 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On", 607 PMC551_DRAM_BLK_GET_SIZE(dcmd), 608 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7), 609 ((dcmd >> 9) & 0xF)); 610 611 pci_read_config_word(dev, PCI_COMMAND, &cmd); 612 printk(KERN_DEBUG "pmc551: Memory Access %s\n", 613 (((0x1 << 1) & cmd) == 0) ? "off" : "on"); 614 printk(KERN_DEBUG "pmc551: I/O Access %s\n", 615 (((0x1 << 0) & cmd) == 0) ? "off" : "on"); 616 617 pci_read_config_word(dev, PCI_STATUS, &cmd); 618 printk(KERN_DEBUG "pmc551: Devsel %s\n", 619 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x000) ? "Fast" : 620 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x200) ? "Medium" : 621 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x400) ? "Slow" : "Invalid"); 622 623 printk(KERN_DEBUG "pmc551: %sFast Back-to-Back\n", 624 ((PCI_COMMAND_FAST_BACK & cmd) == 0) ? "Not " : ""); 625 626 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd); 627 printk(KERN_DEBUG "pmc551: EEPROM is under %s control\n" 628 "pmc551: System Control Register is %slocked to PCI access\n" 629 "pmc551: System Control Register is %slocked to EEPROM access\n", 630 (bcmd & 0x1) ? "software" : "hardware", 631 (bcmd & 0x20) ? "" : "un", (bcmd & 0x40) ? "" : "un"); 632 #endif 633 return size; 634 } 635 636 /* 637 * Kernel version specific module stuffages 638 */ 639 640 MODULE_LICENSE("GPL"); 641 MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>"); 642 MODULE_DESCRIPTION(PMC551_VERSION); 643 644 /* 645 * Stuff these outside the ifdef so as to not bust compiled in driver support 646 */ 647 static int msize = 0; 648 static int asize = 0; 649 650 module_param(msize, int, 0); 651 MODULE_PARM_DESC(msize, "memory size in MiB [1 - 1024]"); 652 module_param(asize, int, 0); 653 MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]"); 654 655 /* 656 * PMC551 Card Initialization 657 */ 658 static int __init init_pmc551(void) 659 { 660 struct pci_dev *PCI_Device = NULL; 661 struct mypriv *priv; 662 int found = 0; 663 struct mtd_info *mtd; 664 int length = 0; 665 666 if (msize) { 667 msize = (1 << (ffs(msize) - 1)) << 20; 668 if (msize > (1 << 30)) { 669 printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n", 670 msize); 671 return -EINVAL; 672 } 673 } 674 675 if (asize) { 676 asize = (1 << (ffs(asize) - 1)) << 20; 677 if (asize > (1 << 30)) { 678 printk(KERN_NOTICE "pmc551: Invalid aperture size " 679 "[%d]\n", asize); 680 return -EINVAL; 681 } 682 } 683 684 printk(KERN_INFO PMC551_VERSION); 685 686 /* 687 * PCU-bus chipset probe. 688 */ 689 for (;;) { 690 691 if ((PCI_Device = pci_get_device(PCI_VENDOR_ID_V3_SEMI, 692 PCI_DEVICE_ID_V3_SEMI_V370PDC, 693 PCI_Device)) == NULL) { 694 break; 695 } 696 697 printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n", 698 (unsigned long long)pci_resource_start(PCI_Device, 0)); 699 700 /* 701 * The PMC551 device acts VERY weird if you don't init it 702 * first. i.e. it will not correctly report devsel. If for 703 * some reason the sdram is in a wrote-protected state the 704 * device will DEVSEL when it is written to causing problems 705 * with the oldproc.c driver in 706 * some kernels (2.2.*) 707 */ 708 if ((length = fixup_pmc551(PCI_Device)) <= 0) { 709 printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n"); 710 break; 711 } 712 713 /* 714 * This is needed until the driver is capable of reading the 715 * onboard I2C SROM to discover the "real" memory size. 716 */ 717 if (msize) { 718 length = msize; 719 printk(KERN_NOTICE "pmc551: Using specified memory " 720 "size 0x%x\n", length); 721 } else { 722 msize = length; 723 } 724 725 mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); 726 if (!mtd) 727 break; 728 729 priv = kzalloc(sizeof(struct mypriv), GFP_KERNEL); 730 if (!priv) { 731 kfree(mtd); 732 break; 733 } 734 mtd->priv = priv; 735 priv->dev = PCI_Device; 736 737 if (asize > length) { 738 printk(KERN_NOTICE "pmc551: reducing aperture size to " 739 "fit %dM\n", length >> 20); 740 priv->asize = asize = length; 741 } else if (asize == 0 || asize == length) { 742 printk(KERN_NOTICE "pmc551: Using existing aperture " 743 "size %dM\n", length >> 20); 744 priv->asize = asize = length; 745 } else { 746 printk(KERN_NOTICE "pmc551: Using specified aperture " 747 "size %dM\n", asize >> 20); 748 priv->asize = asize; 749 } 750 priv->start = pci_iomap(PCI_Device, 0, priv->asize); 751 752 if (!priv->start) { 753 printk(KERN_NOTICE "pmc551: Unable to map IO space\n"); 754 kfree(mtd->priv); 755 kfree(mtd); 756 break; 757 } 758 #ifdef CONFIG_MTD_PMC551_DEBUG 759 printk(KERN_DEBUG "pmc551: setting aperture to %d\n", 760 ffs(priv->asize >> 20) - 1); 761 #endif 762 763 priv->base_map0 = (PMC551_PCI_MEM_MAP_REG_EN 764 | PMC551_PCI_MEM_MAP_ENABLE 765 | (ffs(priv->asize >> 20) - 1) << 4); 766 priv->curr_map0 = priv->base_map0; 767 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0, 768 priv->curr_map0); 769 770 #ifdef CONFIG_MTD_PMC551_DEBUG 771 printk(KERN_DEBUG "pmc551: aperture set to %d\n", 772 (priv->base_map0 & 0xF0) >> 4); 773 #endif 774 775 mtd->size = msize; 776 mtd->flags = MTD_CAP_RAM; 777 mtd->_erase = pmc551_erase; 778 mtd->_read = pmc551_read; 779 mtd->_write = pmc551_write; 780 mtd->_point = pmc551_point; 781 mtd->_unpoint = pmc551_unpoint; 782 mtd->type = MTD_RAM; 783 mtd->name = "PMC551 RAM board"; 784 mtd->erasesize = 0x10000; 785 mtd->writesize = 1; 786 mtd->owner = THIS_MODULE; 787 788 if (mtd_device_register(mtd, NULL, 0)) { 789 printk(KERN_NOTICE "pmc551: Failed to register new device\n"); 790 pci_iounmap(PCI_Device, priv->start); 791 kfree(mtd->priv); 792 kfree(mtd); 793 break; 794 } 795 796 /* Keep a reference as the mtd_device_register worked */ 797 pci_dev_get(PCI_Device); 798 799 printk(KERN_NOTICE "Registered pmc551 memory device.\n"); 800 printk(KERN_NOTICE "Mapped %dMiB of memory from 0x%p to 0x%p\n", 801 priv->asize >> 20, 802 priv->start, priv->start + priv->asize); 803 printk(KERN_NOTICE "Total memory is %d%sB\n", 804 (length < 1024) ? length : 805 (length < 1048576) ? length >> 10 : length >> 20, 806 (length < 1024) ? "" : (length < 1048576) ? "Ki" : "Mi"); 807 priv->nextpmc551 = pmc551list; 808 pmc551list = mtd; 809 found++; 810 } 811 812 /* Exited early, reference left over */ 813 pci_dev_put(PCI_Device); 814 815 if (!pmc551list) { 816 printk(KERN_NOTICE "pmc551: not detected\n"); 817 return -ENODEV; 818 } else { 819 printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found); 820 return 0; 821 } 822 } 823 824 /* 825 * PMC551 Card Cleanup 826 */ 827 static void __exit cleanup_pmc551(void) 828 { 829 int found = 0; 830 struct mtd_info *mtd; 831 struct mypriv *priv; 832 833 while ((mtd = pmc551list)) { 834 priv = mtd->priv; 835 pmc551list = priv->nextpmc551; 836 837 if (priv->start) { 838 printk(KERN_DEBUG "pmc551: unmapping %dMiB starting at " 839 "0x%p\n", priv->asize >> 20, priv->start); 840 pci_iounmap(priv->dev, priv->start); 841 } 842 pci_dev_put(priv->dev); 843 844 kfree(mtd->priv); 845 mtd_device_unregister(mtd); 846 kfree(mtd); 847 found++; 848 } 849 850 printk(KERN_NOTICE "pmc551: %d pmc551 devices unloaded\n", found); 851 } 852 853 module_init(init_pmc551); 854 module_exit(cleanup_pmc551); 855