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