brintos

brintos / linux-shallow public Read only

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