Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
32f40f52
Commit
32f40f52
authored
Aug 15, 2003
by
Dave Jones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[AGPGART] Merge ATI IGP GART driver.
parent
92d7e8ba
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
599 additions
and
0 deletions
+599
-0
drivers/char/agp/Kconfig
drivers/char/agp/Kconfig
+6
-0
drivers/char/agp/Makefile
drivers/char/agp/Makefile
+1
-0
drivers/char/agp/agp.h
drivers/char/agp/agp.h
+40
-0
drivers/char/agp/ati-agp.c
drivers/char/agp/ati-agp.c
+552
-0
No files found.
drivers/char/agp/Kconfig
View file @
32f40f52
...
@@ -43,6 +43,12 @@ config AGP_ALI
...
@@ -43,6 +43,12 @@ config AGP_ALI
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
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.
use GLX or DRI. If unsure, say N.
config AGP_ATI
tristate "ATI chipset support"
depends on AGP && X86
---help---
config AGP_AMD
config AGP_AMD
tristate "AMD Irongate, 761, and 762 chipset support"
tristate "AMD Irongate, 761, and 762 chipset support"
depends on AGP && X86 && !X86_64
depends on AGP && X86 && !X86_64
...
...
drivers/char/agp/Makefile
View file @
32f40f52
...
@@ -2,6 +2,7 @@ agpgart-y := backend.o frontend.o generic.o isoch.o
...
@@ -2,6 +2,7 @@ agpgart-y := backend.o frontend.o generic.o isoch.o
obj-$(CONFIG_AGP)
+=
agpgart.o
obj-$(CONFIG_AGP)
+=
agpgart.o
obj-$(CONFIG_AGP_ALI)
+=
ali-agp.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_AMD)
+=
amd-k7-agp.o
obj-$(CONFIG_AGP_AMD_8151)
+=
amd-k8-agp.o
obj-$(CONFIG_AGP_AMD_8151)
+=
amd-k8-agp.o
obj-$(CONFIG_AGP_ALPHA_CORE)
+=
alpha-agp.o
obj-$(CONFIG_AGP_ALPHA_CORE)
+=
alpha-agp.o
...
...
drivers/char/agp/agp.h
View file @
32f40f52
...
@@ -326,6 +326,46 @@ struct agp_bridge_data {
...
@@ -326,6 +326,46 @@ struct agp_bridge_data {
#define ALI_CACHE_FLUSH_ADDR_MASK 0xFFFFF000
#define ALI_CACHE_FLUSH_ADDR_MASK 0xFFFFF000
#define ALI_CACHE_FLUSH_EN 0x100
#define ALI_CACHE_FLUSH_EN 0x100
#ifndef PCI_VENDOR_ID_ATI
#define PCI_VENDOR_ID_ATI 0x1002
#endif
#ifndef PCI_DEVICE_ID_ATI_RS100
#define PCI_DEVICE_ID_ATI_RS100 0xcab0
#endif
#ifndef PCI_DEVICE_ID_ATI_RS200
#define PCI_DEVICE_ID_ATI_RS200 0xcab2
#endif
#ifndef PCI_DEVICE_ID_ATI_RS250
#define PCI_DEVICE_ID_ATI_RS250 0xcab3
#endif
#ifndef PCI_DEVICE_ID_ATI_RS300_100
#define PCI_DEVICE_ID_ATI_RS300_100 0x5830
#endif
#ifndef PCI_DEVICE_ID_ATI_RS300_133
#define PCI_DEVICE_ID_ATI_RS300_133 0x5831
#endif
#ifndef PCI_DEVICE_ID_ATI_RS300_166
#define PCI_DEVICE_ID_ATI_RS300_166 0x5832
#endif
#ifndef PCI_DEVICE_ID_ATI_RS300_200
#define PCI_DEVICE_ID_ATI_RS300_200 0x5833
#endif
/* ATI register */
#define ATI_APBASE 0x10
#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 */
/* Serverworks Registers */
#define SVWRKS_APSIZE 0x10
#define SVWRKS_APSIZE 0x10
#define SVWRKS_SIZE_MASK 0xfe000000
#define SVWRKS_SIZE_MASK 0xfe000000
...
...
drivers/char/agp/ati-agp.c
0 → 100644
View file @
32f40f52
/*
* 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"
static
int
agp_try_unsupported
__initdata
=
0
;
static
struct
aper_size_info_lvl2
ati_generic_sizes
[
7
]
=
{
{
2048
,
524288
,
0x0000000c
},
{
1024
,
262144
,
0x0000000a
},
{
512
,
131072
,
0x00000008
},
{
256
,
65536
,
0x00000006
},
{
128
,
32768
,
0x00000004
},
{
64
,
16384
,
0x00000002
},
{
32
,
8192
,
0x00000000
}
};
static
struct
gatt_mask
ati_generic_masks
[]
=
{
{
0x00000001
,
0
}
};
typedef
struct
_ati_page_map
{
unsigned
long
*
real
;
unsigned
long
*
remapped
;
}
ati_page_map
;
static
struct
_ati_generic_private
{
volatile
u8
*
registers
;
ati_page_map
**
gatt_pages
;
int
num_tables
;
}
ati_generic_private
;
static
int
ati_create_page_map
(
ati_page_map
*
page_map
)
{
int
i
,
err
=
0
;
page_map
->
real
=
(
unsigned
long
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
page_map
->
real
==
NULL
)
return
-
ENOMEM
;
SetPageReserved
(
virt_to_page
(
page_map
->
real
));
/*
* fredi - WARNING: added looking at the changes during
* 2.4.20. I dont know if it's needed though.
*/
#ifdef CONFIG_X86
err
=
map_page_into_agp
(
virt_to_page
(
page_map
->
real
));
#endif
/* CACHE_FLUSH(); */
global_cache_flush
();
page_map
->
remapped
=
ioremap_nocache
(
virt_to_phys
(
page_map
->
real
),
PAGE_SIZE
);
if
(
page_map
->
remapped
==
NULL
||
err
)
{
ClearPageReserved
(
virt_to_page
(
page_map
->
real
));
free_page
((
unsigned
long
)
page_map
->
real
);
page_map
->
real
=
NULL
;
return
-
ENOMEM
;
}
/*CACHE_FLUSH();*/
global_cache_flush
();
for
(
i
=
0
;
i
<
PAGE_SIZE
/
sizeof
(
unsigned
long
);
i
++
)
page_map
->
remapped
[
i
]
=
agp_bridge
->
scratch_page
;
return
0
;
}
static
void
ati_free_page_map
(
ati_page_map
*
page_map
)
{
/*
* fredi - WARNING: added looking at the changes during
* 2.4.20. I dont know if it's needed though.
*/
#ifdef CONFIG_X86
unmap_page_from_agp
(
virt_to_page
(
page_map
->
real
));
#endif
iounmap
(
page_map
->
remapped
);
ClearPageReserved
(
virt_to_page
(
page_map
->
real
));
free_page
((
unsigned
long
)
page_map
->
real
);
}
static
void
ati_free_gatt_pages
(
void
)
{
int
i
;
ati_page_map
**
tables
;
ati_page_map
*
entry
;
tables
=
ati_generic_private
.
gatt_pages
;
for
(
i
=
0
;
i
<
ati_generic_private
.
num_tables
;
i
++
)
{
entry
=
tables
[
i
];
if
(
entry
!=
NULL
)
{
if
(
entry
->
real
!=
NULL
)
ati_free_page_map
(
entry
);
kfree
(
entry
);
}
}
kfree
(
tables
);
}
static
int
ati_create_gatt_pages
(
int
nr_tables
)
{
ati_page_map
**
tables
;
ati_page_map
*
entry
;
int
retval
=
0
;
int
i
;
tables
=
kmalloc
((
nr_tables
+
1
)
*
sizeof
(
ati_page_map
*
),
GFP_KERNEL
);
if
(
tables
==
NULL
)
return
-
ENOMEM
;
memset
(
tables
,
0
,
sizeof
(
ati_page_map
*
)
*
(
nr_tables
+
1
));
for
(
i
=
0
;
i
<
nr_tables
;
i
++
)
{
entry
=
kmalloc
(
sizeof
(
ati_page_map
),
GFP_KERNEL
);
if
(
entry
==
NULL
)
{
retval
=
-
ENOMEM
;
break
;
}
memset
(
entry
,
0
,
sizeof
(
ati_page_map
));
tables
[
i
]
=
entry
;
retval
=
ati_create_page_map
(
entry
);
if
(
retval
!=
0
)
break
;
}
ati_generic_private
.
num_tables
=
nr_tables
;
ati_generic_private
.
gatt_pages
=
tables
;
if
(
retval
!=
0
)
ati_free_gatt_pages
();
return
retval
;
}
static
int
ati_fetch_size
(
void
)
{
int
i
;
u32
temp
;
struct
aper_size_info_lvl2
*
values
;
if
((
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS100
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS200
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS250
))
{
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS100_APSIZE
,
&
temp
);
}
else
{
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS300_APSIZE
,
&
temp
);
}
temp
=
(
temp
&
0x0000000e
);
values
=
A_SIZE_LVL2
(
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
ati_tlbflush
(
struct
agp_memory
*
mem
)
{
OUTREG32
(
ati_generic_private
.
registers
,
ATI_GART_CACHE_CNTRL
,
1
);
}
static
void
ati_cleanup
(
void
)
{
struct
aper_size_info_lvl2
*
previous_size
;
u32
temp
;
previous_size
=
A_SIZE_LVL2
(
agp_bridge
->
previous_size
);
/* Write back the previous size and disable gart translation */
if
((
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS100
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS200
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS250
))
{
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS100_APSIZE
,
&
temp
);
temp
=
((
temp
&
~
(
0x0000000f
))
|
previous_size
->
size_value
);
pci_write_config_dword
(
agp_bridge
->
dev
,
ATI_RS100_APSIZE
,
temp
);
}
else
{
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS300_APSIZE
,
&
temp
);
temp
=
((
temp
&
~
(
0x0000000f
))
|
previous_size
->
size_value
);
pci_write_config_dword
(
agp_bridge
->
dev
,
ATI_RS300_APSIZE
,
temp
);
}
iounmap
((
void
*
)
ati_generic_private
.
registers
);
}
static
int
ati_configure
(
void
)
{
u32
temp
;
/* Get the memory mapped registers */
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_GART_MMBASE_ADDR
,
&
temp
);
temp
=
(
temp
&
0xfffff000
);
ati_generic_private
.
registers
=
(
volatile
u8
*
)
ioremap
(
temp
,
4096
);
if
((
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS100
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS200
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS250
))
{
pci_write_config_dword
(
agp_bridge
->
dev
,
ATI_RS100_IG_AGPMODE
,
0x20000
);
}
else
{
pci_write_config_dword
(
agp_bridge
->
dev
,
ATI_RS300_IG_AGPMODE
,
0x20000
);
}
/* address to map too */
/*
pci_read_config_dword(agp_bridge.dev, ATI_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
printk(KERN_INFO "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
*/
OUTREG32
(
ati_generic_private
.
registers
,
ATI_GART_FEATURE_ID
,
0x60000
);
/* SIGNALED_SYSTEM_ERROR @ NB_STATUS */
pci_read_config_dword
(
agp_bridge
->
dev
,
4
,
&
temp
);
pci_write_config_dword
(
agp_bridge
->
dev
,
4
,
temp
|
(
1
<<
14
));
/* Write out the address of the gatt table */
OUTREG32
(
ati_generic_private
.
registers
,
ATI_GART_BASE
,
agp_bridge
->
gatt_bus_addr
);
/* Flush the tlb */
OUTREG32
(
ati_generic_private
.
registers
,
ATI_GART_CACHE_CNTRL
,
1
);
return
0
;
}
static
unsigned
long
ati_mask_memory
(
unsigned
long
addr
,
int
type
)
{
/* Memory type is ignored */
return
addr
|
agp_bridge
->
driver
->
masks
[
0
].
mask
;
}
/*
*Since we don't need contigious memory we just try
* to get the gatt table once
*/
#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
#undef GET_GATT(addr)
#define GET_GATT(addr) (ati_generic_private.gatt_pages[\
GET_PAGE_DIR_IDX(addr)]->remapped)
static
int
ati_insert_memory
(
struct
agp_memory
*
mem
,
off_t
pg_start
,
int
type
)
{
int
i
,
j
,
num_entries
;
unsigned
long
*
cur_gatt
;
unsigned
long
addr
;
num_entries
=
A_SIZE_LVL2
(
agp_bridge
->
current_size
)
->
num_entries
;
if
(
type
!=
0
||
mem
->
type
!=
0
)
return
-
EINVAL
;
if
((
pg_start
+
mem
->
page_count
)
>
num_entries
)
return
-
EINVAL
;
j
=
pg_start
;
while
(
j
<
(
pg_start
+
mem
->
page_count
))
{
addr
=
(
j
*
PAGE_SIZE
)
+
agp_bridge
->
gart_bus_addr
;
cur_gatt
=
GET_GATT
(
addr
);
if
(
!
PGE_EMPTY
(
agp_bridge
,
cur_gatt
[
GET_GATT_OFF
(
addr
)]))
return
-
EBUSY
;
j
++
;
}
if
(
mem
->
is_flushed
==
FALSE
)
{
/*CACHE_FLUSH(); */
global_cache_flush
();
mem
->
is_flushed
=
TRUE
;
}
for
(
i
=
0
,
j
=
pg_start
;
i
<
mem
->
page_count
;
i
++
,
j
++
)
{
addr
=
(
j
*
PAGE_SIZE
)
+
agp_bridge
->
gart_bus_addr
;
cur_gatt
=
GET_GATT
(
addr
);
cur_gatt
[
GET_GATT_OFF
(
addr
)]
=
agp_bridge
->
driver
->
mask_memory
(
mem
->
memory
[
i
],
mem
->
type
);
}
agp_bridge
->
driver
->
tlb_flush
(
mem
);
return
0
;
}
static
int
ati_remove_memory
(
struct
agp_memory
*
mem
,
off_t
pg_start
,
int
type
)
{
int
i
;
unsigned
long
*
cur_gatt
;
unsigned
long
addr
;
if
(
type
!=
0
||
mem
->
type
!=
0
)
{
return
-
EINVAL
;
}
for
(
i
=
pg_start
;
i
<
(
mem
->
page_count
+
pg_start
);
i
++
)
{
addr
=
(
i
*
PAGE_SIZE
)
+
agp_bridge
->
gart_bus_addr
;
cur_gatt
=
GET_GATT
(
addr
);
cur_gatt
[
GET_GATT_OFF
(
addr
)]
=
(
unsigned
long
)
agp_bridge
->
scratch_page
;
}
agp_bridge
->
driver
->
tlb_flush
(
mem
);
return
0
;
}
static
int
ati_create_gatt_table
(
void
)
{
struct
aper_size_info_lvl2
*
value
;
ati_page_map
page_dir
;
unsigned
long
addr
;
int
retval
;
u32
temp
;
int
i
;
struct
aper_size_info_lvl2
*
current_size
;
value
=
A_SIZE_LVL2
(
agp_bridge
->
current_size
);
retval
=
ati_create_page_map
(
&
page_dir
);
if
(
retval
!=
0
)
return
retval
;
retval
=
ati_create_gatt_pages
(
value
->
num_entries
/
1024
);
if
(
retval
!=
0
)
{
ati_free_page_map
(
&
page_dir
);
return
retval
;
}
agp_bridge
->
gatt_table_real
=
(
u32
*
)
page_dir
.
real
;
agp_bridge
->
gatt_table
=
(
u32
*
)
page_dir
.
remapped
;
agp_bridge
->
gatt_bus_addr
=
virt_to_bus
(
page_dir
.
real
);
/* Write out the size register */
current_size
=
A_SIZE_LVL2
(
agp_bridge
->
current_size
);
if
((
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS100
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS200
)
||
(
agp_bridge
->
dev
->
device
==
PCI_DEVICE_ID_ATI_RS250
))
{
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS100_APSIZE
,
&
temp
);
temp
=
(((
temp
&
~
(
0x0000000e
))
|
current_size
->
size_value
)
|
0x00000001
);
pci_write_config_dword
(
agp_bridge
->
dev
,
ATI_RS100_APSIZE
,
temp
);
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS100_APSIZE
,
&
temp
);
}
else
{
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS300_APSIZE
,
&
temp
);
temp
=
(((
temp
&
~
(
0x0000000e
))
|
current_size
->
size_value
)
|
0x00000001
);
pci_write_config_dword
(
agp_bridge
->
dev
,
ATI_RS300_APSIZE
,
temp
);
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_RS300_APSIZE
,
&
temp
);
}
/*
* Get the address for the gart region.
* This is a bus address even on the alpha, b/c its
* used to program the agp master not the cpu
*/
pci_read_config_dword
(
agp_bridge
->
dev
,
ATI_APBASE
,
&
temp
);
addr
=
(
temp
&
PCI_BASE_ADDRESS_MEM_MASK
);
agp_bridge
->
gart_bus_addr
=
addr
;
/* Calculate the agp offset */
for
(
i
=
0
;
i
<
value
->
num_entries
/
1024
;
i
++
,
addr
+=
0x00400000
)
{
page_dir
.
remapped
[
GET_PAGE_DIR_OFF
(
addr
)]
=
virt_to_bus
(
ati_generic_private
.
gatt_pages
[
i
]
->
real
);
page_dir
.
remapped
[
GET_PAGE_DIR_OFF
(
addr
)]
|=
0x00000001
;
}
return
0
;
}
static
int
ati_free_gatt_table
(
void
)
{
ati_page_map
page_dir
;
page_dir
.
real
=
(
unsigned
long
*
)
agp_bridge
->
gatt_table_real
;
page_dir
.
remapped
=
(
unsigned
long
*
)
agp_bridge
->
gatt_table
;
ati_free_gatt_pages
();
ati_free_page_map
(
&
page_dir
);
return
0
;
}
struct
agp_bridge_driver
ati_generic_bridge
=
{
.
owner
=
THIS_MODULE
,
.
aperture_sizes
=
ati_generic_sizes
,
.
size_type
=
LVL2_APER_SIZE
,
.
num_aperture_sizes
=
7
,
.
configure
=
ati_configure
,
.
fetch_size
=
ati_fetch_size
,
.
cleanup
=
ati_cleanup
,
.
tlb_flush
=
ati_tlbflush
,
.
mask_memory
=
ati_mask_memory
,
.
masks
=
ati_generic_masks
,
.
agp_enable
=
agp_generic_enable
,
.
cache_flush
=
global_cache_flush
,
.
create_gatt_table
=
ati_create_gatt_table
,
.
free_gatt_table
=
ati_free_gatt_table
,
.
insert_memory
=
ati_insert_memory
,
.
remove_memory
=
ati_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
,
};
struct
agp_device_ids
ali_agp_device_ids
[]
__initdata
=
{
{
.
device_id
=
PCI_DEVICE_ID_ATI_RS100
,
.
chipset_name
=
"IGP320/M"
,
},
{
.
device_id
=
PCI_DEVICE_ID_ATI_RS200
,
.
chipset_name
=
"IGP330/340/345/350/M"
,
},
{
.
device_id
=
PCI_DEVICE_ID_ATI_RS250
,
.
chipset_name
=
"IGP7000/M"
,
},
{
.
device_id
=
PCI_DEVICE_ID_ATI_RS300_100
,
.
chipset_name
=
"IGP9100/M"
,
},
{
.
device_id
=
PCI_DEVICE_ID_ATI_RS300_133
,
.
chipset_name
=
"IGP9100/M"
,
},
{
.
device_id
=
PCI_DEVICE_ID_ATI_RS300_166
,
.
chipset_name
=
"IGP9100/M"
,
},
{
.
device_id
=
PCI_DEVICE_ID_ATI_RS300_200
,
.
chipset_name
=
"IGP9100/M"
,
},
{
},
/* dummy final entry, always present */
};
static
int
__init
agp_ati_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
;
}
if
(
!
agp_try_unsupported
)
{
printk
(
KERN_ERR
PFX
"Unsupported Ati chipset (device id: %04x),"
" you might want to try agp_try_unsupported=1.
\n
"
,
pdev
->
device
);
return
-
ENODEV
;
}
printk
(
KERN_WARNING
PFX
"Trying generic Ati routines"
" for device id: %04x
\n
"
,
pdev
->
device
);
found:
bridge
=
agp_alloc_bridge
();
if
(
!
bridge
)
return
-
ENOMEM
;
bridge
->
dev
=
pdev
;
bridge
->
capndx
=
cap_ptr
;
bridge
->
driver
=
&
ati_generic_bridge
;
printk
(
KERN_INFO
PFX
"Detected Ati %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_ati_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_ati_pci_table
[]
__initdata
=
{
{
.
class
=
(
PCI_CLASS_BRIDGE_HOST
<<
8
),
.
class_mask
=
~
0
,
.
vendor
=
PCI_VENDOR_ID_ATI
,
.
device
=
PCI_ANY_ID
,
.
subvendor
=
PCI_ANY_ID
,
.
subdevice
=
PCI_ANY_ID
,
},
{
}
};
MODULE_DEVICE_TABLE
(
pci
,
agp_ati_pci_table
);
static
struct
pci_driver
agp_ati_pci_driver
=
{
.
name
=
"agpgart-ati"
,
.
id_table
=
agp_ati_pci_table
,
.
probe
=
agp_ati_probe
,
.
remove
=
agp_ati_remove
,
};
static
int
__init
agp_ati_init
(
void
)
{
return
pci_module_init
(
&
agp_ati_pci_driver
);
}
static
void
__exit
agp_ati_cleanup
(
void
)
{
pci_unregister_driver
(
&
agp_ati_pci_driver
);
}
module_init
(
agp_ati_init
);
module_exit
(
agp_ati_cleanup
);
MODULE_PARM
(
agp_try_unsupported
,
"1i"
);
MODULE_AUTHOR
(
"Dave Jones <davej@codemonkey.org.uk>"
);
MODULE_LICENSE
(
"GPL and additional rights"
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment