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