linux/drivers/mtd/devices/pmc551.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * PMC551 PCI Mezzanine Ram Device
 *
 * Author:
 *	Mark Ferrell <[email protected]>
 *	Copyright 1999,2000 Nortel Networks
 *
 * Description:
 *	This driver is intended to support the PMC551 PCI Ram device
 *	from Ramix Inc.  The PMC551 is a PMC Mezzanine module for
 *	cPCI embedded systems.  The device contains a single SROM
 *	that initially programs the V370PDC chipset onboard the
 *	device, and various banks of DRAM/SDRAM onboard.  This driver
 *	implements this PCI Ram device as an MTD (Memory Technology
 *	Device) so that it can be used to hold a file system, or for
 *	added swap space in embedded systems.  Since the memory on
 *	this board isn't as fast as main memory we do not try to hook
 *	it into main memory as that would simply reduce performance
 *	on the system.  Using it as a block device allows us to use
 *	it as high speed swap or for a high speed disk device of some
 *	sort.  Which becomes very useful on diskless systems in the
 *	embedded market I might add.
 *
 * Notes:
 *	Due to what I assume is more buggy SROM, the 64M PMC551 I
 *	have available claims that all 4 of its DRAM banks have 64MiB
 *	of ram configured (making a grand total of 256MiB onboard).
 *	This is slightly annoying since the BAR0 size reflects the
 *	aperture size, not the dram size, and the V370PDC supplies no
 *	other method for memory size discovery.  This problem is
 *	mostly only relevant when compiled as a module, as the
 *	unloading of the module with an aperture size smaller than
 *	the ram will cause the driver to detect the onboard memory
 *	size to be equal to the aperture size when the module is
 *	reloaded.  Soooo, to help, the module supports an msize
 *	option to allow the specification of the onboard memory, and
 *	an asize option, to allow the specification of the aperture
 *	size.  The aperture must be equal to or less then the memory
 *	size, the driver will correct this if you screw it up.  This
 *	problem is not relevant for compiled in drivers as compiled
 *	in drivers only init once.
 *
 * Credits:
 *	Saeed Karamooz <[email protected]> of Ramix INC. for the
 *	initial example code of how to initialize this device and for
 *	help with questions I had concerning operation of the device.
 *
 *	Most of the MTD code for this driver was originally written
 *	for the slram.o module in the MTD drivers package which
 *	allows the mapping of system memory into an MTD device.
 *	Since the PMC551 memory module is accessed in the same
 *	fashion as system memory, the slram.c code became a very nice
 *	fit to the needs of this driver.  All we added was PCI
 *	detection/initialization to the driver and automatically figure
 *	out the size via the PCI detection.o, later changes by Corey
 *	Minyard set up the card to utilize a 1M sliding apature.
 *
 *	Corey Minyard <[email protected]>
 *	* Modified driver to utilize a sliding aperture instead of
 *	 mapping all memory into kernel space which turned out to
 *	 be very wasteful.
 *	* Located a bug in the SROM's initialization sequence that
 *	 made the memory unusable, added a fix to code to touch up
 *	 the DRAM some.
 *
 * Bugs/FIXMEs:
 *	* MUST fix the init function to not spin on a register
 *	waiting for it to set .. this does not safely handle busted
 *	devices that never reset the register correctly which will
 *	cause the system to hang w/ a reboot being the only chance at
 *	recover. [sort of fixed, could be better]
 *	* Add I2C handling of the SROM so we can read the SROM's information
 *	about the aperture size.  This should always accurately reflect the
 *	onboard memory size.
 *	* Comb the init routine.  It's still a bit cludgy on a few things.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <asm/io.h>
#include <linux/pci.h>
#include <linux/mtd/mtd.h>

#define PMC551_VERSION

#define PCI_VENDOR_ID_V3_SEMI
#define PCI_DEVICE_ID_V3_SEMI_V370PDC

#define PMC551_PCI_MEM_MAP0
#define PMC551_PCI_MEM_MAP1
#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK
#define PMC551_PCI_MEM_MAP_APERTURE_MASK
#define PMC551_PCI_MEM_MAP_REG_EN
#define PMC551_PCI_MEM_MAP_ENABLE

#define PMC551_SDRAM_MA
#define PMC551_SDRAM_CMD
#define PMC551_DRAM_CFG
#define PMC551_SYS_CTRL_REG

#define PMC551_DRAM_BLK0
#define PMC551_DRAM_BLK1
#define PMC551_DRAM_BLK2
#define PMC551_DRAM_BLK3
#define PMC551_DRAM_BLK_GET_SIZE(x)
#define PMC551_DRAM_BLK_SET_COL_MUX(x, v)
#define PMC551_DRAM_BLK_SET_ROW_MUX(x, v)

struct mypriv {};

static struct mtd_info *pmc551list;

static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
			size_t *retlen, void **virt, resource_size_t *phys);

static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
{}

static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
			size_t *retlen, void **virt, resource_size_t *phys)
{}

static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{}

static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
			size_t * retlen, u_char * buf)
{}

static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
			size_t * retlen, const u_char * buf)
{}

/*
 * Fixup routines for the V370PDC
 * PCI device ID 0x020011b0
 *
 * This function basically kick starts the DRAM oboard the card and gets it
 * ready to be used.  Before this is done the device reads VERY erratic, so
 * much that it can crash the Linux 2.2.x series kernels when a user cat's
 * /proc/pci .. though that is mainly a kernel bug in handling the PCI DEVSEL
 * register.  FIXME: stop spinning on registers .. must implement a timeout
 * mechanism
 * returns the size of the memory region found.
 */
static int __init fixup_pmc551(struct pci_dev *dev)
{}

/*
 * Kernel version specific module stuffages
 */

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();

/*
 * Stuff these outside the ifdef so as to not bust compiled in driver support
 */
static int msize =;
static int asize =;

module_param(msize, int, 0);
MODULE_PARM_DESC();
module_param(asize, int, 0);
MODULE_PARM_DESC();

/*
 * PMC551 Card Initialization
 */
static int __init init_pmc551(void)
{}

/*
 * PMC551 Card Cleanup
 */
static void __exit cleanup_pmc551(void)
{}

module_init();
module_exit(cleanup_pmc551);