xref: /OK3568_Linux_fs/kernel/drivers/char/agp/intel-agp.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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