brintos

brintos / linux-shallow public Read only

0
0
Text · 13.7 KiB · 8b19a5d Raw
581 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * VIA AGPGART routines.4 */5 6#include <linux/types.h>7#include <linux/module.h>8#include <linux/pci.h>9#include <linux/init.h>10#include <linux/agp_backend.h>11#include "agp.h"12 13static const struct pci_device_id agp_via_pci_table[];14 15#define VIA_GARTCTRL	0x8016#define VIA_APSIZE	0x8417#define VIA_ATTBASE	0x8818 19#define VIA_AGP3_GARTCTRL	0x9020#define VIA_AGP3_APSIZE		0x9421#define VIA_AGP3_ATTBASE	0x9822#define VIA_AGPSEL		0xfd23 24static int via_fetch_size(void)25{26	int i;27	u8 temp;28	struct aper_size_info_8 *values;29 30	values = A_SIZE_8(agp_bridge->driver->aperture_sizes);31	pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp);32	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {33		if (temp == values[i].size_value) {34			agp_bridge->previous_size =35			    agp_bridge->current_size = (void *) (values + i);36			agp_bridge->aperture_size_idx = i;37			return values[i].size;38		}39	}40	printk(KERN_ERR PFX "Unknown aperture size from AGP bridge (0x%x)\n", temp);41	return 0;42}43 44 45static int via_configure(void)46{47	struct aper_size_info_8 *current_size;48 49	current_size = A_SIZE_8(agp_bridge->current_size);50	/* aperture size */51	pci_write_config_byte(agp_bridge->dev, VIA_APSIZE,52			      current_size->size_value);53	/* address to map to */54	agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,55						    AGP_APERTURE_BAR);56 57	/* GART control register */58	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f);59 60	/* attbase - aperture GATT base */61	pci_write_config_dword(agp_bridge->dev, VIA_ATTBASE,62			    (agp_bridge->gatt_bus_addr & 0xfffff000) | 3);63	return 0;64}65 66 67static void via_cleanup(void)68{69	struct aper_size_info_8 *previous_size;70 71	previous_size = A_SIZE_8(agp_bridge->previous_size);72	pci_write_config_byte(agp_bridge->dev, VIA_APSIZE,73			      previous_size->size_value);74	/* Do not disable by writing 0 to VIA_ATTBASE, it screws things up75	 * during reinitialization.76	 */77}78 79 80static void via_tlbflush(struct agp_memory *mem)81{82	u32 temp;83 84	pci_read_config_dword(agp_bridge->dev, VIA_GARTCTRL, &temp);85	temp |= (1<<7);86	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, temp);87	temp &= ~(1<<7);88	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, temp);89}90 91 92static const struct aper_size_info_8 via_generic_sizes[9] =93{94	{256, 65536, 6, 0},95	{128, 32768, 5, 128},96	{64, 16384, 4, 192},97	{32, 8192, 3, 224},98	{16, 4096, 2, 240},99	{8, 2048, 1, 248},100	{4, 1024, 0, 252},101	{2, 512, 0, 254},102	{1, 256, 0, 255}103};104 105 106static int via_fetch_size_agp3(void)107{108	int i;109	u16 temp;110	struct aper_size_info_16 *values;111 112	values = A_SIZE_16(agp_bridge->driver->aperture_sizes);113	pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp);114	temp &= 0xfff;115 116	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {117		if (temp == values[i].size_value) {118			agp_bridge->previous_size =119				agp_bridge->current_size = (void *) (values + i);120			agp_bridge->aperture_size_idx = i;121			return values[i].size;122		}123	}124	return 0;125}126 127 128static int via_configure_agp3(void)129{130	u32 temp;131 132	/* address to map to */133	agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,134						    AGP_APERTURE_BAR);135 136	/* attbase - aperture GATT base */137	pci_write_config_dword(agp_bridge->dev, VIA_AGP3_ATTBASE,138		agp_bridge->gatt_bus_addr & 0xfffff000);139 140	/* 1. Enable GTLB in RX90<7>, all AGP aperture access needs to fetch141	 *    translation table first.142	 * 2. Enable AGP aperture in RX91<0>. This bit controls the enabling of the143	 *    graphics AGP aperture for the AGP3.0 port.144	 */145	pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp);146	pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp | (3<<7));147	return 0;148}149 150 151static void via_cleanup_agp3(void)152{153	struct aper_size_info_16 *previous_size;154 155	previous_size = A_SIZE_16(agp_bridge->previous_size);156	pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, previous_size->size_value);157}158 159 160static void via_tlbflush_agp3(struct agp_memory *mem)161{162	u32 temp;163 164	pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp);165	pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp & ~(1<<7));166	pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp);167}168 169 170static const struct agp_bridge_driver via_agp3_driver = {171	.owner			= THIS_MODULE,172	.aperture_sizes		= agp3_generic_sizes,173	.size_type		= U8_APER_SIZE,174	.num_aperture_sizes	= 10,175	.needs_scratch_page	= true,176	.configure		= via_configure_agp3,177	.fetch_size		= via_fetch_size_agp3,178	.cleanup		= via_cleanup_agp3,179	.tlb_flush		= via_tlbflush_agp3,180	.mask_memory		= agp_generic_mask_memory,181	.masks			= NULL,182	.agp_enable		= agp_generic_enable,183	.cache_flush		= global_cache_flush,184	.create_gatt_table	= agp_generic_create_gatt_table,185	.free_gatt_table	= agp_generic_free_gatt_table,186	.insert_memory		= agp_generic_insert_memory,187	.remove_memory		= agp_generic_remove_memory,188	.alloc_by_type		= agp_generic_alloc_by_type,189	.free_by_type		= agp_generic_free_by_type,190	.agp_alloc_page		= agp_generic_alloc_page,191	.agp_alloc_pages	= agp_generic_alloc_pages,192	.agp_destroy_page	= agp_generic_destroy_page,193	.agp_destroy_pages	= agp_generic_destroy_pages,194	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,195};196 197static const struct agp_bridge_driver via_driver = {198	.owner			= THIS_MODULE,199	.aperture_sizes		= via_generic_sizes,200	.size_type		= U8_APER_SIZE,201	.num_aperture_sizes	= 9,202	.needs_scratch_page	= true,203	.configure		= via_configure,204	.fetch_size		= via_fetch_size,205	.cleanup		= via_cleanup,206	.tlb_flush		= via_tlbflush,207	.mask_memory		= agp_generic_mask_memory,208	.masks			= NULL,209	.agp_enable		= agp_generic_enable,210	.cache_flush		= global_cache_flush,211	.create_gatt_table	= agp_generic_create_gatt_table,212	.free_gatt_table	= agp_generic_free_gatt_table,213	.insert_memory		= agp_generic_insert_memory,214	.remove_memory		= agp_generic_remove_memory,215	.alloc_by_type		= agp_generic_alloc_by_type,216	.free_by_type		= agp_generic_free_by_type,217	.agp_alloc_page		= agp_generic_alloc_page,218	.agp_alloc_pages	= agp_generic_alloc_pages,219	.agp_destroy_page	= agp_generic_destroy_page,220	.agp_destroy_pages	= agp_generic_destroy_pages,221	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,222};223 224static struct agp_device_ids via_agp_device_ids[] =225{226	{227		.device_id	= PCI_DEVICE_ID_VIA_82C597_0,228		.chipset_name	= "Apollo VP3",229	},230 231	{232		.device_id	= PCI_DEVICE_ID_VIA_82C598_0,233		.chipset_name	= "Apollo MVP3",234	},235 236	{237		.device_id	= PCI_DEVICE_ID_VIA_8501_0,238		.chipset_name	= "Apollo MVP4",239	},240 241	/* VT8601 */242	{243		.device_id	= PCI_DEVICE_ID_VIA_8601_0,244		.chipset_name	= "Apollo ProMedia/PLE133Ta",245	},246 247	/* VT82C693A / VT28C694T */248	{249		.device_id	= PCI_DEVICE_ID_VIA_82C691_0,250		.chipset_name	= "Apollo Pro 133",251	},252 253	{254		.device_id	= PCI_DEVICE_ID_VIA_8371_0,255		.chipset_name	= "KX133",256	},257 258	/* VT8633 */259	{260		.device_id	= PCI_DEVICE_ID_VIA_8633_0,261		.chipset_name	= "Pro 266",262	},263 264	{265		.device_id	= PCI_DEVICE_ID_VIA_XN266,266		.chipset_name	= "Apollo Pro266",267	},268 269	/* VT8361 */270	{271		.device_id	= PCI_DEVICE_ID_VIA_8361,272		.chipset_name	= "KLE133",273	},274 275	/* VT8365 / VT8362 */276	{277		.device_id	= PCI_DEVICE_ID_VIA_8363_0,278		.chipset_name	= "Twister-K/KT133x/KM133",279	},280 281	/* VT8753A */282	{283		.device_id	= PCI_DEVICE_ID_VIA_8753_0,284		.chipset_name	= "P4X266",285	},286 287	/* VT8366 */288	{289		.device_id	= PCI_DEVICE_ID_VIA_8367_0,290		.chipset_name	= "KT266/KY266x/KT333",291	},292 293	/* VT8633 (for CuMine/ Celeron) */294	{295		.device_id	= PCI_DEVICE_ID_VIA_8653_0,296		.chipset_name	= "Pro266T",297	},298 299	/* KM266 / PM266 */300	{301		.device_id	= PCI_DEVICE_ID_VIA_XM266,302		.chipset_name	= "PM266/KM266",303	},304 305	/* CLE266 */306	{307		.device_id	= PCI_DEVICE_ID_VIA_862X_0,308		.chipset_name	= "CLE266",309	},310 311	{312		.device_id	= PCI_DEVICE_ID_VIA_8377_0,313		.chipset_name	= "KT400/KT400A/KT600",314	},315 316	/* VT8604 / VT8605 / VT8603317	 * (Apollo Pro133A chipset with S3 Savage4) */318	{319		.device_id	= PCI_DEVICE_ID_VIA_8605_0,320		.chipset_name	= "ProSavage PM133/PL133/PN133"321	},322 323	/* P4M266x/P4N266 */324	{325		.device_id	= PCI_DEVICE_ID_VIA_8703_51_0,326		.chipset_name	= "P4M266x/P4N266",327	},328 329	/* VT8754 */330	{331		.device_id	= PCI_DEVICE_ID_VIA_8754C_0,332		.chipset_name	= "PT800",333	},334 335	/* P4X600 */336	{337		.device_id	= PCI_DEVICE_ID_VIA_8763_0,338		.chipset_name	= "P4X600"339	},340 341	/* KM400 */342	{343		.device_id	= PCI_DEVICE_ID_VIA_8378_0,344		.chipset_name	= "KM400/KM400A",345	},346 347	/* PT880 */348	{349		.device_id	= PCI_DEVICE_ID_VIA_PT880,350		.chipset_name	= "PT880",351	},352 353	/* PT880 Ultra */354	{355		.device_id	= PCI_DEVICE_ID_VIA_PT880ULTRA,356		.chipset_name	= "PT880 Ultra",357	},358 359	/* PT890 */360	{361		.device_id	= PCI_DEVICE_ID_VIA_8783_0,362		.chipset_name	= "PT890",363	},364 365	/* PM800/PN800/PM880/PN880 */366	{367		.device_id	= PCI_DEVICE_ID_VIA_PX8X0_0,368		.chipset_name	= "PM800/PN800/PM880/PN880",369	},370	/* KT880 */371	{372		.device_id	= PCI_DEVICE_ID_VIA_3269_0,373		.chipset_name	= "KT880",374	},375	/* KTxxx/Px8xx */376	{377		.device_id	= PCI_DEVICE_ID_VIA_83_87XX_1,378		.chipset_name	= "VT83xx/VT87xx/KTxxx/Px8xx",379	},380	/* P4M800 */381	{382		.device_id	= PCI_DEVICE_ID_VIA_3296_0,383		.chipset_name	= "P4M800",384	},385	/* P4M800CE */386	{387		.device_id	= PCI_DEVICE_ID_VIA_P4M800CE,388		.chipset_name	= "VT3314",389	},390	/* VT3324 / CX700 */391	{392		.device_id  = PCI_DEVICE_ID_VIA_VT3324,393		.chipset_name   = "CX700",394	},395	/* VT3336 - this is a chipset for AMD Athlon/K8 CPU. Due to K8's unique396	 * architecture, the AGP resource and behavior are different from397	 * the traditional AGP which resides only in chipset. AGP is used398	 * by 3D driver which wasn't available for the VT3336 and VT3364399	 * generation until now.  Unfortunately, by testing, VT3364 works400	 * but VT3336 doesn't. - explanation from via, just leave this as401	 * as a placeholder to avoid future patches adding it back in.402	 */403#if 0404	{405		.device_id  = PCI_DEVICE_ID_VIA_VT3336,406		.chipset_name   = "VT3336",407	},408#endif409	/* P4M890 */410	{411		.device_id  = PCI_DEVICE_ID_VIA_P4M890,412		.chipset_name   = "P4M890",413	},414	/* P4M900 */415	{416		.device_id  = PCI_DEVICE_ID_VIA_VT3364,417		.chipset_name   = "P4M900",418	},419	{ }, /* dummy final entry, always present */420};421 422 423/*424 * VIA's AGP3 chipsets do magick to put the AGP bridge compliant425 * with the same standards version as the graphics card.426 */427static void check_via_agp3 (struct agp_bridge_data *bridge)428{429	u8 reg;430 431	pci_read_config_byte(bridge->dev, VIA_AGPSEL, &reg);432	/* Check AGP 2.0 compatibility mode. */433	if ((reg & (1<<1))==0)434		bridge->driver = &via_agp3_driver;435}436 437 438static int agp_via_probe(struct pci_dev *pdev, const struct pci_device_id *ent)439{440	struct agp_device_ids *devs = via_agp_device_ids;441	struct agp_bridge_data *bridge;442	int j = 0;443	u8 cap_ptr;444 445	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);446	if (!cap_ptr)447		return -ENODEV;448 449	j = ent - agp_via_pci_table;450	printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name);451 452	bridge = agp_alloc_bridge();453	if (!bridge)454		return -ENOMEM;455 456	bridge->dev = pdev;457	bridge->capndx = cap_ptr;458	bridge->driver = &via_driver;459 460	/*461	 * Garg, there are KT400s with KT266 IDs.462	 */463	if (pdev->device == PCI_DEVICE_ID_VIA_8367_0) {464		/* Is there a KT400 subsystem ? */465		if (pdev->subsystem_device == PCI_DEVICE_ID_VIA_8377_0) {466			printk(KERN_INFO PFX "Found KT400 in disguise as a KT266.\n");467			check_via_agp3(bridge);468		}469	}470 471	/* If this is an AGP3 bridge, check which mode its in and adjust. */472	get_agp_version(bridge);473	if (bridge->major_version >= 3)474		check_via_agp3(bridge);475 476	/* Fill in the mode register */477	pci_read_config_dword(pdev,478			bridge->capndx+PCI_AGP_STATUS, &bridge->mode);479 480	pci_set_drvdata(pdev, bridge);481	return agp_add_bridge(bridge);482}483 484static void agp_via_remove(struct pci_dev *pdev)485{486	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);487 488	agp_remove_bridge(bridge);489	agp_put_bridge(bridge);490}491 492static int agp_via_resume(struct device *dev)493{494	struct agp_bridge_data *bridge = dev_get_drvdata(dev);495 496	if (bridge->driver == &via_agp3_driver)497		return via_configure_agp3();498	else if (bridge->driver == &via_driver)499		return via_configure();500 501	return 0;502}503 504/* must be the same order as name table above */505static const struct pci_device_id agp_via_pci_table[] = {506#define ID(x) \507	{						\508	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	\509	.class_mask	= ~0,				\510	.vendor		= PCI_VENDOR_ID_VIA,		\511	.device		= x,				\512	.subvendor	= PCI_ANY_ID,			\513	.subdevice	= PCI_ANY_ID,			\514	}515	ID(PCI_DEVICE_ID_VIA_82C597_0),516	ID(PCI_DEVICE_ID_VIA_82C598_0),517	ID(PCI_DEVICE_ID_VIA_8501_0),518	ID(PCI_DEVICE_ID_VIA_8601_0),519	ID(PCI_DEVICE_ID_VIA_82C691_0),520	ID(PCI_DEVICE_ID_VIA_8371_0),521	ID(PCI_DEVICE_ID_VIA_8633_0),522	ID(PCI_DEVICE_ID_VIA_XN266),523	ID(PCI_DEVICE_ID_VIA_8361),524	ID(PCI_DEVICE_ID_VIA_8363_0),525	ID(PCI_DEVICE_ID_VIA_8753_0),526	ID(PCI_DEVICE_ID_VIA_8367_0),527	ID(PCI_DEVICE_ID_VIA_8653_0),528	ID(PCI_DEVICE_ID_VIA_XM266),529	ID(PCI_DEVICE_ID_VIA_862X_0),530	ID(PCI_DEVICE_ID_VIA_8377_0),531	ID(PCI_DEVICE_ID_VIA_8605_0),532	ID(PCI_DEVICE_ID_VIA_8703_51_0),533	ID(PCI_DEVICE_ID_VIA_8754C_0),534	ID(PCI_DEVICE_ID_VIA_8763_0),535	ID(PCI_DEVICE_ID_VIA_8378_0),536	ID(PCI_DEVICE_ID_VIA_PT880),537	ID(PCI_DEVICE_ID_VIA_PT880ULTRA),538	ID(PCI_DEVICE_ID_VIA_8783_0),539	ID(PCI_DEVICE_ID_VIA_PX8X0_0),540	ID(PCI_DEVICE_ID_VIA_3269_0),541	ID(PCI_DEVICE_ID_VIA_83_87XX_1),542	ID(PCI_DEVICE_ID_VIA_3296_0),543	ID(PCI_DEVICE_ID_VIA_P4M800CE),544	ID(PCI_DEVICE_ID_VIA_VT3324),545	ID(PCI_DEVICE_ID_VIA_P4M890),546	ID(PCI_DEVICE_ID_VIA_VT3364),547	{ }548};549 550MODULE_DEVICE_TABLE(pci, agp_via_pci_table);551 552static DEFINE_SIMPLE_DEV_PM_OPS(agp_via_pm_ops, NULL, agp_via_resume);553 554static struct pci_driver agp_via_pci_driver = {555	.name		= "agpgart-via",556	.id_table	= agp_via_pci_table,557	.probe		= agp_via_probe,558	.remove		= agp_via_remove,559	.driver.pm      = &agp_via_pm_ops,560};561 562 563static int __init agp_via_init(void)564{565	if (agp_off)566		return -EINVAL;567	return pci_register_driver(&agp_via_pci_driver);568}569 570static void __exit agp_via_cleanup(void)571{572	pci_unregister_driver(&agp_via_pci_driver);573}574 575module_init(agp_via_init);576module_exit(agp_via_cleanup);577 578MODULE_DESCRIPTION("VIA AGPGART routines");579MODULE_LICENSE("GPL");580MODULE_AUTHOR("Dave Jones");581