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