1 #include <linux/config.h>
2 #include <linux/sched.h>
3 #include <linux/kernel.h>
4 #include <linux/pci.h>
5 #include <linux/ptrace.h>
6 #include <linux/interrupt.h>
7 #include <linux/mm.h>
8 #include <linux/init.h>
9 #include <linux/ioport.h>
10
11 #include <asm/io.h>
12 #include <asm/system.h>
13
14 #include <asm/mach/pci.h>
15
16 #define MAX_SLOTS 7
17
18 #define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
19
20 static int
via82c505_read_config_byte(struct pci_dev * dev,int where,u8 * value)21 via82c505_read_config_byte(struct pci_dev *dev, int where, u8 *value)
22 {
23 outl(CONFIG_CMD(dev,where),0xCF8);
24 *value=inb(0xCFC + (where&3));
25 return PCIBIOS_SUCCESSFUL;
26 }
27
28 static int
via82c505_read_config_word(struct pci_dev * dev,int where,u16 * value)29 via82c505_read_config_word(struct pci_dev *dev, int where, u16 *value)
30 {
31 outl(CONFIG_CMD(dev,where),0xCF8);
32 *value=inw(0xCFC + (where&2));
33 return PCIBIOS_SUCCESSFUL;
34 }
35
36 static int
via82c505_read_config_dword(struct pci_dev * dev,int where,u32 * value)37 via82c505_read_config_dword(struct pci_dev *dev, int where, u32 *value)
38 {
39 outl(CONFIG_CMD(dev,where),0xCF8);
40 *value=inl(0xCFC);
41 return PCIBIOS_SUCCESSFUL;
42 }
43
44 static int
via82c505_write_config_byte(struct pci_dev * dev,int where,u8 value)45 via82c505_write_config_byte(struct pci_dev *dev, int where, u8 value)
46 {
47 outl(CONFIG_CMD(dev,where),0xCF8);
48 outb(value, 0xCFC + (where&3));
49 return PCIBIOS_SUCCESSFUL;
50 }
51
52 static int
via82c505_write_config_word(struct pci_dev * dev,int where,u16 value)53 via82c505_write_config_word(struct pci_dev *dev, int where, u16 value)
54 {
55 outl(CONFIG_CMD(dev,where),0xCF8);
56 outw(value, 0xCFC + (where&2));
57 return PCIBIOS_SUCCESSFUL;
58 }
59
60 static int
via82c505_write_config_dword(struct pci_dev * dev,int where,u32 value)61 via82c505_write_config_dword(struct pci_dev *dev, int where, u32 value)
62 {
63 outl(CONFIG_CMD(dev,where),0xCF8);
64 outl(value, 0xCFC);
65 return PCIBIOS_SUCCESSFUL;
66 }
67
68 static struct pci_ops via82c505_ops = {
69 via82c505_read_config_byte,
70 via82c505_read_config_word,
71 via82c505_read_config_dword,
72 via82c505_write_config_byte,
73 via82c505_write_config_word,
74 via82c505_write_config_dword,
75 };
76
77 #ifdef CONFIG_ARCH_SHARK
78
79 static char size_wanted;
80
81 static int
dummy_read_config_byte(struct pci_dev * dev,int where,u8 * value)82 dummy_read_config_byte(struct pci_dev *dev, int where, u8 *value)
83 {
84 *value=0;
85 return PCIBIOS_SUCCESSFUL;
86 }
87
88 static int
dummy_read_config_word(struct pci_dev * dev,int where,u16 * value)89 dummy_read_config_word(struct pci_dev *dev, int where, u16 *value)
90 {
91 *value=0;
92 return PCIBIOS_SUCCESSFUL;
93 }
94
95 static int
dummy_read_config_dword(struct pci_dev * dev,int where,u32 * value)96 dummy_read_config_dword(struct pci_dev *dev, int where, u32 *value)
97 {
98 if (dev->devfn != 0) *value = 0;
99 else
100 switch(where) {
101 case PCI_VENDOR_ID:
102 *value = PCI_VENDOR_ID_INTERG | PCI_DEVICE_ID_INTERG_2010 << 16;
103 break;
104 case PCI_CLASS_REVISION:
105 *value = PCI_CLASS_DISPLAY_VGA << 16;
106 break;
107 case PCI_BASE_ADDRESS_0:
108 if (size_wanted) {
109 /* 0x00900000 bytes long (0xff700000) */
110 *value = 0xff000000;
111 size_wanted = 0;
112 } else {
113 *value = FB_START;
114 }
115 break;
116 case PCI_INTERRUPT_LINE:
117 *value = 6;
118 break;
119 default:
120 *value = 0;
121 }
122 return PCIBIOS_SUCCESSFUL;
123 }
124
125 static int
dummy_write_config_byte(struct pci_dev * dev,int where,u8 value)126 dummy_write_config_byte(struct pci_dev *dev, int where, u8 value)
127 {
128 return PCIBIOS_SUCCESSFUL;
129 }
130
131 static int
dummy_write_config_word(struct pci_dev * dev,int where,u16 value)132 dummy_write_config_word(struct pci_dev *dev, int where, u16 value)
133 {
134 return PCIBIOS_SUCCESSFUL;
135 }
136
137 static int
dummy_write_config_dword(struct pci_dev * dev,int where,u32 value)138 dummy_write_config_dword(struct pci_dev *dev, int where, u32 value)
139 {
140 if ((dev->devfn == 0) && (where == PCI_BASE_ADDRESS_0) && (value == 0xffffffff))
141 size_wanted = 1;
142 return PCIBIOS_SUCCESSFUL;
143 }
144
145 static struct pci_ops dummy_ops = {
146 dummy_read_config_byte,
147 dummy_read_config_word,
148 dummy_read_config_dword,
149 dummy_write_config_byte,
150 dummy_write_config_word,
151 dummy_write_config_dword,
152 };
153 #endif
154
via82c505_init(void * sysdata)155 void __init via82c505_init(void *sysdata)
156 {
157 struct pci_bus *bus;
158
159 printk(KERN_DEBUG "PCI: VIA 82c505\n");
160 if (!request_region(0xA8,2,"via config")) {
161 printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n");
162 return;
163 }
164 if (!request_region(0xCF8,8,"pci config")) {
165 printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n");
166 release_region(0xA8, 2);
167 return;
168 }
169
170 /* Enable compatible Mode */
171 outb(0x96,0xA8);
172 outb(0x18,0xA9);
173 outb(0x93,0xA8);
174 outb(0xd0,0xA9);
175
176 pci_scan_bus(0, &via82c505_ops, sysdata);
177
178 #ifdef CONFIG_ARCH_SHARK
179 /*
180 * Initialize a fake pci-bus number 1 for the CyberPro
181 * on the vlbus
182 */
183 bus = pci_scan_bus(1, &dummy_ops, sysdata);
184 #endif
185 }
186