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
Kirill Smelkov
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
Hide 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