4 * Normal mappings of chips in physical memory
5 * $Id: amd76xrom.c,v 1.1 2002/10/18 22:45:48 eric Exp $
8 #include <linux/module.h>
9 #include <linux/types.h>
10 #include <linux/kernel.h>
12 #include <linux/mtd/mtd.h>
13 #include <linux/mtd/map.h>
14 #include <linux/config.h>
15 #include <linux/pci.h>
16 #include <linux/pci_ids.h>
19 struct amd76xrom_map_info {
22 unsigned long window_addr;
23 u32 window_start, window_size;
27 static __u8 amd76xrom_read8(struct map_info *map, unsigned long ofs)
29 return __raw_readb(map->map_priv_1 + ofs);
32 static __u16 amd76xrom_read16(struct map_info *map, unsigned long ofs)
34 return __raw_readw(map->map_priv_1 + ofs);
37 static __u32 amd76xrom_read32(struct map_info *map, unsigned long ofs)
39 return __raw_readl(map->map_priv_1 + ofs);
42 static void amd76xrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
44 memcpy_fromio(to, map->map_priv_1 + from, len);
47 static void amd76xrom_write8(struct map_info *map, __u8 d, unsigned long adr)
49 __raw_writeb(d, map->map_priv_1 + adr);
53 static void amd76xrom_write16(struct map_info *map, __u16 d, unsigned long adr)
55 __raw_writew(d, map->map_priv_1 + adr);
59 static void amd76xrom_write32(struct map_info *map, __u32 d, unsigned long adr)
61 __raw_writel(d, map->map_priv_1 + adr);
65 static void amd76xrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
67 memcpy_toio(map->map_priv_1 + to, from, len);
70 static struct amd76xrom_map_info amd76xrom_map = {
75 read8: amd76xrom_read8,
76 read16: amd76xrom_read16,
77 read32: amd76xrom_read32,
78 copy_from: amd76xrom_copy_from,
79 write8: amd76xrom_write8,
80 write16: amd76xrom_write16,
81 write32: amd76xrom_write32,
82 copy_to: amd76xrom_copy_to,
83 /* The standard rom socket is for single power supply chips
84 * that don't have an extra vpp.
91 static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
92 const struct pci_device_id *ent)
99 static struct rom_window rom_window[] = {
100 { 0xffb00000, 5*1024*1024, (1<<7) | (1<<6), },
101 { 0xffc00000, 4*1024*1024, (1<<7), },
102 { 0xffff0000, 64*1024, 0 },
105 static const u32 rom_probe_sizes[] = {
106 5*1024*1024, 4*1024*1024, 2*1024*1024, 1024*1024, 512*1024,
107 256*1024, 128*1024, 64*1024, 0};
108 static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", 0 };
110 struct amd76xrom_map_info *info = &amd76xrom_map;
111 struct rom_window *window;
115 window = &rom_window[0];
117 while(window->size) {
118 if (request_mem_region(window->start, window->size, "amd76xrom")) {
124 printk(KERN_ERR "amd76xrom: cannot reserve rom window\n");
129 /* Enable the selected rom window */
130 pci_read_config_byte(pdev, 0x43, &byte);
131 pci_write_config_byte(pdev, 0x43, byte | window->segen_bits);
133 /* Enable writes through the rom window */
134 pci_read_config_byte(pdev, 0x40, &byte);
135 pci_write_config_byte(pdev, 0x40, byte | 1);
137 /* FIXME handle registers 0x80 - 0x8C the bios region locks */
139 printk(KERN_NOTICE "amd76xrom window : %x at %x\n",
140 window->size, window->start);
141 /* For write accesses caches are useless */
142 info->window_addr = (unsigned long)ioremap_nocache(window->start, window->size);
144 if (!info->window_addr) {
145 printk(KERN_ERR "Failed to ioremap\n");
146 goto err_out_free_mmio_region;
149 for(i = 0; (rom_size = rom_probe_sizes[i]); i++) {
151 if (rom_size > window->size) {
154 info->map.map_priv_1 =
155 info->window_addr + window->size - rom_size;
156 info->map.size = rom_size;
157 chip_type = rom_probe_types;
158 for(; !info->mtd && *chip_type; chip_type++) {
159 info->mtd = do_map_probe(*chip_type, &amd76xrom_map.map);
166 goto err_out_iounmap;
168 printk(KERN_NOTICE "amd76xrom chip at offset: %x\n",
169 window->size - rom_size);
171 info->mtd->module = THIS_MODULE;
172 add_mtd_device(info->mtd);
173 info->window_start = window->start;
174 info->window_size = window->size;
178 iounmap((void *)(info->window_addr));
179 err_out_free_mmio_region:
180 release_mem_region(window->start, window->size);
186 static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
188 struct amd76xrom_map_info *info = &amd76xrom_map;
191 del_mtd_device(info->mtd);
192 map_destroy(info->mtd);
194 info->map.map_priv_1 = 0;
196 iounmap((void *)(info->window_addr));
197 info->window_addr = 0;
199 /* Disable writes through the rom window */
200 pci_read_config_byte(pdev, 0x40, &byte);
201 pci_write_config_byte(pdev, 0x40, byte & ~1);
203 release_mem_region(info->window_start, info->window_size);
206 static struct pci_device_id amd76xrom_pci_tbl[] __devinitdata = {
207 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
208 PCI_ANY_ID, PCI_ANY_ID, },
209 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
210 PCI_ANY_ID, PCI_ANY_ID, },
214 MODULE_DEVICE_TABLE(pci, amd76xrom_pci_tbl);
217 static struct pci_driver amd76xrom_driver = {
219 id_table: amd76xrom_pci_tbl,
220 probe: amd76xrom_init_one,
221 remove: amd76xrom_remove_one,
225 int __init init_amd76xrom(void)
227 struct pci_dev *pdev;
228 struct pci_device_id *id;
230 for(id = amd76xrom_pci_tbl; id->vendor; id++) {
231 pdev = pci_find_device(id->vendor, id->device, 0);
237 amd76xrom_map.pdev = pdev;
238 return amd76xrom_init_one(pdev, &amd76xrom_pci_tbl[0]);
242 return pci_module_init(&amd76xrom_driver);
246 static void __exit cleanup_amd76xrom(void)
248 amd76xrom_remove_one(amd76xrom_map.pdev);
251 module_init(init_amd76xrom);
252 module_exit(cleanup_amd76xrom);
254 MODULE_LICENSE("GPL");
255 MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>");
256 MODULE_DESCRIPTION("MTD map driver for BIOS chips on the AMD76X southbridge");