Commit 0b778621 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-dj.bkbits.net/agpgart

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 49838689 d9654a8c
...@@ -201,7 +201,7 @@ S: Maintained ...@@ -201,7 +201,7 @@ S: Maintained
AGPGART DRIVER AGPGART DRIVER
P: Dave Jones P: Dave Jones
M: davej@codemonkey.org.uk M: davej@codemonkey.org.uk
W: http://www.codemonkey.org.uk/agp/ W: http://www.codemonkey.org.uk/projects/agp/
S: Maintained S: Maintained
AHA152X SCSI DRIVER AHA152X SCSI DRIVER
......
...@@ -77,7 +77,7 @@ config AGP_AMD64 ...@@ -77,7 +77,7 @@ config AGP_AMD64
config AGP_INTEL config AGP_INTEL
tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
depends on AGP && X86 depends on AGP && X86 && !X86_64
help help
This option gives you AGP support for the GLX component of XFree86 4.x 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, on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875,
...@@ -88,6 +88,16 @@ config AGP_INTEL ...@@ -88,6 +88,16 @@ config AGP_INTEL
use GLX or DRI, or if you have any Intel integrated graphics use GLX or DRI, or if you have any Intel integrated graphics
chipsets. If unsure, say Y. chipsets. If unsure, say Y.
config AGP_INTEL_MCH
tristate "Intel i865 chipset support"
depends on AGP && X86
help
This option gives you AGP support for the GLX component of XFree86 4.x
on Intel chipsets that support Intel EM64T processors.
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_NVIDIA config AGP_NVIDIA
tristate "NVIDIA nForce/nForce2 chipset support" tristate "NVIDIA nForce/nForce2 chipset support"
depends on AGP && X86 && !X86_64 depends on AGP && X86 && !X86_64
......
...@@ -9,6 +9,7 @@ obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o ...@@ -9,6 +9,7 @@ obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o
obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o
obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
obj-$(CONFIG_AGP_I460) += i460-agp.o obj-$(CONFIG_AGP_I460) += i460-agp.o
obj-$(CONFIG_AGP_INTEL_MCH) += intel-mch-agp.o
obj-$(CONFIG_AGP_INTEL) += intel-agp.o obj-$(CONFIG_AGP_INTEL) += intel-agp.o
obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o
obj-$(CONFIG_AGP_SIS) += sis-agp.o obj-$(CONFIG_AGP_SIS) += sis-agp.o
......
/* /*
* AGPGART * AGPGART
* Copyright (C) 2002-2003 Dave Jones * Copyright (C) 2002-2004 Dave Jones
* Copyright (C) 1999 Jeff Hartmann * Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc. * Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc. * Copyright (C) 1999 Xi Graphics, Inc.
...@@ -167,8 +167,6 @@ struct agp_bridge_data { ...@@ -167,8 +167,6 @@ struct agp_bridge_data {
#define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page) #define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page)
/* Chipset independant registers (from AGP Spec) */
#define AGP_APBASE 0x10
/* Intel registers */ /* Intel registers */
#define INTEL_APSIZE 0xb4 #define INTEL_APSIZE 0xb4
...@@ -177,14 +175,6 @@ struct agp_bridge_data { ...@@ -177,14 +175,6 @@ struct agp_bridge_data {
#define INTEL_NBXCFG 0x50 #define INTEL_NBXCFG 0x50
#define INTEL_ERRSTS 0x91 #define INTEL_ERRSTS 0x91
/* Intel 460GX Registers */
#define INTEL_I460_BAPBASE 0x98
#define INTEL_I460_GXBCTL 0xa0
#define INTEL_I460_AGPSIZ 0xa2
#define INTEL_I460_ATTBASE 0xfe200000
#define INTEL_I460_GATT_VALID (1UL << 24)
#define INTEL_I460_GATT_COHERENT (1UL << 25)
/* Intel i830 registers */ /* Intel i830 registers */
#define I830_GMCH_CTRL 0x52 #define I830_GMCH_CTRL 0x52
#define I830_GMCH_ENABLED 0x4 #define I830_GMCH_ENABLED 0x4
...@@ -219,26 +209,10 @@ struct agp_bridge_data { ...@@ -219,26 +209,10 @@ struct agp_bridge_data {
#define I852_GME 0x2 #define I852_GME 0x2
#define I852_GM 0x5 #define I852_GM 0x5
/* Intel 815 register */
#define INTEL_815_APCONT 0x51
#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
/* Intel i820 registers */
#define INTEL_I820_RDCR 0x51
#define INTEL_I820_ERRSTS 0xc8
/* Intel i840 registers */
#define INTEL_I840_MCHCFG 0x50
#define INTEL_I840_ERRSTS 0xc8
/* Intel i845 registers */ /* Intel i845 registers */
#define INTEL_I845_AGPM 0x51 #define INTEL_I845_AGPM 0x51
#define INTEL_I845_ERRSTS 0xc8 #define INTEL_I845_ERRSTS 0xc8
/* Intel i850 registers */
#define INTEL_I850_MCHCFG 0x50
#define INTEL_I850_ERRSTS 0xc8
/* Intel i860 registers */ /* Intel i860 registers */
#define INTEL_I860_MCHCFG 0x50 #define INTEL_I860_MCHCFG 0x50
#define INTEL_I860_ERRSTS 0xc8 #define INTEL_I860_ERRSTS 0xc8
...@@ -261,110 +235,6 @@ struct agp_bridge_data { ...@@ -261,110 +235,6 @@ struct agp_bridge_data {
#define I810_DRAM_ROW_0 0x00000001 #define I810_DRAM_ROW_0 0x00000001
#define I810_DRAM_ROW_0_SDRAM 0x00000001 #define I810_DRAM_ROW_0_SDRAM 0x00000001
/* Intel 7505 registers */
#define INTEL_I7505_APSIZE 0x74
#define INTEL_I7505_NCAPID 0x60
#define INTEL_I7505_NISTAT 0x6c
#define INTEL_I7505_ATTBASE 0x78
#define INTEL_I7505_ERRSTS 0x42
#define INTEL_I7505_AGPCTRL 0x70
#define INTEL_I7505_MCHCFG 0x50
/* VIA register */
#define VIA_GARTCTRL 0x80
#define VIA_APSIZE 0x84
#define VIA_ATTBASE 0x88
/* VIA KT400 */
#define VIA_AGP3_GARTCTRL 0x90
#define VIA_AGP3_APSIZE 0x94
#define VIA_AGP3_ATTBASE 0x98
#define VIA_AGPSEL 0xfd
/* SiS registers */
#define SIS_ATTBASE 0x90
#define SIS_APSIZE 0x94
#define SIS_TLBCNTRL 0x97
#define SIS_TLBFLUSH 0x98
/* AMD registers */
#define AMD_MMBASE 0x14
#define AMD_APSIZE 0xac
#define AMD_MODECNTL 0xb0
#define AMD_MODECNTL2 0xb2
#define AMD_GARTENABLE 0x02 /* In mmio region (16-bit register) */
#define AMD_ATTBASE 0x04 /* In mmio region (32-bit register) */
#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
/* AMD64 registers */
#define AMD64_GARTAPERTURECTL 0x90
#define AMD64_GARTAPERTUREBASE 0x94
#define AMD64_GARTTABLEBASE 0x98
#define AMD64_GARTCACHECTL 0x9c
#define AMD64_GARTEN (1<<0)
/* ALi registers */
#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
/* ATI register */
#define ATI_GART_MMBASE_ADDR 0x14
#define ATI_RS100_APSIZE 0xac
#define ATI_RS300_APSIZE 0xf8
#define ATI_RS100_IG_AGPMODE 0xb0
#define ATI_RS300_IG_AGPMODE 0xfc
#define ATI_GART_FEATURE_ID 0x00
#define ATI_GART_BASE 0x04
#define ATI_GART_CACHE_SZBASE 0x08
#define ATI_GART_CACHE_CNTRL 0x0c
#define ATI_GART_CACHE_ENTRY_CNTRL 0x10
/* Serverworks Registers */
#define SVWRKS_APSIZE 0x10
#define SVWRKS_SIZE_MASK 0xfe000000
#define SVWRKS_MMBASE 0x14
#define SVWRKS_CACHING 0x4b
#define SVWRKS_FEATURE 0x68
/* func 1 registers */
#define SVWRKS_AGP_ENABLE 0x60
#define SVWRKS_COMMAND 0x04
/* Memory mapped registers */
#define SVWRKS_GART_CACHE 0x02
#define SVWRKS_GATTBASE 0x04
#define SVWRKS_TLBFLUSH 0x10
#define SVWRKS_POSTFLUSH 0x14
#define SVWRKS_DIRFLUSH 0x0c
/* HP ZX1 SBA registers */
#define HP_ZX1_CTRL 0x200
#define HP_ZX1_IBASE 0x300
#define HP_ZX1_IMASK 0x308
#define HP_ZX1_PCOM 0x310
#define HP_ZX1_TCNFG 0x318
#define HP_ZX1_PDIR_BASE 0x320
#define HP_ZX1_CACHE_FLUSH 0x428
/* NVIDIA registers */
#define NVIDIA_0_APSIZE 0x80
#define NVIDIA_1_WBC 0xf0
#define NVIDIA_2_GARTCTRL 0xd0
#define NVIDIA_2_APBASE 0xd8
#define NVIDIA_2_APLIMIT 0xdc
#define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4)
#define NVIDIA_3_APBASE 0x50
#define NVIDIA_3_APLIMIT 0x54
struct agp_device_ids { struct agp_device_ids {
unsigned short device_id; /* first, to make table easier to read */ unsigned short device_id; /* first, to make table easier to read */
enum chipset_type chipset; enum chipset_type chipset;
...@@ -402,21 +272,38 @@ void global_cache_flush(void); ...@@ -402,21 +272,38 @@ void global_cache_flush(void);
void get_agp_version(struct agp_bridge_data *bridge); void get_agp_version(struct agp_bridge_data *bridge);
unsigned long agp_generic_mask_memory(unsigned long addr, int type); unsigned long agp_generic_mask_memory(unsigned long addr, int type);
/* 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_off;
extern int agp_try_unsupported_boot; extern int agp_try_unsupported_boot;
/* Standard agp registers */ /* Chipset independant registers (from AGP Spec) */
#define AGP_APBASE 0x10
#define AGPSTAT 0x4 #define AGPSTAT 0x4
#define AGPCMD 0x8 #define AGPCMD 0x8
#define AGPNISTAT 0xc #define AGPNISTAT 0xc
#define AGPCTRL 0x10 #define AGPCTRL 0x10
#define AGPAPSIZE 0x14
#define AGPNEPG 0x16 #define AGPNEPG 0x16
#define AGPGARTLO 0x18
#define AGPGARTHI 0x1c
#define AGPNICMD 0x20 #define AGPNICMD 0x20
#define AGP_MAJOR_VERSION_SHIFT (20) #define AGP_MAJOR_VERSION_SHIFT (20)
#define AGP_MINOR_VERSION_SHIFT (16) #define AGP_MINOR_VERSION_SHIFT (16)
#define AGPSTAT_RQ_DEPTH (0xff000000) #define AGPSTAT_RQ_DEPTH (0xff000000)
#define AGPSTAT_RQ_DEPTH_SHIFT 24
#define AGPSTAT_CAL_MASK (1<<12|1<<11|1<<10) #define AGPSTAT_CAL_MASK (1<<12|1<<11|1<<10)
#define AGPSTAT_ARQSZ (1<<15|1<<14|1<<13) #define AGPSTAT_ARQSZ (1<<15|1<<14|1<<13)
...@@ -435,4 +322,7 @@ extern int agp_try_unsupported_boot; ...@@ -435,4 +322,7 @@ extern int agp_try_unsupported_boot;
#define AGPSTAT3_8X (1<<1) #define AGPSTAT3_8X (1<<1)
#define AGPSTAT3_4X (1) #define AGPSTAT3_4X (1)
#define AGPCTRL_APERENB (1<<8)
#define AGPCTRL_GTLBEN (1<<7)
#endif /* _AGP_BACKEND_PRIV_H */ #endif /* _AGP_BACKEND_PRIV_H */
...@@ -9,6 +9,14 @@ ...@@ -9,6 +9,14 @@
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include "agp.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) static int ali_fetch_size(void)
{ {
int i; int i;
......
...@@ -11,6 +11,15 @@ ...@@ -11,6 +11,15 @@
#include <linux/mm.h> #include <linux/mm.h>
#include "agp.h" #include "agp.h"
#define AMD_MMBASE 0x14
#define AMD_APSIZE 0xac
#define AMD_MODECNTL 0xb0
#define AMD_MODECNTL2 0xb2
#define AMD_GARTENABLE 0x02 /* In mmio region (16-bit register) */
#define AMD_ATTBASE 0x04 /* In mmio region (32-bit register) */
#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
struct amd_page_map { struct amd_page_map {
unsigned long *real; unsigned long *real;
unsigned long *remapped; unsigned long *remapped;
......
...@@ -31,6 +31,13 @@ ...@@ -31,6 +31,13 @@
#define INVGART (1<<0) #define INVGART (1<<0)
#define GARTPTEERR (1<<1) #define GARTPTEERR (1<<1)
/* K8 On-cpu GART registers */
#define AMD64_GARTAPERTURECTL 0x90
#define AMD64_GARTAPERTUREBASE 0x94
#define AMD64_GARTTABLEBASE 0x98
#define AMD64_GARTCACHECTL 0x9c
#define AMD64_GARTEN (1<<0)
/* NVIDIA K8 registers */ /* NVIDIA K8 registers */
#define NVIDIA_X86_64_0_APBASE 0x10 #define NVIDIA_X86_64_0_APBASE 0x10
#define NVIDIA_X86_64_1_APBASE1 0x50 #define NVIDIA_X86_64_1_APBASE1 0x50
...@@ -382,6 +389,7 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data ...@@ -382,6 +389,7 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data
case 0x11: revstring="B0"; break; case 0x11: revstring="B0"; break;
case 0x12: revstring="B1"; break; case 0x12: revstring="B1"; break;
case 0x13: revstring="B2"; break; case 0x13: revstring="B2"; break;
case 0x14: revstring="B3"; break;
default: revstring="??"; break; default: revstring="??"; break;
} }
......
...@@ -10,6 +10,18 @@ ...@@ -10,6 +10,18 @@
#include <asm/agp.h> #include <asm/agp.h>
#include "agp.h" #include "agp.h"
#define ATI_GART_MMBASE_ADDR 0x14
#define ATI_RS100_APSIZE 0xac
#define ATI_RS100_IG_AGPMODE 0xb0
#define ATI_RS300_APSIZE 0xf8
#define ATI_RS300_IG_AGPMODE 0xfc
#define ATI_GART_FEATURE_ID 0x00
#define ATI_GART_BASE 0x04
#define ATI_GART_CACHE_SZBASE 0x08
#define ATI_GART_CACHE_CNTRL 0x0c
#define ATI_GART_CACHE_ENTRY_CNTRL 0x10
static struct aper_size_info_lvl2 ati_generic_sizes[7] = static struct aper_size_info_lvl2 ati_generic_sizes[7] =
{ {
{2048, 524288, 0x0000000c}, {2048, 524288, 0x0000000c},
......
...@@ -956,3 +956,85 @@ unsigned long agp_generic_mask_memory(unsigned long addr, int type) ...@@ -956,3 +956,85 @@ unsigned long agp_generic_mask_memory(unsigned long addr, int type)
} }
EXPORT_SYMBOL(agp_generic_mask_memory); EXPORT_SYMBOL(agp_generic_mask_memory);
/*
* These functions are implemented according to the AGPv3 spec,
* which covers implementation details that had previously been
* left open.
*/
int agp3_generic_fetch_size(void)
{
u16 temp_size;
int i;
struct aper_size_info_16 *values;
pci_read_config_word(agp_bridge->dev, agp_bridge->capndx+AGPAPSIZE, &temp_size);
values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp_size == 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;
}
EXPORT_SYMBOL(agp3_generic_fetch_size);
void agp3_generic_tlbflush(struct agp_memory *mem)
{
u32 ctrl;
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &ctrl);
pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, ctrl & ~AGPCTRL_GTLBEN);
pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, ctrl);
}
EXPORT_SYMBOL(agp3_generic_tlbflush);
int agp3_generic_configure(void)
{
u32 temp;
struct aper_size_info_16 *current_size;
current_size = A_SIZE_16(agp_bridge->current_size);
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* set aperture size */
pci_write_config_word(agp_bridge->dev, agp_bridge->capndx+AGPAPSIZE, current_size->size_value);
/* set gart pointer */
pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPGARTLO, agp_bridge->gatt_bus_addr);
/* enable aperture and GTLB */
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, temp | AGPCTRL_APERENB | AGPCTRL_GTLBEN);
return 0;
}
EXPORT_SYMBOL(agp3_generic_configure);
void agp3_generic_cleanup(void)
{
u32 ctrl;
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &ctrl);
pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, ctrl & ~AGPCTRL_APERENB);
}
EXPORT_SYMBOL(agp3_generic_cleanup);
struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] =
{
{4096, 1048576, 10,0x000},
{2048, 524288, 9, 0x800},
{1024, 262144, 8, 0xc00},
{ 512, 131072, 7, 0xe00},
{ 256, 65536, 6, 0xf00},
{ 128, 32768, 5, 0xf20},
{ 64, 16384, 4, 0xf30},
{ 32, 8192, 3, 0xf38},
{ 16, 4096, 2, 0xf3c},
{ 8, 2048, 1, 0xf3e},
{ 4, 1024, 0, 0xf3f}
};
EXPORT_SYMBOL(agp3_generic_sizes);
...@@ -14,6 +14,13 @@ ...@@ -14,6 +14,13 @@
#include "agp.h" #include "agp.h"
#define INTEL_I460_BAPBASE 0x98
#define INTEL_I460_GXBCTL 0xa0
#define INTEL_I460_AGPSIZ 0xa2
#define INTEL_I460_ATTBASE 0xfe200000
#define INTEL_I460_GATT_VALID (1UL << 24)
#define INTEL_I460_GATT_COHERENT (1UL << 25)
/* /*
* The i460 can operate with large (4MB) pages, but there is no sane way to support this * The i460 can operate with large (4MB) pages, but there is no sane way to support this
* within the current kernel/DRM environment, so we disable the relevant code for now. * within the current kernel/DRM environment, so we disable the relevant code for now.
......
...@@ -13,6 +13,31 @@ ...@@ -13,6 +13,31 @@
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include "agp.h" #include "agp.h"
/* Intel 815 register */
#define INTEL_815_APCONT 0x51
#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
/* Intel i820 registers */
#define INTEL_I820_RDCR 0x51
#define INTEL_I820_ERRSTS 0xc8
/* Intel i840 registers */
#define INTEL_I840_MCHCFG 0x50
#define INTEL_I840_ERRSTS 0xc8
/* Intel i850 registers */
#define INTEL_I850_MCHCFG 0x50
#define INTEL_I850_ERRSTS 0xc8
/* Intel 7505 registers */
#define INTEL_I7505_APSIZE 0x74
#define INTEL_I7505_NCAPID 0x60
#define INTEL_I7505_NISTAT 0x6c
#define INTEL_I7505_ATTBASE 0x78
#define INTEL_I7505_ERRSTS 0x42
#define INTEL_I7505_AGPCTRL 0x70
#define INTEL_I7505_MCHCFG 0x50
static struct aper_size_info_fixed intel_i810_sizes[] = static struct aper_size_info_fixed intel_i810_sizes[] =
{ {
{64, 16384, 4}, {64, 16384, 4},
...@@ -942,7 +967,7 @@ static struct aper_size_info_8 intel_830mp_sizes[4] = ...@@ -942,7 +967,7 @@ static struct aper_size_info_8 intel_830mp_sizes[4] =
{32, 8192, 3, 56} {32, 8192, 3, 56}
}; };
struct agp_bridge_driver intel_generic_driver = { static struct agp_bridge_driver intel_generic_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_generic_sizes, .aperture_sizes = intel_generic_sizes,
.size_type = U16_APER_SIZE, .size_type = U16_APER_SIZE,
...@@ -965,7 +990,7 @@ struct agp_bridge_driver intel_generic_driver = { ...@@ -965,7 +990,7 @@ struct agp_bridge_driver intel_generic_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_810_driver = { static struct agp_bridge_driver intel_810_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_i810_sizes, .aperture_sizes = intel_i810_sizes,
.size_type = FIXED_APER_SIZE, .size_type = FIXED_APER_SIZE,
...@@ -989,8 +1014,7 @@ struct agp_bridge_driver intel_810_driver = { ...@@ -989,8 +1014,7 @@ struct agp_bridge_driver intel_810_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
static struct agp_bridge_driver intel_815_driver = {
struct agp_bridge_driver intel_815_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_815_sizes, .aperture_sizes = intel_815_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
...@@ -1013,7 +1037,7 @@ struct agp_bridge_driver intel_815_driver = { ...@@ -1013,7 +1037,7 @@ struct agp_bridge_driver intel_815_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_830_driver = { static struct agp_bridge_driver intel_830_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_i830_sizes, .aperture_sizes = intel_i830_sizes,
.size_type = FIXED_APER_SIZE, .size_type = FIXED_APER_SIZE,
...@@ -1037,8 +1061,7 @@ struct agp_bridge_driver intel_830_driver = { ...@@ -1037,8 +1061,7 @@ struct agp_bridge_driver intel_830_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
static struct agp_bridge_driver intel_820_driver = {
struct agp_bridge_driver intel_820_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes, .aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
...@@ -1061,7 +1084,7 @@ struct agp_bridge_driver intel_820_driver = { ...@@ -1061,7 +1084,7 @@ struct agp_bridge_driver intel_820_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_830mp_driver = { static struct agp_bridge_driver intel_830mp_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_830mp_sizes, .aperture_sizes = intel_830mp_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
...@@ -1084,7 +1107,7 @@ struct agp_bridge_driver intel_830mp_driver = { ...@@ -1084,7 +1107,7 @@ struct agp_bridge_driver intel_830mp_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_840_driver = { static struct agp_bridge_driver intel_840_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes, .aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
...@@ -1107,7 +1130,7 @@ struct agp_bridge_driver intel_840_driver = { ...@@ -1107,7 +1130,7 @@ struct agp_bridge_driver intel_840_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_845_driver = { static struct agp_bridge_driver intel_845_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes, .aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
...@@ -1130,7 +1153,7 @@ struct agp_bridge_driver intel_845_driver = { ...@@ -1130,7 +1153,7 @@ struct agp_bridge_driver intel_845_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_850_driver = { static struct agp_bridge_driver intel_850_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes, .aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
...@@ -1153,7 +1176,7 @@ struct agp_bridge_driver intel_850_driver = { ...@@ -1153,7 +1176,7 @@ struct agp_bridge_driver intel_850_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_860_driver = { static struct agp_bridge_driver intel_860_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes, .aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
...@@ -1176,7 +1199,7 @@ struct agp_bridge_driver intel_860_driver = { ...@@ -1176,7 +1199,7 @@ struct agp_bridge_driver intel_860_driver = {
.agp_destroy_page = agp_generic_destroy_page, .agp_destroy_page = agp_generic_destroy_page,
}; };
struct agp_bridge_driver intel_7505_driver = { static struct agp_bridge_driver intel_7505_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes, .aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
......
/*
* Intel MCH AGPGART routines.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
#define AGP_DCACHE_MEMORY 1
#define AGP_PHYS_MEMORY 2
static struct gatt_mask intel_i810_masks[] =
{
{.mask = I810_PTE_VALID, .type = 0},
{.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
{.mask = I810_PTE_VALID, .type = 0}
};
static void intel_i810_tlbflush(struct agp_memory *mem)
{
return;
}
static void intel_i810_agp_enable(u32 mode)
{
return;
}
/*
* The i810/i830 requires a physical address to program its mouse
* pointer into hardware.
* However the Xserver still writes to it through the agp aperture.
*/
static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
{
struct agp_memory *new;
void *addr;
if (pg_count != 1)
return NULL;
addr = agp_bridge->driver->agp_alloc_page();
if (addr == NULL)
return NULL;
new = agp_create_memory(1);
if (new == NULL)
return NULL;
new->memory[0] = agp_bridge->driver->mask_memory(virt_to_phys(addr), type);
new->page_count = 1;
new->num_scratch_pages = 1;
new->type = AGP_PHYS_MEMORY;
new->physical = new->memory[0];
return new;
}
static void intel_i810_free_by_type(struct agp_memory *curr)
{
agp_free_key(curr->key);
if(curr->type == AGP_PHYS_MEMORY) {
agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[0]));
vfree(curr->memory);
}
kfree(curr);
}
static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
{
/* Type checking must be done elsewhere */
return addr | agp_bridge->driver->masks[type].mask;
}
static struct aper_size_info_fixed intel_i830_sizes[] =
{
{128, 32768, 5},
/* The 64M mode still requires a 128k gatt */
{64, 16384, 5}
};
static struct _intel_i830_private {
struct pci_dev *i830_dev; /* device one */
volatile u8 *registers;
int gtt_entries;
} intel_i830_private;
static void intel_i830_init_gtt_entries(void)
{
u16 gmch_ctrl;
int gtt_entries;
u8 rdct;
int local = 0;
static const int ddt[4] = { 0, 16, 32, 64 };
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I830_GMCH_GMS_STOLEN_512:
gtt_entries = KB(512) - KB(132);
break;
case I830_GMCH_GMS_STOLEN_1024:
gtt_entries = MB(1) - KB(132);
break;
case I830_GMCH_GMS_STOLEN_8192:
gtt_entries = MB(8) - KB(132);
break;
case I830_GMCH_GMS_LOCAL:
rdct = INREG8(intel_i830_private.registers,
I830_RDRAM_CHANNEL_TYPE);
gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
MB(ddt[I830_RDRAM_DDT(rdct)]);
local = 1;
break;
default:
gtt_entries = 0;
break;
}
} else {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
gtt_entries = MB(1) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_4M:
gtt_entries = MB(4) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_8M:
gtt_entries = MB(8) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_16M:
gtt_entries = MB(16) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_32M:
gtt_entries = MB(32) - KB(132);
break;
default:
gtt_entries = 0;
break;
}
}
if (gtt_entries > 0)
printk(KERN_INFO PFX "Detected %dK %s memory.\n",
gtt_entries / KB(1), local ? "local" : "stolen");
else
printk(KERN_INFO PFX
"No pre-allocated video memory detected.\n");
gtt_entries /= KB(4);
intel_i830_private.gtt_entries = gtt_entries;
}
/* The intel i830 automatically initializes the agp aperture during POST.
* Use the memory already set aside for in the GTT.
*/
static int intel_i830_create_gatt_table(void)
{
int page_order;
struct aper_size_info_fixed *size;
int num_entries;
u32 temp;
size = agp_bridge->current_size;
page_order = size->page_order;
num_entries = size->num_entries;
agp_bridge->gatt_table_real = 0;
pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
temp &= 0xfff80000;
intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096);
if (!intel_i830_private.registers)
return (-ENOMEM);
temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush();
/* we have to call this as early as possible after the MMIO base address is known */
intel_i830_init_gtt_entries();
agp_bridge->gatt_table = NULL;
agp_bridge->gatt_bus_addr = temp;
return(0);
}
/* Return the gatt table to a sane state. Use the top of stolen
* memory for the GTT.
*/
static int intel_i830_free_gatt_table(void)
{
return(0);
}
static int intel_i830_fetch_size(void)
{
u16 gmch_ctrl;
struct aper_size_info_fixed *values;
values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
/* 855GM/852GM/865G has 128MB aperture size */
agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 0;
return(values[0].size);
}
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 0;
return(values[0].size);
} else {
agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 1;
return(values[1].size);
}
return(0);
}
static int intel_i830_configure(void)
{
struct aper_size_info_fixed *current_size;
u32 temp;
u16 gmch_ctrl;
int i;
current_size = A_SIZE_FIX(agp_bridge->current_size);
pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
gmch_ctrl |= I830_GMCH_ENABLED;
pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
global_cache_flush();
if (agp_bridge->driver->needs_scratch_page)
for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
return (0);
}
static void intel_i830_cleanup(void)
{
iounmap((void *) intel_i830_private.registers);
}
static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start,
int type)
{
int i,j,num_entries;
void *temp;
temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
if (pg_start < intel_i830_private.gtt_entries) {
printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
pg_start,intel_i830_private.gtt_entries);
printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
return (-EINVAL);
}
if ((pg_start + mem->page_count) > num_entries)
return (-EINVAL);
/* The i830 can't check the GTT for entries since its read only,
* depend on the caller to make the correct offset decisions.
*/
if ((type != 0 && type != AGP_PHYS_MEMORY) ||
(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
return (-EINVAL);
global_cache_flush();
for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),
agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
global_cache_flush();
agp_bridge->driver->tlb_flush(mem);
return(0);
}
static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
int type)
{
int i;
global_cache_flush();
if (pg_start < intel_i830_private.gtt_entries) {
printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
return (-EINVAL);
}
for (i = pg_start; i < (mem->page_count + pg_start); i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
global_cache_flush();
agp_bridge->driver->tlb_flush(mem);
return (0);
}
static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
{
if (type == AGP_PHYS_MEMORY)
return(alloc_agpphysmem_i8xx(pg_count, type));
/* always return NULL for other allocation types for now */
return(NULL);
}
static int intel_8xx_fetch_size(void)
{
u8 temp;
int i;
struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
values = A_SIZE_8(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 intel_8xx_tlbflush(struct agp_memory *mem)
{
u32 temp;
pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
}
static void intel_8xx_cleanup(void)
{
u16 temp;
struct aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge->previous_size);
pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
}
static int intel_845_configure(void)
{
u32 temp;
u8 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge->current_size);
/* aperture size */
pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
/* 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);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
/* agpm */
pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
/* clear any possible error conditions */
pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
return 0;
}
/* Setup function */
static struct gatt_mask intel_generic_masks[] =
{
{.mask = 0x00000017, .type = 0}
};
static struct aper_size_info_8 intel_8xx_sizes[7] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
{64, 16384, 4, 48},
{32, 8192, 3, 56},
{16, 4096, 2, 60},
{8, 2048, 1, 62},
{4, 1024, 0, 63}
};
static struct agp_bridge_driver intel_830_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_i830_sizes,
.size_type = FIXED_APER_SIZE,
.num_aperture_sizes = 2,
.needs_scratch_page = TRUE,
.configure = intel_i830_configure,
.fetch_size = intel_i830_fetch_size,
.cleanup = intel_i830_cleanup,
.tlb_flush = intel_i810_tlbflush,
.mask_memory = intel_i810_mask_memory,
.masks = intel_i810_masks,
.agp_enable = intel_i810_agp_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = intel_i830_create_gatt_table,
.free_gatt_table = intel_i830_free_gatt_table,
.insert_memory = intel_i830_insert_entries,
.remove_memory = intel_i830_remove_entries,
.alloc_by_type = intel_i830_alloc_by_type,
.free_by_type = intel_i810_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static struct agp_bridge_driver intel_845_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 7,
.configure = intel_845_configure,
.fetch_size = intel_8xx_fetch_size,
.cleanup = intel_8xx_cleanup,
.tlb_flush = intel_8xx_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = intel_generic_masks,
.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 = agp_generic_destroy_page,
};
static int find_i830(u16 device)
{
struct pci_dev *i830_dev;
i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL, device, NULL);
if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
device, i830_dev);
}
if (!i830_dev)
return 0;
intel_i830_private.i830_dev = i830_dev;
return 1;
}
static int __devinit agp_intelmch_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
char *name = "(unknown)";
u8 cap_ptr = 0;
struct resource *r;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
switch (pdev->device) {
case PCI_DEVICE_ID_INTEL_82865_HB:
if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG)) {
bridge->driver = &intel_830_driver;
} else {
bridge->driver = &intel_845_driver;
}
name = "865";
break;
case PCI_DEVICE_ID_INTEL_82875_HB:
bridge->driver = &intel_845_driver;
name = "i875";
break;
default:
printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x)\n",
pdev->device);
return -ENODEV;
};
bridge->dev = pdev;
bridge->capndx = cap_ptr;
if (bridge->driver == &intel_830_driver)
bridge->dev_private_data = &intel_i830_private;
printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
/*
* The following fixes the case where the BIOS has "forgotten" to
* provide an address range for the GART.
* 20030610 - hamish@zot.org
*/
r = &pdev->resource[0];
if (!r->start && r->end) {
if(pci_assign_resource(pdev, 0)) {
printk(KERN_ERR PFX "could not assign resource 0\n");
return (-ENODEV);
}
}
/*
* If the device has not been properly setup, the following will catch
* the problem and should stop the system from crashing.
* 20030610 - hamish@zot.org
*/
if (pci_enable_device(pdev)) {
printk(KERN_ERR PFX "Unable to Enable PCI device\n");
return (-ENODEV);
}
/* Fill in the mode register */
if (cap_ptr) {
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_intelmch_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static int agp_intelmch_suspend(struct pci_dev *dev, u32 state)
{
return 0;
}
static int agp_intelmch_resume(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
if (bridge->driver == &intel_845_driver)
intel_845_configure();
return 0;
}
static struct pci_device_id agp_intelmch_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_intelmch_pci_table);
static struct pci_driver agp_intelmch_pci_driver = {
.name = "agpgart-intel-mch",
.id_table = agp_intelmch_pci_table,
.probe = agp_intelmch_probe,
.remove = agp_intelmch_remove,
.suspend = agp_intelmch_suspend,
.resume = agp_intelmch_resume,
};
/* intel_agp_init() must not be declared static for explicit
early initialization to work (ie i810fb) */
int __init agp_intelmch_init(void)
{
static int agp_initialised=0;
if (agp_initialised == 1)
return 0;
agp_initialised=1;
return pci_module_init(&agp_intelmch_pci_driver);
}
static void __exit agp_intelmch_cleanup(void)
{
pci_unregister_driver(&agp_intelmch_pci_driver);
}
module_init(agp_intelmch_init);
module_exit(agp_intelmch_cleanup);
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_LICENSE("GPL and additional rights");
...@@ -13,6 +13,17 @@ ...@@ -13,6 +13,17 @@
#include <linux/mm.h> #include <linux/mm.h>
#include "agp.h" #include "agp.h"
/* NVIDIA registers */
#define NVIDIA_0_APSIZE 0x80
#define NVIDIA_1_WBC 0xf0
#define NVIDIA_2_GARTCTRL 0xd0
#define NVIDIA_2_APBASE 0xd8
#define NVIDIA_2_APLIMIT 0xdc
#define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4)
#define NVIDIA_3_APBASE 0x50
#define NVIDIA_3_APLIMIT 0x54
static struct _nvidia_private { static struct _nvidia_private {
struct pci_dev *dev_1; struct pci_dev *dev_1;
struct pci_dev *dev_2; struct pci_dev *dev_2;
......
...@@ -8,6 +8,12 @@ ...@@ -8,6 +8,12 @@
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include "agp.h" #include "agp.h"
#define SIS_ATTBASE 0x90
#define SIS_APSIZE 0x94
#define SIS_TLBCNTRL 0x97
#define SIS_TLBFLUSH 0x98
static int sis_fetch_size(void) static int sis_fetch_size(void)
{ {
u8 temp_size; u8 temp_size;
...@@ -61,6 +67,42 @@ static void sis_cleanup(void) ...@@ -61,6 +67,42 @@ static void sis_cleanup(void)
(previous_size->size_value & ~(0x03))); (previous_size->size_value & ~(0x03)));
} }
static void sis_648_enable(u32 mode)
{
struct pci_dev *device = NULL;
u32 command;
int rate;
printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n",
agp_bridge->major_version,
agp_bridge->minor_version,
agp_bridge->dev->slot_name);
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + PCI_AGP_STATUS, &command);
command = agp_collect_device_status(mode, command);
command |= AGPSTAT_AGP_ENABLE;
rate = (command & 0x7) << 2;
while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!agp)
continue;
printk(KERN_INFO PFX "Putting AGP V3 device at %s into %dx mode\n",
pci_name(device), rate);
pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command);
if(device->device == PCI_DEVICE_ID_SI_648) {
// weird: on 648 and 648fx chipsets any rate change in the target command register
// triggers a 5ms screwup during which the master cannot be configured
printk(KERN_INFO PFX "sis 648 agp fix - giving bridge time to recover\n");
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout (1+(HZ*10)/1000);
}
}
}
static struct aper_size_info_8 sis_generic_sizes[7] = static struct aper_size_info_8 sis_generic_sizes[7] =
{ {
{256, 65536, 6, 99}, {256, 65536, 6, 99},
...@@ -176,6 +218,26 @@ static struct agp_device_ids sis_agp_device_ids[] __devinitdata = ...@@ -176,6 +218,26 @@ static struct agp_device_ids sis_agp_device_ids[] __devinitdata =
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
static void __devinit sis_get_driver(struct agp_bridge_data *bridge)
{
if (bridge->dev->device == PCI_DEVICE_ID_SI_648) {
if (agp_bridge->major_version == 3 && agp_bridge->minor_version < 5) {
sis_driver.agp_enable=sis_648_enable;
} else {
sis_driver.agp_enable = sis_648_enable;
sis_driver.aperture_sizes = agp3_generic_sizes;
sis_driver.size_type = U16_APER_SIZE;
sis_driver.num_aperture_sizes = AGP_GENERIC_SIZES_ENTRIES;
sis_driver.configure = agp3_generic_configure;
sis_driver.fetch_size = agp3_generic_fetch_size;
sis_driver.cleanup = agp3_generic_cleanup;
sis_driver.tlb_flush = agp3_generic_tlbflush;
}
}
}
static int __devinit agp_sis_probe(struct pci_dev *pdev, static int __devinit agp_sis_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
...@@ -210,10 +272,11 @@ static int __devinit agp_sis_probe(struct pci_dev *pdev, ...@@ -210,10 +272,11 @@ static int __devinit agp_sis_probe(struct pci_dev *pdev,
bridge->dev = pdev; bridge->dev = pdev;
bridge->capndx = cap_ptr; bridge->capndx = cap_ptr;
get_agp_version(bridge);
/* Fill in the mode register */ /* Fill in the mode register */
pci_read_config_dword(pdev, pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
bridge->capndx+PCI_AGP_STATUS, sis_get_driver(bridge);
&bridge->mode);
pci_set_drvdata(pdev, bridge); pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge); return agp_add_bridge(bridge);
......
...@@ -8,6 +8,23 @@ ...@@ -8,6 +8,23 @@
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include "agp.h" #include "agp.h"
#define SVWRKS_COMMAND 0x04
#define SVWRKS_APSIZE 0x10
#define SVWRKS_MMBASE 0x14
#define SVWRKS_CACHING 0x4b
#define SVWRKS_AGP_ENABLE 0x60
#define SVWRKS_FEATURE 0x68
#define SVWRKS_SIZE_MASK 0xfe000000
/* Memory mapped registers */
#define SVWRKS_GART_CACHE 0x02
#define SVWRKS_GATTBASE 0x04
#define SVWRKS_TLBFLUSH 0x10
#define SVWRKS_POSTFLUSH 0x14
#define SVWRKS_DIRFLUSH 0x0c
struct serverworks_page_map { struct serverworks_page_map {
unsigned long *real; unsigned long *real;
unsigned long *remapped; unsigned long *remapped;
...@@ -454,10 +471,17 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, ...@@ -454,10 +471,17 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
} }
switch (pdev->device) { switch (pdev->device) {
case 0x0006:
/* ServerWorks CNB20HE
Fail silently.*/
printk (KERN_ERR PFX "Detected ServerWorks CNB20HE chipset: No AGP present.\n");
return -ENODEV;
case PCI_DEVICE_ID_SERVERWORKS_HE: case PCI_DEVICE_ID_SERVERWORKS_HE:
case PCI_DEVICE_ID_SERVERWORKS_LE: case PCI_DEVICE_ID_SERVERWORKS_LE:
case 0x0007: case 0x0007:
break; break;
default: default:
printk(KERN_ERR PFX "Unsupported Serverworks chipset " printk(KERN_ERR PFX "Unsupported Serverworks chipset "
"(device id: %04x)\n", pdev->device); "(device id: %04x)\n", pdev->device);
......
...@@ -9,6 +9,15 @@ ...@@ -9,6 +9,15 @@
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include "agp.h" #include "agp.h"
#define VIA_GARTCTRL 0x80
#define VIA_APSIZE 0x84
#define VIA_ATTBASE 0x88
#define VIA_AGP3_GARTCTRL 0x90
#define VIA_AGP3_APSIZE 0x94
#define VIA_AGP3_ATTBASE 0x98
#define VIA_AGPSEL 0xfd
static int via_fetch_size(void) static int via_fetch_size(void)
{ {
int i; int i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment