Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
54 | pj | 1 | #include <linux/pci.h> |
2 | #include <asm/io.h> |
||
3 | #include <stdint.h> |
||
4 | #include "svgalib_helper.h" |
||
5 | |||
6 | #define ioremap(a,b) \ |
||
7 | (((a)<0x100000) ? (void *)((u_long)(a)) : vremap(a,b)) |
||
8 | #define iounmap(v) \ |
||
9 | do { if ((u_long)(v) > 0x100000) vfree(v); } while (0) |
||
10 | |||
11 | int vga_test_vsync(struct sh_pci_device *dev) { |
||
12 | return inb(0x3c2)&0x80; |
||
13 | } |
||
14 | |||
15 | void vga_ack_vsync(struct sh_pci_device *dev) { |
||
16 | int pb; |
||
17 | |||
18 | /* disable interrupt, clear pending */ |
||
19 | outb(0x11, 0x3d4); |
||
20 | pb = inb(0x3d5); |
||
21 | outb(0x11, 0x3d4); |
||
22 | outb((pb&0xef) | 0x20, 0x3d5); |
||
23 | } |
||
24 | |||
25 | void vga_enable_vsync(struct sh_pci_device *dev) { |
||
26 | int pb; |
||
27 | |||
28 | /* enable interrupt, clear pending */ |
||
29 | outb(0x11, 0x3d4); |
||
30 | pb = inb(0x3d5); |
||
31 | outb(0x11, 0x3d4); |
||
32 | outb((pb&0xcf) , 0x3d5); |
||
33 | |||
34 | /* Allow interrupts */ |
||
35 | outb(0x11, 0x3d4); |
||
36 | pb = inb(0x3d5); |
||
37 | outb(0x11, 0x3d4); |
||
38 | outb(pb | 0x10 , 0x3d5); |
||
39 | } |
||
40 | |||
41 | int io_test_vsync(struct sh_pci_device *dev) { |
||
42 | return inb(dev->iobase+0x3c2)&0x80; |
||
43 | } |
||
44 | |||
45 | void io_ack_vsync(struct sh_pci_device *dev) { |
||
46 | int pb; |
||
47 | |||
48 | /* disable interrupt, clear pending */ |
||
49 | outb(0x11, dev->iobase+0x3d4); |
||
50 | pb = inb(dev->iobase+0x3d5); |
||
51 | outb(0x11, dev->iobase+0x3d4); |
||
52 | outb((pb&0xef) | 0x20, dev->iobase+0x3d5); |
||
53 | } |
||
54 | |||
55 | void io_enable_vsync(struct sh_pci_device *dev) { |
||
56 | int pb; |
||
57 | |||
58 | /* enable interrupt, clear pending */ |
||
59 | outb(0x11, dev->iobase+0x3d4); |
||
60 | pb = inb(dev->iobase+0x3d5); |
||
61 | outb(0x11, dev->iobase+0x3d4); |
||
62 | outb((pb&0xcf) , dev->iobase+0x3d5); |
||
63 | |||
64 | /* Allow interrupts */ |
||
65 | outb(0x11, dev->iobase+0x3d4); |
||
66 | pb = inb(dev->iobase+0x3d5); |
||
67 | outb(0x11, dev->iobase+0x3d4); |
||
68 | outb(pb | 0x10 , dev->iobase+0x3d5); |
||
69 | } |
||
70 | |||
71 | int mm_test_vsync(struct sh_pci_device *dev) { |
||
72 | return readb(dev->iobase+0x3c2)&0x80; |
||
73 | } |
||
74 | |||
75 | void mm_ack_vsync(struct sh_pci_device *dev) { |
||
76 | int pb; |
||
77 | |||
78 | /* disable interrupt, clear pending */ |
||
79 | writeb(0x11, dev->iobase+0x3d4); |
||
80 | pb = readb(dev->iobase+0x3d5); |
||
81 | writeb(0x11, dev->iobase+0x3d4); |
||
82 | writeb((pb&0xef) | 0x20, dev->iobase+0x3d5); |
||
83 | } |
||
84 | |||
85 | void mm_enable_vsync(struct sh_pci_device *dev) { |
||
86 | int pb; |
||
87 | |||
88 | /* enable interrupt, clear pending */ |
||
89 | writeb(0x11, dev->iobase+0x3d4); |
||
90 | pb = readb(dev->iobase+0x3d5); |
||
91 | writeb(0x11, dev->iobase+0x3d4); |
||
92 | writeb((pb&0xcf) , dev->iobase+0x3d5); |
||
93 | |||
94 | /* Allow interrupts */ |
||
95 | writeb(0x11, dev->iobase+0x3d4); |
||
96 | pb = readb(dev->iobase+0x3d5); |
||
97 | writeb(0x11, dev->iobase+0x3d4); |
||
98 | writeb(pb | 0x10 , dev->iobase+0x3d5); |
||
99 | } |
||
100 | |||
101 | static uint32_t saved_pmc; |
||
102 | |||
103 | int nv3_test_vsync(struct sh_pci_device *dev) { |
||
104 | return readl(dev->iobase+0x400100)&0x100; |
||
105 | } |
||
106 | |||
107 | void nv3_ack_vsync(struct sh_pci_device *dev) { |
||
108 | |||
109 | /* disable interrupt, clear pending */ |
||
110 | writel(0xffffffff, dev->iobase + 0x000100); |
||
111 | writel(0x100, dev->iobase + 0x400100); |
||
112 | writel(0, dev->iobase + 0x000140); |
||
113 | writel(0, dev->iobase + 0x400140); |
||
114 | writel(saved_pmc, dev->iobase + 0x000200); |
||
115 | |||
116 | } |
||
117 | |||
118 | void nv3_enable_vsync(struct sh_pci_device *dev) { |
||
119 | saved_pmc = inl(dev->iobase + 0x200); |
||
120 | writel(saved_pmc|0x1000, dev->iobase+0x200); |
||
121 | writel(0x1, dev->iobase + 0x000140); |
||
122 | writel(0x100, dev->iobase + 0x400140); |
||
123 | writel(0xffffffff, dev->iobase + 0x000100); |
||
124 | writel(0xffffffff, dev->iobase + 0x400100); |
||
125 | } |
||
126 | |||
127 | int nv4_test_vsync(struct sh_pci_device *dev) { |
||
128 | return readl(dev->iobase+0x600100)&0x1; |
||
129 | } |
||
130 | |||
131 | void nv4_ack_vsync(struct sh_pci_device *dev) { |
||
132 | |||
133 | /* disable interrupt, clear pending */ |
||
134 | writel(0xffffffff, dev->iobase + 0x000100); |
||
135 | writel(0x1, dev->iobase + 0x600100); |
||
136 | writel(0, dev->iobase + 0x000140); |
||
137 | writel(0, dev->iobase + 0x600140); |
||
138 | writel(saved_pmc, dev->iobase + 0x000200); |
||
139 | } |
||
140 | |||
141 | void nv4_enable_vsync(struct sh_pci_device *dev) { |
||
142 | saved_pmc = inl(dev->iobase + 0x200); |
||
143 | writel(saved_pmc|(1<<24),dev->iobase+0x200); |
||
144 | writel(0x1, dev->iobase + 0x000140); |
||
145 | writel(0x1, dev->iobase + 0x600140); |
||
146 | writel(0xffffffff, dev->iobase + 0x000100); |
||
147 | writel(0xffffffff, dev->iobase + 0x600100); |
||
148 | } |
||
149 | |||
150 | int r128_test_vsync(struct sh_pci_device *dev) { |
||
151 | return readl(dev->iobase + 0x44) &1; |
||
152 | } |
||
153 | |||
154 | void r128_ack_vsync(struct sh_pci_device *dev) { |
||
155 | writel(1, dev->iobase + 0x44); |
||
156 | writel(readl(dev->iobase + 0x40) & 0xfffffffe, dev->iobase + 0x40); |
||
157 | } |
||
158 | |||
159 | void r128_enable_vsync(struct sh_pci_device *dev) { |
||
160 | writel(1, dev->iobase + 0x44); |
||
161 | writel(readl(dev->iobase + 0x40) | 1, dev->iobase + 0x40); |
||
162 | } |
||
163 | |||
164 | int rage_test_vsync(struct sh_pci_device *dev) { |
||
165 | return inl(dev->iobase + 0x18) &4; |
||
166 | } |
||
167 | |||
168 | void rage_ack_vsync(struct sh_pci_device *dev) { |
||
169 | outl((inl(dev->iobase + 0x18) & 0xfffffff8) | 4, dev->iobase + 0x18); |
||
170 | } |
||
171 | |||
172 | void rage_enable_vsync(struct sh_pci_device *dev) { |
||
173 | outl((inl(dev->iobase + 0x18) & 0xfffffff8) | 6, dev->iobase + 0x18); |
||
174 | } |
||
175 | |||
176 | int rendition_test_vsync(struct sh_pci_device *dev) { |
||
177 | return inw(dev->iobase + 0x44) & 1; |
||
178 | } |
||
179 | |||
180 | void rendition_ack_vsync(struct sh_pci_device *dev) { |
||
181 | outw(1, dev->iobase + 0x44); |
||
182 | outw(0, dev->iobase + 0x46); |
||
183 | } |
||
184 | |||
185 | void rendition_enable_vsync(struct sh_pci_device *dev) { |
||
186 | outw(1, dev->iobase + 0x44); |
||
187 | outw(1, dev->iobase + 0x46); |
||
188 | } |
||
189 | |||
190 | void vga_init_vsync(struct sh_pci_device *dev) { |
||
191 | int i, id; |
||
192 | switch(dev->vendor) { |
||
193 | case PCI_VENDOR_ID_MATROX: |
||
194 | i=0; |
||
195 | if(dev->len[0]>=1048576)i=1; |
||
196 | dev->iobase = (unsigned long)ioremap(dev->mem[i],0x2000) + 0x1c00; |
||
197 | dev->test_vsync = mm_test_vsync; |
||
198 | dev->ack_vsync = mm_ack_vsync; |
||
199 | dev->enable_vsync = mm_enable_vsync; |
||
200 | break; |
||
201 | case PCI_VENDOR_ID_SI: /* SiS */ |
||
202 | dev->iobase = dev->mem[2]-0x380; |
||
203 | dev->test_vsync = io_test_vsync; |
||
204 | dev->ack_vsync = io_ack_vsync; |
||
205 | dev->enable_vsync = io_enable_vsync; |
||
206 | break; |
||
207 | case PCI_VENDOR_ID_NVIDIA_SGS: |
||
208 | dev->iobase = (unsigned long)ioremap(dev->mem[0],0x800000); |
||
209 | if(dev->id<0x20) { |
||
210 | dev->test_vsync = nv3_test_vsync; |
||
211 | dev->ack_vsync = nv3_ack_vsync; |
||
212 | dev->enable_vsync = nv3_enable_vsync; |
||
213 | } else { |
||
214 | dev->test_vsync = nv4_test_vsync; |
||
215 | dev->ack_vsync = nv4_ack_vsync; |
||
216 | dev->enable_vsync = nv4_enable_vsync; |
||
217 | } |
||
218 | break; |
||
219 | case PCI_VENDOR_ID_NVIDIA: |
||
220 | dev->iobase = (unsigned long)ioremap(dev->mem[0],0x800000); |
||
221 | dev->test_vsync = nv4_test_vsync; |
||
222 | dev->ack_vsync = nv4_ack_vsync; |
||
223 | dev->enable_vsync = nv4_enable_vsync; |
||
224 | break; |
||
225 | case PCI_VENDOR_ID_ATI: |
||
226 | id=dev->id; |
||
227 | |||
228 | if( (id==0x4c45) || |
||
229 | (id==0x4c56) || |
||
230 | (id==0x4d46) || |
||
231 | (id==0x4d4c) || |
||
232 | ((id>>8)==0x50) || |
||
233 | ((id>>8)==0x52) || |
||
234 | ((id>>8)==0x53) || |
||
235 | ((id>>8)==0x54)) { |
||
236 | dev->iobase = (unsigned long)ioremap(dev->mem[2], 16384); |
||
237 | dev->test_vsync = r128_test_vsync; |
||
238 | dev->ack_vsync = r128_ack_vsync; |
||
239 | dev->enable_vsync = r128_enable_vsync; |
||
240 | } else |
||
241 | if( (id==0x4242) || |
||
242 | (id==0x4c57) || |
||
243 | (id==0x4c59) || |
||
244 | (id==0x4c5a) || |
||
245 | ((id>>8)==0x51)) { |
||
246 | dev->iobase = (unsigned long)ioremap(dev->mem[2], 16384); |
||
247 | dev->test_vsync = r128_test_vsync; |
||
248 | dev->ack_vsync = r128_ack_vsync; |
||
249 | dev->enable_vsync = r128_enable_vsync; |
||
250 | } else { |
||
251 | dev->iobase = dev->mem[1]; |
||
252 | dev->test_vsync = rage_test_vsync; |
||
253 | dev->ack_vsync = rage_ack_vsync; |
||
254 | dev->enable_vsync = rage_enable_vsync; |
||
255 | |||
256 | } |
||
257 | break; |
||
258 | case PCI_VENDOR_ID_RENDITION: |
||
259 | dev->iobase = dev->mem[1]; |
||
260 | dev->test_vsync = rendition_test_vsync; |
||
261 | dev->ack_vsync = rendition_ack_vsync; |
||
262 | dev->enable_vsync = rendition_enable_vsync; |
||
263 | break; |
||
264 | default: |
||
265 | dev->test_vsync = vga_test_vsync; |
||
266 | dev->ack_vsync = vga_ack_vsync; |
||
267 | dev->enable_vsync = vga_enable_vsync; |
||
268 | dev->iobase = 0; |
||
269 | } |
||
270 | |||
271 | } |
||
272 |