diff options
Diffstat (limited to 'drivers/char/agp')
-rw-r--r-- | drivers/char/agp/Kconfig | 171 | ||||
-rw-r--r-- | drivers/char/agp/Makefile | 18 | ||||
-rw-r--r-- | drivers/char/agp/agp.h | 331 | ||||
-rw-r--r-- | drivers/char/agp/ali-agp.c | 414 | ||||
-rw-r--r-- | drivers/char/agp/alpha-agp.c | 216 | ||||
-rw-r--r-- | drivers/char/agp/amd-k7-agp.c | 542 | ||||
-rw-r--r-- | drivers/char/agp/amd64-agp.c | 761 | ||||
-rw-r--r-- | drivers/char/agp/ati-agp.c | 548 | ||||
-rw-r--r-- | drivers/char/agp/backend.c | 348 | ||||
-rw-r--r-- | drivers/char/agp/efficeon-agp.c | 463 | ||||
-rw-r--r-- | drivers/char/agp/frontend.c | 1103 | ||||
-rw-r--r-- | drivers/char/agp/generic.c | 1222 | ||||
-rw-r--r-- | drivers/char/agp/hp-agp.c | 552 | ||||
-rw-r--r-- | drivers/char/agp/i460-agp.c | 642 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 1833 | ||||
-rw-r--r-- | drivers/char/agp/isoch.c | 470 | ||||
-rw-r--r-- | drivers/char/agp/nvidia-agp.c | 424 | ||||
-rw-r--r-- | drivers/char/agp/sgi-agp.c | 331 | ||||
-rw-r--r-- | drivers/char/agp/sis-agp.c | 360 | ||||
-rw-r--r-- | drivers/char/agp/sworks-agp.c | 556 | ||||
-rw-r--r-- | drivers/char/agp/uninorth-agp.c | 647 | ||||
-rw-r--r-- | drivers/char/agp/via-agp.c | 548 |
22 files changed, 12500 insertions, 0 deletions
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig new file mode 100644 index 00000000000..7f8c1b53b75 --- /dev/null +++ b/drivers/char/agp/Kconfig @@ -0,0 +1,171 @@ +config AGP + tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU + depends on ALPHA || IA64 || PPC || X86 + default y if GART_IOMMU + ---help--- + AGP (Accelerated Graphics Port) is a bus system mainly used to + connect graphics cards to the rest of the system. + + If you have an AGP system and you say Y here, it will be possible to + use the AGP features of your 3D rendering video card. This code acts + as a sort of "AGP driver" for the motherboard's chipset. + + If you need more texture memory than you can get with the AGP GART + (theoretically up to 256 MB, but in practice usually 64 or 128 MB + due to kernel allocation issues), you could use PCI accesses + and have up to a couple gigs of texture space. + + Note that this is the only means to have XFree4/GLX use + write-combining with MTRR support on the AGP bus. Without it, OpenGL + direct rendering will be a lot slower but still faster than PIO. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called agpgart. + +config AGP_ALI + tristate "ALI chipset support" + depends on AGP && X86 && !X86_64 + ---help--- + This option gives you AGP support for the GLX component of + XFree86 4.x on the following ALi chipsets. The supported chipsets + include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. + For the ALi-chipset question, ALi suggests you refer to + <http://www.ali.com.tw/eng/support/index.shtml>. + + The M1541 chipset can do AGP 1x and 2x, but note that there is an + acknowledged incompatibility with Matrox G200 cards. Due to + timing issues, this chipset cannot do AGP 2x with the G200. + This is a hardware limitation. AGP 1x seems to be fine, though. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + +config AGP_ATI + tristate "ATI chipset support" + depends on AGP && X86 && !X86_64 + ---help--- + This option gives you AGP support for the GLX component of + XFree86 4.x on the ATI RadeonIGP family of chipsets. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + +config AGP_AMD + tristate "AMD Irongate, 761, and 762 chipset support" + depends on AGP && X86 && !X86_64 + help + This option gives you AGP support for the GLX component of + XFree86 4.x on AMD Irongate, 761, and 762 chipsets. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + +config AGP_AMD64 + tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU + depends on AGP && X86 + default y if GART_IOMMU + help + This option gives you AGP support for the GLX component of + XFree86 4.x using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. + You still need an external AGP bridge like the AMD 8151, VIA + K8T400M, SiS755. It may also support other AGP bridges when loaded + with agp_try_unsupported=1. + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say Y + +config AGP_INTEL + tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" + depends on AGP && X86 + help + This option gives you AGP support for the GLX component of XFree86 4.x + on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, + E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G, + 852GM, 855GM, 865G and I915 integrated graphics chipsets. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI, or if you have any Intel integrated graphics + chipsets. If unsure, say Y. + +config AGP_NVIDIA + tristate "NVIDIA nForce/nForce2 chipset support" + depends on AGP && X86 && !X86_64 + help + This option gives you AGP support for the GLX component of + XFree86 4.x on the following NVIDIA chipsets. The supported chipsets + include nForce and nForce2 + +config AGP_SIS + tristate "SiS chipset support" + depends on AGP && X86 && !X86_64 + help + This option gives you AGP support for the GLX component of + XFree86 4.x on Silicon Integrated Systems [SiS] chipsets. + + Note that 5591/5592 AGP chipsets are NOT supported. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + +config AGP_SWORKS + tristate "Serverworks LE/HE chipset support" + depends on AGP && X86 && !X86_64 + help + Say Y here to support the Serverworks AGP card. See + <http://www.serverworks.com/> for product descriptions and images. + +config AGP_VIA + tristate "VIA chipset support" + depends on AGP && X86 && !X86_64 + help + This option gives you AGP support for the GLX component of + XFree86 4.x on VIA MVP3/Apollo Pro chipsets. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say N. + +config AGP_I460 + tristate "Intel 460GX chipset support" + depends on AGP && (IA64_DIG || IA64_GENERIC) + help + This option gives you AGP GART support for the Intel 460GX chipset + for IA64 processors. + +config AGP_HP_ZX1 + tristate "HP ZX1 chipset AGP support" + depends on AGP && (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC) + help + This option gives you AGP GART support for the HP ZX1 chipset + for IA64 processors. + +config AGP_ALPHA_CORE + tristate "Alpha AGP support" + depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL) + default AGP + +config AGP_UNINORTH + tristate "Apple UniNorth & U3 AGP support" + depends on AGP && PPC_PMAC + help + This option gives you AGP support for Apple machines with a + UniNorth or U3 (Apple G5) bridge. + +config AGP_EFFICEON + tristate "Transmeta Efficeon support" + depends on AGP && X86 && !X86_64 + help + This option gives you AGP support for the Transmeta Efficeon + series processors with integrated northbridges. + + You should say Y here if you use XFree86 3.3.6 or 4.x and want to + use GLX or DRI. If unsure, say Y. + +config AGP_SGI_TIOCA + tristate "SGI TIO chipset AGP support" + depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC) + help + This option gives you AGP GART support for the SGI TIO chipset + for IA64 processors. + diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile new file mode 100644 index 00000000000..d33a22f2fa0 --- /dev/null +++ b/drivers/char/agp/Makefile @@ -0,0 +1,18 @@ +agpgart-y := backend.o frontend.o generic.o isoch.o + +obj-$(CONFIG_AGP) += agpgart.o +obj-$(CONFIG_AGP_ALI) += ali-agp.o +obj-$(CONFIG_AGP_ATI) += ati-agp.o +obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o +obj-$(CONFIG_AGP_AMD64) += amd64-agp.o +obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o +obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o +obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o +obj-$(CONFIG_AGP_I460) += i460-agp.o +obj-$(CONFIG_AGP_INTEL) += intel-agp.o +obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o +obj-$(CONFIG_AGP_SGI_TIOCA) += sgi-agp.o +obj-$(CONFIG_AGP_SIS) += sis-agp.o +obj-$(CONFIG_AGP_SWORKS) += sworks-agp.o +obj-$(CONFIG_AGP_UNINORTH) += uninorth-agp.o +obj-$(CONFIG_AGP_VIA) += via-agp.o diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h new file mode 100644 index 00000000000..ad9c11391d8 --- /dev/null +++ b/drivers/char/agp/agp.h @@ -0,0 +1,331 @@ +/* + * AGPGART + * Copyright (C) 2004 Silicon Graphics, Inc. + * Copyright (C) 2002-2004 Dave Jones + * Copyright (C) 1999 Jeff Hartmann + * Copyright (C) 1999 Precision Insight, Inc. + * Copyright (C) 1999 Xi Graphics, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _AGP_BACKEND_PRIV_H +#define _AGP_BACKEND_PRIV_H 1 + +#include <asm/agp.h> /* for flush_agp_cache() */ + +#define PFX "agpgart: " + +//#define AGP_DEBUG 1 +#ifdef AGP_DEBUG +#define DBG(x,y...) printk (KERN_DEBUG PFX "%s: " x "\n", __FUNCTION__ , ## y) +#else +#define DBG(x,y...) do { } while (0) +#endif + +extern struct agp_bridge_data *agp_bridge; + +enum aper_size_type { + U8_APER_SIZE, + U16_APER_SIZE, + U32_APER_SIZE, + LVL2_APER_SIZE, + FIXED_APER_SIZE +}; + +struct gatt_mask { + unsigned long mask; + u32 type; + /* totally device specific, for integrated chipsets that + * might have different types of memory masks. For other + * devices this will probably be ignored */ +}; + +struct aper_size_info_8 { + int size; + int num_entries; + int page_order; + u8 size_value; +}; + +struct aper_size_info_16 { + int size; + int num_entries; + int page_order; + u16 size_value; +}; + +struct aper_size_info_32 { + int size; + int num_entries; + int page_order; + u32 size_value; +}; + +struct aper_size_info_lvl2 { + int size; + int num_entries; + u32 size_value; +}; + +struct aper_size_info_fixed { + int size; + int num_entries; + int page_order; +}; + +struct agp_bridge_driver { + struct module *owner; + void *aperture_sizes; + int num_aperture_sizes; + enum aper_size_type size_type; + int cant_use_aperture; + int needs_scratch_page; + struct gatt_mask *masks; + int (*fetch_size)(void); + int (*configure)(void); + void (*agp_enable)(struct agp_bridge_data *, u32); + void (*cleanup)(void); + void (*tlb_flush)(struct agp_memory *); + unsigned long (*mask_memory)(struct agp_bridge_data *, + unsigned long, int); + void (*cache_flush)(void); + int (*create_gatt_table)(struct agp_bridge_data *); + int (*free_gatt_table)(struct agp_bridge_data *); + int (*insert_memory)(struct agp_memory *, off_t, int); + int (*remove_memory)(struct agp_memory *, off_t, int); + struct agp_memory *(*alloc_by_type) (size_t, int); + void (*free_by_type)(struct agp_memory *); + void *(*agp_alloc_page)(struct agp_bridge_data *); + void (*agp_destroy_page)(void *); +}; + +struct agp_bridge_data { + struct agp_version *version; + struct agp_bridge_driver *driver; + struct vm_operations_struct *vm_ops; + void *previous_size; + void *current_size; + void *dev_private_data; + struct pci_dev *dev; + u32 __iomem *gatt_table; + u32 *gatt_table_real; + unsigned long scratch_page; + unsigned long scratch_page_real; + unsigned long gart_bus_addr; + unsigned long gatt_bus_addr; + u32 mode; + enum chipset_type type; + unsigned long *key_list; + atomic_t current_memory_agp; + atomic_t agp_in_use; + int max_memory_agp; /* in number of pages */ + int aperture_size_idx; + int capndx; + int flags; + char major_version; + char minor_version; + struct list_head list; +}; + +#define KB(x) ((x) * 1024) +#define MB(x) (KB (KB (x))) +#define GB(x) (MB (KB (x))) + +#define A_SIZE_8(x) ((struct aper_size_info_8 *) x) +#define A_SIZE_16(x) ((struct aper_size_info_16 *) x) +#define A_SIZE_32(x) ((struct aper_size_info_32 *) x) +#define A_SIZE_LVL2(x) ((struct aper_size_info_lvl2 *) x) +#define A_SIZE_FIX(x) ((struct aper_size_info_fixed *) x) +#define A_IDX8(bridge) (A_SIZE_8((bridge)->driver->aperture_sizes) + i) +#define A_IDX16(bridge) (A_SIZE_16((bridge)->driver->aperture_sizes) + i) +#define A_IDX32(bridge) (A_SIZE_32((bridge)->driver->aperture_sizes) + i) +#define MAXKEY (4096 * 32) + +#define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page) + + +/* Intel registers */ +#define INTEL_APSIZE 0xb4 +#define INTEL_ATTBASE 0xb8 +#define INTEL_AGPCTRL 0xb0 +#define INTEL_NBXCFG 0x50 +#define INTEL_ERRSTS 0x91 + +/* Intel i830 registers */ +#define I830_GMCH_CTRL 0x52 +#define I830_GMCH_ENABLED 0x4 +#define I830_GMCH_MEM_MASK 0x1 +#define I830_GMCH_MEM_64M 0x1 +#define I830_GMCH_MEM_128M 0 +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_DISABLED 0x00 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 +#define I830_RDRAM_CHANNEL_TYPE 0x03010 +#define I830_RDRAM_ND(x) (((x) & 0x20) >> 5) +#define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3) + +/* This one is for I830MP w. an external graphic card */ +#define INTEL_I830_ERRSTS 0x92 + +/* Intel 855GM/852GM registers */ +#define I855_GMCH_GMS_STOLEN_0M 0x0 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I85X_CAPID 0x44 +#define I85X_VARIANT_MASK 0x7 +#define I85X_VARIANT_SHIFT 5 +#define I855_GME 0x0 +#define I855_GM 0x4 +#define I852_GME 0x2 +#define I852_GM 0x5 + +/* Intel i845 registers */ +#define INTEL_I845_AGPM 0x51 +#define INTEL_I845_ERRSTS 0xc8 + +/* Intel i860 registers */ +#define INTEL_I860_MCHCFG 0x50 +#define INTEL_I860_ERRSTS 0xc8 + +/* Intel i810 registers */ +#define I810_GMADDR 0x10 +#define I810_MMADDR 0x14 +#define I810_PTE_BASE 0x10000 +#define I810_PTE_MAIN_UNCACHED 0x00000000 +#define I810_PTE_LOCAL 0x00000002 +#define I810_PTE_VALID 0x00000001 +#define I810_SMRAM_MISCC 0x70 +#define I810_GFX_MEM_WIN_SIZE 0x00010000 +#define I810_GFX_MEM_WIN_32M 0x00010000 +#define I810_GMS 0x000000c0 +#define I810_GMS_DISABLE 0x00000000 +#define I810_PGETBL_CTL 0x2020 +#define I810_PGETBL_ENABLED 0x00000001 +#define I810_DRAM_CTL 0x3000 +#define I810_DRAM_ROW_0 0x00000001 +#define I810_DRAM_ROW_0_SDRAM 0x00000001 + +struct agp_device_ids { + unsigned short device_id; /* first, to make table easier to read */ + enum chipset_type chipset; + const char *chipset_name; + int (*chipset_setup) (struct pci_dev *pdev); /* used to override generic */ +}; + +/* Driver registration */ +struct agp_bridge_data *agp_alloc_bridge(void); +void agp_put_bridge(struct agp_bridge_data *bridge); +int agp_add_bridge(struct agp_bridge_data *bridge); +void agp_remove_bridge(struct agp_bridge_data *bridge); + +/* Frontend routines. */ +int agp_frontend_initialize(void); +void agp_frontend_cleanup(void); + +/* Generic routines. */ +void agp_generic_enable(struct agp_bridge_data *bridge, u32 mode); +int agp_generic_create_gatt_table(struct agp_bridge_data *bridge); +int agp_generic_free_gatt_table(struct agp_bridge_data *bridge); +struct agp_memory *agp_create_memory(int scratch_pages); +int agp_generic_insert_memory(struct agp_memory *mem, off_t pg_start, int type); +int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type); +struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); +void agp_generic_free_by_type(struct agp_memory *curr); +void *agp_generic_alloc_page(struct agp_bridge_data *bridge); +void agp_generic_destroy_page(void *addr); +void agp_free_key(int key); +int agp_num_entries(void); +u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); +void agp_device_command(u32 command, int agp_v3); +int agp_3_5_enable(struct agp_bridge_data *bridge); +void global_cache_flush(void); +void get_agp_version(struct agp_bridge_data *bridge); +unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, + unsigned long addr, int type); +struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev); + +/* generic routines for agp>=3 */ +int agp3_generic_fetch_size(void); +void agp3_generic_tlbflush(struct agp_memory *mem); +int agp3_generic_configure(void); +void agp3_generic_cleanup(void); + +/* aperture sizes have been standardised since v3 */ +#define AGP_GENERIC_SIZES_ENTRIES 11 +extern struct aper_size_info_16 agp3_generic_sizes[]; + + +extern int agp_off; +extern int agp_try_unsupported_boot; + +/* Chipset independant registers (from AGP Spec) */ +#define AGP_APBASE 0x10 + +#define AGPSTAT 0x4 +#define AGPCMD 0x8 +#define AGPNISTAT 0xc +#define AGPCTRL 0x10 +#define AGPAPSIZE 0x14 +#define AGPNEPG 0x16 +#define AGPGARTLO 0x18 +#define AGPGARTHI 0x1c +#define AGPNICMD 0x20 + +#define AGP_MAJOR_VERSION_SHIFT (20) +#define AGP_MINOR_VERSION_SHIFT (16) + +#define AGPSTAT_RQ_DEPTH (0xff000000) +#define AGPSTAT_RQ_DEPTH_SHIFT 24 + +#define AGPSTAT_CAL_MASK (1<<12|1<<11|1<<10) +#define AGPSTAT_ARQSZ (1<<15|1<<14|1<<13) +#define AGPSTAT_ARQSZ_SHIFT 13 + +#define AGPSTAT_SBA (1<<9) +#define AGPSTAT_AGP_ENABLE (1<<8) +#define AGPSTAT_FW (1<<4) +#define AGPSTAT_MODE_3_0 (1<<3) + +#define AGPSTAT2_1X (1<<0) +#define AGPSTAT2_2X (1<<1) +#define AGPSTAT2_4X (1<<2) + +#define AGPSTAT3_RSVD (1<<2) +#define AGPSTAT3_8X (1<<1) +#define AGPSTAT3_4X (1) + +#define AGPCTRL_APERENB (1<<8) +#define AGPCTRL_GTLBEN (1<<7) + +#define AGP2_RESERVED_MASK 0x00fffcc8 +#define AGP3_RESERVED_MASK 0x00ff00c4 + +#define AGP_ERRATA_FASTWRITES 1<<0 +#define AGP_ERRATA_SBA 1<<1 +#define AGP_ERRATA_1X 1<<2 + +#endif /* _AGP_BACKEND_PRIV_H */ diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c new file mode 100644 index 00000000000..c86a22c5499 --- /dev/null +++ b/drivers/char/agp/ali-agp.c @@ -0,0 +1,414 @@ +/* + * ALi AGPGART routines. + */ + +#include <linux/types.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/agp_backend.h> +#include "agp.h" + +#define ALI_AGPCTRL 0xb8 +#define ALI_ATTBASE 0xbc +#define ALI_TLBCTRL 0xc0 +#define ALI_TAGCTRL 0xc4 +#define ALI_CACHE_FLUSH_CTRL 0xD0 +#define ALI_CACHE_FLUSH_ADDR_MASK 0xFFFFF000 +#define ALI_CACHE_FLUSH_EN 0x100 + +static int ali_fetch_size(void) +{ + int i; + u32 temp; + struct aper_size_info_32 *values; + + pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); + temp &= ~(0xfffffff0); + values = A_SIZE_32(agp_bridge->driver->aperture_sizes); + + for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { + if (temp == values[i].size_value) { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; + return values[i].size; + } + } + + return 0; +} + +static void ali_tlbflush(struct agp_memory *mem) +{ + u32 temp; + + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); + temp &= 0xfffffff0; + temp |= (1<<0 | 1<<1); + pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL, temp); +} + +static void ali_cleanup(void) +{ + struct aper_size_info_32 *previous_size; + u32 temp; + + previous_size = A_SIZE_32(agp_bridge->previous_size); + + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); +// clear tag + pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL, + ((temp & 0xffffff00) | 0x00000001|0x00000002)); + + pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE, + ((temp & 0x00000ff0) | previous_size->size_value)); +} + +static int ali_configure(void) +{ + u32 temp; + struct aper_size_info_32 *current_size; + + current_size = A_SIZE_32(agp_bridge->current_size); + + /* aperture size and gatt addr */ + pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); + temp = (((temp & 0x00000ff0) | (agp_bridge->gatt_bus_addr & 0xfffff000)) + | (current_size->size_value & 0xf)); + pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE, temp); + + /* tlb control */ + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010)); + + /* address to map to */ + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + +#if 0 + if (agp_bridge->type == ALI_M1541) { + u32 nlvm_addr = 0; + + switch (current_size->size_value) { + case 0: break; + case 1: nlvm_addr = 0x100000;break; + case 2: nlvm_addr = 0x200000;break; + case 3: nlvm_addr = 0x400000;break; + case 4: nlvm_addr = 0x800000;break; + case 6: nlvm_addr = 0x1000000;break; + case 7: nlvm_addr = 0x2000000;break; + case 8: nlvm_addr = 0x4000000;break; + case 9: nlvm_addr = 0x8000000;break; + case 10: nlvm_addr = 0x10000000;break; + default: break; + } + nlvm_addr--; + nlvm_addr&=0xfff00000; + + nlvm_addr+= agp_bridge->gart_bus_addr; + nlvm_addr|=(agp_bridge->gart_bus_addr>>12); + printk(KERN_INFO PFX "nlvm top &base = %8x\n",nlvm_addr); + } +#endif + + pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp); + temp &= 0xffffff7f; //enable TLB + pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, temp); + + return 0; +} + + +static void m1541_cache_flush(void) +{ + int i, page_count; + u32 temp; + + global_cache_flush(); + + page_count = 1 << A_SIZE_32(agp_bridge->current_size)->page_order; + for (i = 0; i < PAGE_SIZE * page_count; i += PAGE_SIZE) { + pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, + &temp); + pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, + (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | + (agp_bridge->gatt_bus_addr + i)) | + ALI_CACHE_FLUSH_EN)); + } +} + +static void *m1541_alloc_page(struct agp_bridge_data *bridge) +{ + void *addr = agp_generic_alloc_page(agp_bridge); + u32 temp; + + if (!addr) + return NULL; + + pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, + (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | + virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN )); + return addr; +} + +static void ali_destroy_page(void * addr) +{ + if (addr) { + global_cache_flush(); /* is this really needed? --hch */ + agp_generic_destroy_page(addr); + } +} + +static void m1541_destroy_page(void * addr) +{ + u32 temp; + + if (addr == NULL) + return; + + global_cache_flush(); + + pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, + (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | + virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); + agp_generic_destroy_page(addr); +} + + +/* Setup function */ + +static struct aper_size_info_32 ali_generic_sizes[7] = +{ + {256, 65536, 6, 10}, + {128, 32768, 5, 9}, + {64, 16384, 4, 8}, + {32, 8192, 3, 7}, + {16, 4096, 2, 6}, + {8, 2048, 1, 4}, + {4, 1024, 0, 3} +}; + +struct agp_bridge_driver ali_generic_bridge = { + .owner = THIS_MODULE, + .aperture_sizes = ali_generic_sizes, + .size_type = U32_APER_SIZE, + .num_aperture_sizes = 7, + .configure = ali_configure, + .fetch_size = ali_fetch_size, + .cleanup = ali_cleanup, + .tlb_flush = ali_tlbflush, + .mask_memory = agp_generic_mask_memory, + .masks = NULL, + .agp_enable = agp_generic_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = agp_generic_create_gatt_table, + .free_gatt_table = agp_generic_free_gatt_table, + .insert_memory = agp_generic_insert_memory, + .remove_memory = agp_generic_remove_memory, + .alloc_by_type = agp_generic_alloc_by_type, + .free_by_type = agp_generic_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_destroy_page = ali_destroy_page, +}; + +struct agp_bridge_driver ali_m1541_bridge = { + .owner = THIS_MODULE, + .aperture_sizes = ali_generic_sizes, + .size_type = U32_APER_SIZE, + .num_aperture_sizes = 7, + .configure = ali_configure, + .fetch_size = ali_fetch_size, + .cleanup = ali_cleanup, + .tlb_flush = ali_tlbflush, + .mask_memory = agp_generic_mask_memory, + .masks = NULL, + .agp_enable = agp_generic_enable, + .cache_flush = m1541_cache_flush, + .create_gatt_table = agp_generic_create_gatt_table, + .free_gatt_table = agp_generic_free_gatt_table, + .insert_memory = agp_generic_insert_memory, + .remove_memory = agp_generic_remove_memory, + .alloc_by_type = agp_generic_alloc_by_type, + .free_by_type = agp_generic_free_by_type, + .agp_alloc_page = m1541_alloc_page, + .agp_destroy_page = m1541_destroy_page, +}; + + +static struct agp_device_ids ali_agp_device_ids[] __devinitdata = +{ + { + .device_id = PCI_DEVICE_ID_AL_M1541, + .chipset_name = "M1541", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1621, + .chipset_name = "M1621", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1631, + .chipset_name = "M1631", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1632, + .chipset_name = "M1632", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1641, + .chipset_name = "M1641", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1644, + .chipset_name = "M1644", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1647, + .chipset_name = "M1647", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1651, + .chipset_name = "M1651", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1671, + .chipset_name = "M1671", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1681, + .chipset_name = "M1681", + }, + { + .device_id = PCI_DEVICE_ID_AL_M1683, + .chipset_name = "M1683", + }, + + { }, /* dummy final entry, always present */ +}; + +static int __devinit agp_ali_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct agp_device_ids *devs = ali_agp_device_ids; + struct agp_bridge_data *bridge; + u8 hidden_1621_id, cap_ptr; + int j; + + cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); + if (!cap_ptr) + return -ENODEV; + + /* probe for known chipsets */ + for (j = 0; devs[j].chipset_name; j++) { + if (pdev->device == devs[j].device_id) + goto found; + } + + printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x)\n", + pdev->device); + return -ENODEV; + + +found: + bridge = agp_alloc_bridge(); + if (!bridge) + return -ENOMEM; + + bridge->dev = pdev; + bridge->capndx = cap_ptr; + + switch (pdev->device) { + case PCI_DEVICE_ID_AL_M1541: + bridge->driver = &ali_m1541_bridge; + break; + case PCI_DEVICE_ID_AL_M1621: + pci_read_config_byte(pdev, 0xFB, &hidden_1621_id); + switch (hidden_1621_id) { + case 0x31: + devs[j].chipset_name = "M1631"; + break; + case 0x32: + devs[j].chipset_name = "M1632"; + break; + case 0x41: + devs[j].chipset_name = "M1641"; + break; + case 0x43: + devs[j].chipset_name = "M????"; + break; + case 0x47: + devs[j].chipset_name = "M1647"; + break; + case 0x51: + devs[j].chipset_name = "M1651"; + break; + default: + break; + } + /*FALLTHROUGH*/ + default: + bridge->driver = &ali_generic_bridge; + } + + printk(KERN_INFO PFX "Detected ALi %s chipset\n", + devs[j].chipset_name); + + /* Fill in the mode register */ + pci_read_config_dword(pdev, + bridge->capndx+PCI_AGP_STATUS, + &bridge->mode); + + pci_set_drvdata(pdev, bridge); + return agp_add_bridge(bridge); +} + +static void __devexit agp_ali_remove(struct pci_dev *pdev) +{ + struct agp_bridge_data *bridge = pci_get_drvdata(pdev); + + agp_remove_bridge(bridge); + agp_put_bridge(bridge); +} + +static struct pci_device_id agp_ali_pci_table[] = { + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_AL, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { } +}; + +MODULE_DEVICE_TABLE(pci, agp_ali_pci_table); + +static struct pci_driver agp_ali_pci_driver = { + .name = "agpgart-ali", + .id_table = agp_ali_pci_table, + .probe = agp_ali_probe, + .remove = agp_ali_remove, +}; + +static int __init agp_ali_init(void) +{ + if (agp_off) + return -EINVAL; + return pci_register_driver(&agp_ali_pci_driver); +} + +static void __exit agp_ali_cleanup(void) +{ + pci_unregister_driver(&agp_ali_pci_driver); +} + +module_init(agp_ali_init); +module_exit(agp_ali_cleanup); + +MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); +MODULE_LICENSE("GPL and additional rights"); + diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c new file mode 100644 index 00000000000..a072d32005a --- /dev/null +++ b/drivers/char/agp/alpha-agp.c @@ -0,0 +1,216 @@ +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/agp_backend.h> +#include <linux/mm.h> +#include <linux/slab.h> + +#include <asm/machvec.h> +#include <asm/agp_backend.h> +#include "../../../arch/alpha/kernel/pci_impl.h" + +#include "agp.h" + +static struct page *alpha_core_agp_vm_nopage(struct vm_area_struct *vma, + unsi |