13 #include <linux/types.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/pci.h>
37 static struct resource pci_ioport_resource = {
44 static struct resource pci_iomem_resource = {
55 #define CONFIG_CMD(bus, devfn, where) \
56 (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
58 #define MEM_PAGING_REG (*(volatile __u32 *) 0xBFFFFFF4)
59 #define CONFIG_ADDRESS (*(volatile __u32 *) 0xBFFFFFF8)
60 #define CONFIG_DATAL(X) (*(volatile __u32 *) 0xBFFFFFFC)
61 #define CONFIG_DATAW(X) (*(volatile __u16 *) (0xBFFFFFFC + ((X) & 2)))
62 #define CONFIG_DATAB(X) (*(volatile __u8 *) (0xBFFFFFFC + ((X) & 3)))
64 #define BRIDGEREGB(X) (*(volatile __u8 *) (0xBE040000 + (X)))
65 #define BRIDGEREGW(X) (*(volatile __u16 *) (0xBE040000 + (X)))
66 #define BRIDGEREGL(X) (*(volatile __u32 *) (0xBE040000 + (X)))
68 static inline int __query(
const struct pci_bus *
bus,
unsigned int devfn)
82 static int pci_ampci_read_config_byte(
struct pci_bus *
bus,
unsigned int devfn,
83 int where,
u32 *_value)
89 __pcbdebug(
"=> %02hx", &
BRIDGEREGL(where), value);
94 if (__query(bus, devfn))
95 __pcidebug(
"=> %02hx", bus, devfn, where, value);
102 static int pci_ampci_read_config_word(
struct pci_bus *bus,
unsigned int devfn,
103 int where,
u32 *_value)
109 __pcbdebug(
"=> %04hx", &
BRIDGEREGL(where), value);
114 if (__query(bus, devfn))
115 __pcidebug(
"=> %04hx", bus, devfn, where, value);
122 static int pci_ampci_read_config_dword(
struct pci_bus *bus,
unsigned int devfn,
123 int where,
u32 *_value)
129 __pcbdebug(
"=> %08x", &
BRIDGEREGL(where), value);
134 if (__query(bus, devfn))
135 __pcidebug(
"=> %08x", bus, devfn, where, value);
142 static int pci_ampci_write_config_byte(
struct pci_bus *bus,
unsigned int devfn,
148 __pcbdebug(
"<= %02x", &
BRIDGEREGB(where), value);
154 __pcidebug(
"<= %02x", bus, devfn, where, value);
162 static int pci_ampci_write_config_word(
struct pci_bus *bus,
unsigned int devfn,
163 int where,
u16 value)
168 __pcbdebug(
"<= %04hx", &
BRIDGEREGW(where), value);
171 if (__query(bus, devfn))
172 __pcidebug(
"<= %04hx", bus, devfn, where, value);
180 static int pci_ampci_write_config_dword(
struct pci_bus *bus,
unsigned int devfn,
181 int where,
u32 value)
186 __pcbdebug(
"<= %08x", &
BRIDGEREGL(where), value);
189 if (__query(bus, devfn))
190 __pcidebug(
"<= %08x", bus, devfn, where, value);
198 static int pci_ampci_read_config(
struct pci_bus *bus,
unsigned int devfn,
203 return pci_ampci_read_config_byte(bus, devfn, where, val);
205 return pci_ampci_read_config_word(bus, devfn, where, val);
207 return pci_ampci_read_config_dword(bus, devfn, where, val);
214 static int pci_ampci_write_config(
struct pci_bus *bus,
unsigned int devfn,
215 int where,
int size,
u32 val)
219 return pci_ampci_write_config_byte(bus, devfn, where, val);
221 return pci_ampci_write_config_word(bus, devfn, where, val);
223 return pci_ampci_write_config_dword(bus, devfn, where, val);
230 static struct pci_ops pci_direct_ampci = {
231 pci_ampci_read_config,
232 pci_ampci_write_config,
262 static int __init pci_check_direct(
void)
271 if (pci_sanity_check(&pci_direct_ampci)) {
290 pci_bus_for_each_resource(dev->
bus, busr, i) {
291 if (!busr || (busr->flags ^ devr->
flags) & type_mask)
295 devr->
start >= busr->start &&
296 devr->
end <= busr->end)
310 if (dev->
bus->number != 0)
316 for (i = 0; i <
limit; i++) {
320 if (is_valid_resource(dev, i))
359 panic(
"Unable to insert PCI IOMEM resource\n");
361 panic(
"Unable to insert PCI IOPORT resource\n");
366 if (pci_check_direct() < 0) {
374 io_offset = pci_ioport_resource.
start -
375 (pci_ioport_resource.
start & 0x00ffffff);
376 mem_offset = pci_iomem_resource.
start -
394 if (!
strcmp(str,
"off")) {
398 }
else if (!
strncmp(str,
"lastbus=", 8)) {
435 #define RDP (*(volatile u32 *) 0xBE030010)
436 #define RAP (*(volatile u32 *) 0xBE030014)
437 #define __set_RAP(X) do { RAP = (X); x = RAP; } while (0)
438 #define __set_RDP(X) do { RDP = (X); x = RDP; } while (0)
439 #define __get_RDP() ({ RDP & 0xffff; })
447 for (x = 0; x < 100; x++)
459 struct pci_ops *o = &pci_direct_ampci;
464 memset(&bus, 0,
sizeof(bus));
512 unit_disable_pcnet(&bus, o);