1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Intel AGPGART routines.
3*4882a593Smuzhiyun */
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun #include <linux/module.h>
6*4882a593Smuzhiyun #include <linux/pci.h>
7*4882a593Smuzhiyun #include <linux/slab.h>
8*4882a593Smuzhiyun #include <linux/init.h>
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/pagemap.h>
11*4882a593Smuzhiyun #include <linux/agp_backend.h>
12*4882a593Smuzhiyun #include <asm/smp.h>
13*4882a593Smuzhiyun #include "agp.h"
14*4882a593Smuzhiyun #include "intel-agp.h"
15*4882a593Smuzhiyun #include <drm/intel-gtt.h>
16*4882a593Smuzhiyun
intel_fetch_size(void)17*4882a593Smuzhiyun static int intel_fetch_size(void)
18*4882a593Smuzhiyun {
19*4882a593Smuzhiyun int i;
20*4882a593Smuzhiyun u16 temp;
21*4882a593Smuzhiyun struct aper_size_info_16 *values;
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
24*4882a593Smuzhiyun values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
27*4882a593Smuzhiyun if (temp == values[i].size_value) {
28*4882a593Smuzhiyun agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
29*4882a593Smuzhiyun agp_bridge->aperture_size_idx = i;
30*4882a593Smuzhiyun return values[i].size;
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun return 0;
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun
__intel_8xx_fetch_size(u8 temp)37*4882a593Smuzhiyun static int __intel_8xx_fetch_size(u8 temp)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun int i;
40*4882a593Smuzhiyun struct aper_size_info_8 *values;
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
45*4882a593Smuzhiyun if (temp == values[i].size_value) {
46*4882a593Smuzhiyun agp_bridge->previous_size =
47*4882a593Smuzhiyun agp_bridge->current_size = (void *) (values + i);
48*4882a593Smuzhiyun agp_bridge->aperture_size_idx = i;
49*4882a593Smuzhiyun return values[i].size;
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun return 0;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun
intel_8xx_fetch_size(void)55*4882a593Smuzhiyun static int intel_8xx_fetch_size(void)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun u8 temp;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
60*4882a593Smuzhiyun return __intel_8xx_fetch_size(temp);
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun
intel_815_fetch_size(void)63*4882a593Smuzhiyun static int intel_815_fetch_size(void)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun u8 temp;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun /* Intel 815 chipsets have a _weird_ APSIZE register with only
68*4882a593Smuzhiyun * one non-reserved bit, so mask the others out ... */
69*4882a593Smuzhiyun pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
70*4882a593Smuzhiyun temp &= (1 << 3);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun return __intel_8xx_fetch_size(temp);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
intel_tlbflush(struct agp_memory * mem)75*4882a593Smuzhiyun static void intel_tlbflush(struct agp_memory *mem)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
78*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun
intel_8xx_tlbflush(struct agp_memory * mem)82*4882a593Smuzhiyun static void intel_8xx_tlbflush(struct agp_memory *mem)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun u32 temp;
85*4882a593Smuzhiyun pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
86*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
87*4882a593Smuzhiyun pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
88*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun
intel_cleanup(void)92*4882a593Smuzhiyun static void intel_cleanup(void)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun u16 temp;
95*4882a593Smuzhiyun struct aper_size_info_16 *previous_size;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun previous_size = A_SIZE_16(agp_bridge->previous_size);
98*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
99*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
100*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun
intel_8xx_cleanup(void)104*4882a593Smuzhiyun static void intel_8xx_cleanup(void)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun u16 temp;
107*4882a593Smuzhiyun struct aper_size_info_8 *previous_size;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun previous_size = A_SIZE_8(agp_bridge->previous_size);
110*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
111*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
112*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun
intel_configure(void)116*4882a593Smuzhiyun static int intel_configure(void)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun u16 temp2;
119*4882a593Smuzhiyun struct aper_size_info_16 *current_size;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun current_size = A_SIZE_16(agp_bridge->current_size);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* aperture size */
124*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /* address to map to */
127*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
128*4882a593Smuzhiyun AGP_APERTURE_BAR);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /* attbase - aperture base */
131*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun /* agpctrl */
134*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun /* paccfg/nbxcfg */
137*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
138*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
139*4882a593Smuzhiyun (temp2 & ~(1 << 10)) | (1 << 9));
140*4882a593Smuzhiyun /* clear any possible error conditions */
141*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
142*4882a593Smuzhiyun return 0;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
intel_815_configure(void)145*4882a593Smuzhiyun static int intel_815_configure(void)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun u32 addr;
148*4882a593Smuzhiyun u8 temp2;
149*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* attbase - aperture base */
152*4882a593Smuzhiyun /* the Intel 815 chipset spec. says that bits 29-31 in the
153*4882a593Smuzhiyun * ATTBASE register are reserved -> try not to write them */
154*4882a593Smuzhiyun if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
155*4882a593Smuzhiyun dev_emerg(&agp_bridge->dev->dev, "gatt bus addr too high");
156*4882a593Smuzhiyun return -EINVAL;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* aperture size */
162*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
163*4882a593Smuzhiyun current_size->size_value);
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun /* address to map to */
166*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
167*4882a593Smuzhiyun AGP_APERTURE_BAR);
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);
170*4882a593Smuzhiyun addr &= INTEL_815_ATTBASE_MASK;
171*4882a593Smuzhiyun addr |= agp_bridge->gatt_bus_addr;
172*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /* agpctrl */
175*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun /* apcont */
178*4882a593Smuzhiyun pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);
179*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun /* clear any possible error conditions */
182*4882a593Smuzhiyun /* Oddness : this chipset seems to have no ERRSTS register ! */
183*4882a593Smuzhiyun return 0;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
intel_820_tlbflush(struct agp_memory * mem)186*4882a593Smuzhiyun static void intel_820_tlbflush(struct agp_memory *mem)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun return;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
intel_820_cleanup(void)191*4882a593Smuzhiyun static void intel_820_cleanup(void)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun u8 temp;
194*4882a593Smuzhiyun struct aper_size_info_8 *previous_size;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun previous_size = A_SIZE_8(agp_bridge->previous_size);
197*4882a593Smuzhiyun pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);
198*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR,
199*4882a593Smuzhiyun temp & ~(1 << 1));
200*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
201*4882a593Smuzhiyun previous_size->size_value);
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun
intel_820_configure(void)205*4882a593Smuzhiyun static int intel_820_configure(void)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun u8 temp2;
208*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /* aperture size */
213*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun /* address to map to */
216*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
217*4882a593Smuzhiyun AGP_APERTURE_BAR);
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /* attbase - aperture base */
220*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* agpctrl */
223*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /* global enable aperture access */
226*4882a593Smuzhiyun /* This flag is not accessed through MCHCFG register as in */
227*4882a593Smuzhiyun /* i850 chipset. */
228*4882a593Smuzhiyun pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);
229*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));
230*4882a593Smuzhiyun /* clear any possible AGP-related error conditions */
231*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c);
232*4882a593Smuzhiyun return 0;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
intel_840_configure(void)235*4882a593Smuzhiyun static int intel_840_configure(void)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun u16 temp2;
238*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun /* aperture size */
243*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun /* address to map to */
246*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
247*4882a593Smuzhiyun AGP_APERTURE_BAR);
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun /* attbase - aperture base */
250*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* agpctrl */
253*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun /* mcgcfg */
256*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);
257*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
258*4882a593Smuzhiyun /* clear any possible error conditions */
259*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000);
260*4882a593Smuzhiyun return 0;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
intel_845_configure(void)263*4882a593Smuzhiyun static int intel_845_configure(void)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun u8 temp2;
266*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun /* aperture size */
271*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun if (agp_bridge->apbase_config != 0) {
274*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
275*4882a593Smuzhiyun agp_bridge->apbase_config);
276*4882a593Smuzhiyun } else {
277*4882a593Smuzhiyun /* address to map to */
278*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
279*4882a593Smuzhiyun AGP_APERTURE_BAR);
280*4882a593Smuzhiyun agp_bridge->apbase_config = agp_bridge->gart_bus_addr;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun /* attbase - aperture base */
284*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun /* agpctrl */
287*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun /* agpm */
290*4882a593Smuzhiyun pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
291*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
292*4882a593Smuzhiyun /* clear any possible error conditions */
293*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
294*4882a593Smuzhiyun return 0;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
intel_850_configure(void)297*4882a593Smuzhiyun static int intel_850_configure(void)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun u16 temp2;
300*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /* aperture size */
305*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun /* address to map to */
308*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
309*4882a593Smuzhiyun AGP_APERTURE_BAR);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun /* attbase - aperture base */
312*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun /* agpctrl */
315*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun /* mcgcfg */
318*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);
319*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
320*4882a593Smuzhiyun /* clear any possible AGP-related error conditions */
321*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c);
322*4882a593Smuzhiyun return 0;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
intel_860_configure(void)325*4882a593Smuzhiyun static int intel_860_configure(void)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun u16 temp2;
328*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun /* aperture size */
333*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun /* address to map to */
336*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
337*4882a593Smuzhiyun AGP_APERTURE_BAR);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun /* attbase - aperture base */
340*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /* agpctrl */
343*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun /* mcgcfg */
346*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);
347*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
348*4882a593Smuzhiyun /* clear any possible AGP-related error conditions */
349*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);
350*4882a593Smuzhiyun return 0;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
intel_830mp_configure(void)353*4882a593Smuzhiyun static int intel_830mp_configure(void)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun u16 temp2;
356*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun /* aperture size */
361*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun /* address to map to */
364*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
365*4882a593Smuzhiyun AGP_APERTURE_BAR);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun /* attbase - aperture base */
368*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun /* agpctrl */
371*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun /* gmch */
374*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
375*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));
376*4882a593Smuzhiyun /* clear any possible AGP-related error conditions */
377*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);
378*4882a593Smuzhiyun return 0;
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun
intel_7505_configure(void)381*4882a593Smuzhiyun static int intel_7505_configure(void)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun u16 temp2;
384*4882a593Smuzhiyun struct aper_size_info_8 *current_size;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun current_size = A_SIZE_8(agp_bridge->current_size);
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun /* aperture size */
389*4882a593Smuzhiyun pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun /* address to map to */
392*4882a593Smuzhiyun agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
393*4882a593Smuzhiyun AGP_APERTURE_BAR);
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /* attbase - aperture base */
396*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun /* agpctrl */
399*4882a593Smuzhiyun pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun /* mchcfg */
402*4882a593Smuzhiyun pci_read_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, &temp2);
403*4882a593Smuzhiyun pci_write_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, temp2 | (1 << 9));
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun return 0;
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun /* Setup function */
409*4882a593Smuzhiyun static const struct gatt_mask intel_generic_masks[] =
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun {.mask = 0x00000017, .type = 0}
412*4882a593Smuzhiyun };
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun static const struct aper_size_info_8 intel_815_sizes[2] =
415*4882a593Smuzhiyun {
416*4882a593Smuzhiyun {64, 16384, 4, 0},
417*4882a593Smuzhiyun {32, 8192, 3, 8},
418*4882a593Smuzhiyun };
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun static const struct aper_size_info_8 intel_8xx_sizes[7] =
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun {256, 65536, 6, 0},
423*4882a593Smuzhiyun {128, 32768, 5, 32},
424*4882a593Smuzhiyun {64, 16384, 4, 48},
425*4882a593Smuzhiyun {32, 8192, 3, 56},
426*4882a593Smuzhiyun {16, 4096, 2, 60},
427*4882a593Smuzhiyun {8, 2048, 1, 62},
428*4882a593Smuzhiyun {4, 1024, 0, 63}
429*4882a593Smuzhiyun };
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun static const struct aper_size_info_16 intel_generic_sizes[7] =
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun {256, 65536, 6, 0},
434*4882a593Smuzhiyun {128, 32768, 5, 32},
435*4882a593Smuzhiyun {64, 16384, 4, 48},
436*4882a593Smuzhiyun {32, 8192, 3, 56},
437*4882a593Smuzhiyun {16, 4096, 2, 60},
438*4882a593Smuzhiyun {8, 2048, 1, 62},
439*4882a593Smuzhiyun {4, 1024, 0, 63}
440*4882a593Smuzhiyun };
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun static const struct aper_size_info_8 intel_830mp_sizes[4] =
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun {256, 65536, 6, 0},
445*4882a593Smuzhiyun {128, 32768, 5, 32},
446*4882a593Smuzhiyun {64, 16384, 4, 48},
447*4882a593Smuzhiyun {32, 8192, 3, 56}
448*4882a593Smuzhiyun };
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun static const struct agp_bridge_driver intel_generic_driver = {
451*4882a593Smuzhiyun .owner = THIS_MODULE,
452*4882a593Smuzhiyun .aperture_sizes = intel_generic_sizes,
453*4882a593Smuzhiyun .size_type = U16_APER_SIZE,
454*4882a593Smuzhiyun .num_aperture_sizes = 7,
455*4882a593Smuzhiyun .needs_scratch_page = true,
456*4882a593Smuzhiyun .configure = intel_configure,
457*4882a593Smuzhiyun .fetch_size = intel_fetch_size,
458*4882a593Smuzhiyun .cleanup = intel_cleanup,
459*4882a593Smuzhiyun .tlb_flush = intel_tlbflush,
460*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
461*4882a593Smuzhiyun .masks = intel_generic_masks,
462*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
463*4882a593Smuzhiyun .cache_flush = global_cache_flush,
464*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
465*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
466*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
467*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
468*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
469*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
470*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
471*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
472*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
473*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
474*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
475*4882a593Smuzhiyun };
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun static const struct agp_bridge_driver intel_815_driver = {
478*4882a593Smuzhiyun .owner = THIS_MODULE,
479*4882a593Smuzhiyun .aperture_sizes = intel_815_sizes,
480*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
481*4882a593Smuzhiyun .num_aperture_sizes = 2,
482*4882a593Smuzhiyun .needs_scratch_page = true,
483*4882a593Smuzhiyun .configure = intel_815_configure,
484*4882a593Smuzhiyun .fetch_size = intel_815_fetch_size,
485*4882a593Smuzhiyun .cleanup = intel_8xx_cleanup,
486*4882a593Smuzhiyun .tlb_flush = intel_8xx_tlbflush,
487*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
488*4882a593Smuzhiyun .masks = intel_generic_masks,
489*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
490*4882a593Smuzhiyun .cache_flush = global_cache_flush,
491*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
492*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
493*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
494*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
495*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
496*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
497*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
498*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
499*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
500*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
501*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
502*4882a593Smuzhiyun };
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun static const struct agp_bridge_driver intel_820_driver = {
505*4882a593Smuzhiyun .owner = THIS_MODULE,
506*4882a593Smuzhiyun .aperture_sizes = intel_8xx_sizes,
507*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
508*4882a593Smuzhiyun .num_aperture_sizes = 7,
509*4882a593Smuzhiyun .needs_scratch_page = true,
510*4882a593Smuzhiyun .configure = intel_820_configure,
511*4882a593Smuzhiyun .fetch_size = intel_8xx_fetch_size,
512*4882a593Smuzhiyun .cleanup = intel_820_cleanup,
513*4882a593Smuzhiyun .tlb_flush = intel_820_tlbflush,
514*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
515*4882a593Smuzhiyun .masks = intel_generic_masks,
516*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
517*4882a593Smuzhiyun .cache_flush = global_cache_flush,
518*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
519*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
520*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
521*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
522*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
523*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
524*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
525*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
526*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
527*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
528*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
529*4882a593Smuzhiyun };
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun static const struct agp_bridge_driver intel_830mp_driver = {
532*4882a593Smuzhiyun .owner = THIS_MODULE,
533*4882a593Smuzhiyun .aperture_sizes = intel_830mp_sizes,
534*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
535*4882a593Smuzhiyun .num_aperture_sizes = 4,
536*4882a593Smuzhiyun .needs_scratch_page = true,
537*4882a593Smuzhiyun .configure = intel_830mp_configure,
538*4882a593Smuzhiyun .fetch_size = intel_8xx_fetch_size,
539*4882a593Smuzhiyun .cleanup = intel_8xx_cleanup,
540*4882a593Smuzhiyun .tlb_flush = intel_8xx_tlbflush,
541*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
542*4882a593Smuzhiyun .masks = intel_generic_masks,
543*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
544*4882a593Smuzhiyun .cache_flush = global_cache_flush,
545*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
546*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
547*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
548*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
549*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
550*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
551*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
552*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
553*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
554*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
555*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
556*4882a593Smuzhiyun };
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun static const struct agp_bridge_driver intel_840_driver = {
559*4882a593Smuzhiyun .owner = THIS_MODULE,
560*4882a593Smuzhiyun .aperture_sizes = intel_8xx_sizes,
561*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
562*4882a593Smuzhiyun .num_aperture_sizes = 7,
563*4882a593Smuzhiyun .needs_scratch_page = true,
564*4882a593Smuzhiyun .configure = intel_840_configure,
565*4882a593Smuzhiyun .fetch_size = intel_8xx_fetch_size,
566*4882a593Smuzhiyun .cleanup = intel_8xx_cleanup,
567*4882a593Smuzhiyun .tlb_flush = intel_8xx_tlbflush,
568*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
569*4882a593Smuzhiyun .masks = intel_generic_masks,
570*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
571*4882a593Smuzhiyun .cache_flush = global_cache_flush,
572*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
573*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
574*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
575*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
576*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
577*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
578*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
579*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
580*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
581*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
582*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
583*4882a593Smuzhiyun };
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun static const struct agp_bridge_driver intel_845_driver = {
586*4882a593Smuzhiyun .owner = THIS_MODULE,
587*4882a593Smuzhiyun .aperture_sizes = intel_8xx_sizes,
588*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
589*4882a593Smuzhiyun .num_aperture_sizes = 7,
590*4882a593Smuzhiyun .needs_scratch_page = true,
591*4882a593Smuzhiyun .configure = intel_845_configure,
592*4882a593Smuzhiyun .fetch_size = intel_8xx_fetch_size,
593*4882a593Smuzhiyun .cleanup = intel_8xx_cleanup,
594*4882a593Smuzhiyun .tlb_flush = intel_8xx_tlbflush,
595*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
596*4882a593Smuzhiyun .masks = intel_generic_masks,
597*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
598*4882a593Smuzhiyun .cache_flush = global_cache_flush,
599*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
600*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
601*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
602*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
603*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
604*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
605*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
606*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
607*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
608*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
609*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
610*4882a593Smuzhiyun };
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun static const struct agp_bridge_driver intel_850_driver = {
613*4882a593Smuzhiyun .owner = THIS_MODULE,
614*4882a593Smuzhiyun .aperture_sizes = intel_8xx_sizes,
615*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
616*4882a593Smuzhiyun .num_aperture_sizes = 7,
617*4882a593Smuzhiyun .needs_scratch_page = true,
618*4882a593Smuzhiyun .configure = intel_850_configure,
619*4882a593Smuzhiyun .fetch_size = intel_8xx_fetch_size,
620*4882a593Smuzhiyun .cleanup = intel_8xx_cleanup,
621*4882a593Smuzhiyun .tlb_flush = intel_8xx_tlbflush,
622*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
623*4882a593Smuzhiyun .masks = intel_generic_masks,
624*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
625*4882a593Smuzhiyun .cache_flush = global_cache_flush,
626*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
627*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
628*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
629*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
630*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
631*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
632*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
633*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
634*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
635*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
636*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
637*4882a593Smuzhiyun };
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun static const struct agp_bridge_driver intel_860_driver = {
640*4882a593Smuzhiyun .owner = THIS_MODULE,
641*4882a593Smuzhiyun .aperture_sizes = intel_8xx_sizes,
642*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
643*4882a593Smuzhiyun .num_aperture_sizes = 7,
644*4882a593Smuzhiyun .needs_scratch_page = true,
645*4882a593Smuzhiyun .configure = intel_860_configure,
646*4882a593Smuzhiyun .fetch_size = intel_8xx_fetch_size,
647*4882a593Smuzhiyun .cleanup = intel_8xx_cleanup,
648*4882a593Smuzhiyun .tlb_flush = intel_8xx_tlbflush,
649*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
650*4882a593Smuzhiyun .masks = intel_generic_masks,
651*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
652*4882a593Smuzhiyun .cache_flush = global_cache_flush,
653*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
654*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
655*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
656*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
657*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
658*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
659*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
660*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
661*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
662*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
663*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
664*4882a593Smuzhiyun };
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun static const struct agp_bridge_driver intel_7505_driver = {
667*4882a593Smuzhiyun .owner = THIS_MODULE,
668*4882a593Smuzhiyun .aperture_sizes = intel_8xx_sizes,
669*4882a593Smuzhiyun .size_type = U8_APER_SIZE,
670*4882a593Smuzhiyun .num_aperture_sizes = 7,
671*4882a593Smuzhiyun .needs_scratch_page = true,
672*4882a593Smuzhiyun .configure = intel_7505_configure,
673*4882a593Smuzhiyun .fetch_size = intel_8xx_fetch_size,
674*4882a593Smuzhiyun .cleanup = intel_8xx_cleanup,
675*4882a593Smuzhiyun .tlb_flush = intel_8xx_tlbflush,
676*4882a593Smuzhiyun .mask_memory = agp_generic_mask_memory,
677*4882a593Smuzhiyun .masks = intel_generic_masks,
678*4882a593Smuzhiyun .agp_enable = agp_generic_enable,
679*4882a593Smuzhiyun .cache_flush = global_cache_flush,
680*4882a593Smuzhiyun .create_gatt_table = agp_generic_create_gatt_table,
681*4882a593Smuzhiyun .free_gatt_table = agp_generic_free_gatt_table,
682*4882a593Smuzhiyun .insert_memory = agp_generic_insert_memory,
683*4882a593Smuzhiyun .remove_memory = agp_generic_remove_memory,
684*4882a593Smuzhiyun .alloc_by_type = agp_generic_alloc_by_type,
685*4882a593Smuzhiyun .free_by_type = agp_generic_free_by_type,
686*4882a593Smuzhiyun .agp_alloc_page = agp_generic_alloc_page,
687*4882a593Smuzhiyun .agp_alloc_pages = agp_generic_alloc_pages,
688*4882a593Smuzhiyun .agp_destroy_page = agp_generic_destroy_page,
689*4882a593Smuzhiyun .agp_destroy_pages = agp_generic_destroy_pages,
690*4882a593Smuzhiyun .agp_type_to_mask_type = agp_generic_type_to_mask_type,
691*4882a593Smuzhiyun };
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of
694*4882a593Smuzhiyun * driver and gmch_driver must be non-null, and find_gmch will determine
695*4882a593Smuzhiyun * which one should be used if a gmch_chip_id is present.
696*4882a593Smuzhiyun */
697*4882a593Smuzhiyun static const struct intel_agp_driver_description {
698*4882a593Smuzhiyun unsigned int chip_id;
699*4882a593Smuzhiyun char *name;
700*4882a593Smuzhiyun const struct agp_bridge_driver *driver;
701*4882a593Smuzhiyun } intel_agp_chipsets[] = {
702*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82443LX_0, "440LX", &intel_generic_driver },
703*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82443BX_0, "440BX", &intel_generic_driver },
704*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82443GX_0, "440GX", &intel_generic_driver },
705*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82815_MC, "i815", &intel_815_driver },
706*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82820_HB, "i820", &intel_820_driver },
707*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver },
708*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver },
709*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver },
710*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82845_HB, "i845", &intel_845_driver },
711*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82845G_HB, "845G", &intel_845_driver },
712*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver },
713*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver },
714*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver },
715*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82855GM_HB, "855GM", &intel_845_driver },
716*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82860_HB, "i860", &intel_860_driver },
717*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82865_HB, "865", &intel_845_driver },
718*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_82875_HB, "i875", &intel_845_driver },
719*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_7505_0, "E7505", &intel_7505_driver },
720*4882a593Smuzhiyun { PCI_DEVICE_ID_INTEL_7205_0, "E7205", &intel_7505_driver },
721*4882a593Smuzhiyun { 0, NULL, NULL }
722*4882a593Smuzhiyun };
723*4882a593Smuzhiyun
agp_intel_probe(struct pci_dev * pdev,const struct pci_device_id * ent)724*4882a593Smuzhiyun static int agp_intel_probe(struct pci_dev *pdev,
725*4882a593Smuzhiyun const struct pci_device_id *ent)
726*4882a593Smuzhiyun {
727*4882a593Smuzhiyun struct agp_bridge_data *bridge;
728*4882a593Smuzhiyun u8 cap_ptr = 0;
729*4882a593Smuzhiyun struct resource *r;
730*4882a593Smuzhiyun int i, err;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
733*4882a593Smuzhiyun
734*4882a593Smuzhiyun bridge = agp_alloc_bridge();
735*4882a593Smuzhiyun if (!bridge)
736*4882a593Smuzhiyun return -ENOMEM;
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun bridge->capndx = cap_ptr;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun if (intel_gmch_probe(pdev, NULL, bridge))
741*4882a593Smuzhiyun goto found_gmch;
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
744*4882a593Smuzhiyun /* In case that multiple models of gfx chip may
745*4882a593Smuzhiyun stand on same host bridge type, this can be
746*4882a593Smuzhiyun sure we detect the right IGD. */
747*4882a593Smuzhiyun if (pdev->device == intel_agp_chipsets[i].chip_id) {
748*4882a593Smuzhiyun bridge->driver = intel_agp_chipsets[i].driver;
749*4882a593Smuzhiyun break;
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun
753*4882a593Smuzhiyun if (!bridge->driver) {
754*4882a593Smuzhiyun if (cap_ptr)
755*4882a593Smuzhiyun dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n",
756*4882a593Smuzhiyun pdev->vendor, pdev->device);
757*4882a593Smuzhiyun agp_put_bridge(bridge);
758*4882a593Smuzhiyun return -ENODEV;
759*4882a593Smuzhiyun }
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun bridge->dev = pdev;
762*4882a593Smuzhiyun bridge->dev_private_data = NULL;
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun /*
767*4882a593Smuzhiyun * The following fixes the case where the BIOS has "forgotten" to
768*4882a593Smuzhiyun * provide an address range for the GART.
769*4882a593Smuzhiyun * 20030610 - hamish@zot.org
770*4882a593Smuzhiyun * This happens before pci_enable_device() intentionally;
771*4882a593Smuzhiyun * calling pci_enable_device() before assigning the resource
772*4882a593Smuzhiyun * will result in the GART being disabled on machines with such
773*4882a593Smuzhiyun * BIOSs (the GART ends up with a BAR starting at 0, which
774*4882a593Smuzhiyun * conflicts a lot of other devices).
775*4882a593Smuzhiyun */
776*4882a593Smuzhiyun r = &pdev->resource[0];
777*4882a593Smuzhiyun if (!r->start && r->end) {
778*4882a593Smuzhiyun if (pci_assign_resource(pdev, 0)) {
779*4882a593Smuzhiyun dev_err(&pdev->dev, "can't assign resource 0\n");
780*4882a593Smuzhiyun agp_put_bridge(bridge);
781*4882a593Smuzhiyun return -ENODEV;
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun /*
786*4882a593Smuzhiyun * If the device has not been properly setup, the following will catch
787*4882a593Smuzhiyun * the problem and should stop the system from crashing.
788*4882a593Smuzhiyun * 20030610 - hamish@zot.org
789*4882a593Smuzhiyun */
790*4882a593Smuzhiyun if (pci_enable_device(pdev)) {
791*4882a593Smuzhiyun dev_err(&pdev->dev, "can't enable PCI device\n");
792*4882a593Smuzhiyun agp_put_bridge(bridge);
793*4882a593Smuzhiyun return -ENODEV;
794*4882a593Smuzhiyun }
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun /* Fill in the mode register */
797*4882a593Smuzhiyun if (cap_ptr) {
798*4882a593Smuzhiyun pci_read_config_dword(pdev,
799*4882a593Smuzhiyun bridge->capndx+PCI_AGP_STATUS,
800*4882a593Smuzhiyun &bridge->mode);
801*4882a593Smuzhiyun }
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun found_gmch:
804*4882a593Smuzhiyun pci_set_drvdata(pdev, bridge);
805*4882a593Smuzhiyun err = agp_add_bridge(bridge);
806*4882a593Smuzhiyun return err;
807*4882a593Smuzhiyun }
808*4882a593Smuzhiyun
agp_intel_remove(struct pci_dev * pdev)809*4882a593Smuzhiyun static void agp_intel_remove(struct pci_dev *pdev)
810*4882a593Smuzhiyun {
811*4882a593Smuzhiyun struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun agp_remove_bridge(bridge);
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun intel_gmch_remove();
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun agp_put_bridge(bridge);
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun #ifdef CONFIG_PM
agp_intel_resume(struct pci_dev * pdev)821*4882a593Smuzhiyun static int agp_intel_resume(struct pci_dev *pdev)
822*4882a593Smuzhiyun {
823*4882a593Smuzhiyun struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
824*4882a593Smuzhiyun
825*4882a593Smuzhiyun bridge->driver->configure();
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun return 0;
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun #endif
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun static const struct pci_device_id agp_intel_pci_table[] = {
832*4882a593Smuzhiyun #define ID(x) \
833*4882a593Smuzhiyun { \
834*4882a593Smuzhiyun .class = (PCI_CLASS_BRIDGE_HOST << 8), \
835*4882a593Smuzhiyun .class_mask = ~0, \
836*4882a593Smuzhiyun .vendor = PCI_VENDOR_ID_INTEL, \
837*4882a593Smuzhiyun .device = x, \
838*4882a593Smuzhiyun .subvendor = PCI_ANY_ID, \
839*4882a593Smuzhiyun .subdevice = PCI_ANY_ID, \
840*4882a593Smuzhiyun }
841*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */
842*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82443LX_0),
843*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82443BX_0),
844*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82443GX_0),
845*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82810_MC1),
846*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82810_MC3),
847*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82810E_MC),
848*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82815_MC),
849*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82820_HB),
850*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82820_UP_HB),
851*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82830_HB),
852*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82840_HB),
853*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82845_HB),
854*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82845G_HB),
855*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82850_HB),
856*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82854_HB),
857*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
858*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
859*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82860_HB),
860*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82865_HB),
861*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82875_HB),
862*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_7505_0),
863*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_7205_0),
864*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_E7221_HB),
865*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82915G_HB),
866*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
867*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82945G_HB),
868*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
869*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
870*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
871*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
872*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
873*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82G35_HB),
874*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
875*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82965G_HB),
876*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
877*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_82965GME_HB),
878*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_G33_HB),
879*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_Q35_HB),
880*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_Q33_HB),
881*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_GM45_HB),
882*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
883*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_Q45_HB),
884*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_G45_HB),
885*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_G41_HB),
886*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_B43_HB),
887*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_B43_1_HB),
888*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
889*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB),
890*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
891*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
892*4882a593Smuzhiyun ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
893*4882a593Smuzhiyun { }
894*4882a593Smuzhiyun };
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
897*4882a593Smuzhiyun
898*4882a593Smuzhiyun static struct pci_driver agp_intel_pci_driver = {
899*4882a593Smuzhiyun .name = "agpgart-intel",
900*4882a593Smuzhiyun .id_table = agp_intel_pci_table,
901*4882a593Smuzhiyun .probe = agp_intel_probe,
902*4882a593Smuzhiyun .remove = agp_intel_remove,
903*4882a593Smuzhiyun #ifdef CONFIG_PM
904*4882a593Smuzhiyun .resume = agp_intel_resume,
905*4882a593Smuzhiyun #endif
906*4882a593Smuzhiyun };
907*4882a593Smuzhiyun
agp_intel_init(void)908*4882a593Smuzhiyun static int __init agp_intel_init(void)
909*4882a593Smuzhiyun {
910*4882a593Smuzhiyun if (agp_off)
911*4882a593Smuzhiyun return -EINVAL;
912*4882a593Smuzhiyun return pci_register_driver(&agp_intel_pci_driver);
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun
agp_intel_cleanup(void)915*4882a593Smuzhiyun static void __exit agp_intel_cleanup(void)
916*4882a593Smuzhiyun {
917*4882a593Smuzhiyun pci_unregister_driver(&agp_intel_pci_driver);
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun module_init(agp_intel_init);
921*4882a593Smuzhiyun module_exit(agp_intel_cleanup);
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun MODULE_AUTHOR("Dave Jones, Various @Intel");
924*4882a593Smuzhiyun MODULE_LICENSE("GPL and additional rights");
925