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
5e27cb68
Commit
5e27cb68
authored
May 14, 2003
by
Dave Jones
Browse files
Options
Browse Files
Download
Plain Diff
Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/bk-linus
into tetrachloride.(none):/mnt/raid/src/kernel/2.5/agpgart
parents
162132e0
0b1640a1
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
259 additions
and
216 deletions
+259
-216
drivers/char/agp/Makefile
drivers/char/agp/Makefile
+1
-1
drivers/char/agp/agp.h
drivers/char/agp/agp.h
+16
-3
drivers/char/agp/amd-k8-agp.c
drivers/char/agp/amd-k8-agp.c
+30
-4
drivers/char/agp/generic.c
drivers/char/agp/generic.c
+132
-59
drivers/char/agp/isoch.c
drivers/char/agp/isoch.c
+78
-147
drivers/char/drm/Kconfig
drivers/char/drm/Kconfig
+2
-2
No files found.
drivers/char/agp/Makefile
View file @
5e27cb68
agpgart-y
:=
backend.o frontend.o generic.o
generic-3.0
.o
agpgart-y
:=
backend.o frontend.o generic.o
isoch
.o
obj-$(CONFIG_AGP)
+=
agpgart.o
obj-$(CONFIG_AGP_ALI)
+=
ali-agp.o
...
...
drivers/char/agp/agp.h
View file @
5e27cb68
...
...
@@ -139,6 +139,8 @@ struct agp_bridge_data {
int
max_memory_agp
;
/* in number of pages */
int
aperture_size_idx
;
int
capndx
;
char
major_version
;
char
minor_version
;
};
#define OUTREG64(mmap, addr, val) __raw_writeq((val), (mmap)+(addr))
...
...
@@ -388,27 +390,38 @@ void agp_free_key(int key);
int
agp_num_entries
(
void
);
u32
agp_collect_device_status
(
u32
mode
,
u32
command
);
void
agp_device_command
(
u32
command
,
int
agp_v3
);
int
agp_3_0_node_enable
(
struct
agp_bridge_data
*
bridge
,
u32
mode
,
u32
minor
);
int
agp_3_0_enable
(
struct
agp_bridge_data
*
bridge
,
u32
mode
);
int
agp_3_5_enable
(
struct
agp_bridge_data
*
bridge
,
u32
mode
);
void
global_cache_flush
(
void
);
void
get_agp_version
(
struct
agp_bridge_data
*
bridge
);
/* Standard agp registers */
#define AGPSTAT 0x4
#define AGPCMD 0x8
#define AGPNISTAT 0xc
#define AGPNEPG 0x16
#define AGPNICMD 0x20
#define AGP_MAJOR_VERSION_SHIFT (20)
#define AGP_MINOR_VERSION_SHIFT (16)
#define AGPSTAT_RQ_DEPTH (0xff000000)
#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_AGP_ENABLE (1<<8)
#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 AGPSTAT_FW (1<<4)
#define AGPSTAT3_RSVD (1<<2)
#define AGPSTAT3_8X (1<<1)
#define AGPSTAT3_4X (1)
#endif
/* _AGP_BACKEND_PRIV_H */
drivers/char/agp/amd-k8-agp.c
View file @
5e27cb68
...
...
@@ -253,8 +253,10 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
{
struct
agp_bridge_data
*
bridge
;
struct
pci_dev
*
loop_dev
;
u8
rev_id
;
u8
cap_ptr
;
int
i
=
0
;
char
*
revstring
=
" "
;
cap_ptr
=
pci_find_capability
(
pdev
,
PCI_CAP_ID_AGP
);
if
(
!
cap_ptr
)
...
...
@@ -266,14 +268,38 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
if
(
!
bridge
)
return
-
ENOMEM
;
/* Assume here we have an 8151. (Later this assumption will be fixed). */
pci_read_config_byte
(
pdev
,
PCI_REVISION_ID
,
&
rev_id
);
switch
(
rev_id
)
{
case
0x01
:
revstring
=
"A0"
;
break
;
case
0x02
:
revstring
=
"A1"
;
break
;
case
0x11
:
revstring
=
"B0"
;
break
;
case
0x12
:
revstring
=
"B1"
;
break
;
case
0x13
:
revstring
=
"B2"
;
break
;
default:
revstring
=
"??"
;
break
;
}
printk
(
"Detected AMD 8151 AGP Bridge rev %s"
,
revstring
);
/*
* Work around errata.
* Chips before B2 stepping incorrectly reporting v3.5
*/
if
(
rev_id
<
0x13
)
{
bridge
->
major_version
=
3
;
bridge
->
minor_version
=
0
;
}
bridge
->
driver
=
&
amd_8151_driver
;
bridge
->
dev
=
pdev
;
bridge
->
capndx
=
cap_ptr
;
/* Fill in the mode register */
pci_read_config_dword
(
pdev
,
bridge
->
capndx
+
PCI_AGP_STATUS
,
&
bridge
->
mode
);
pci_read_config_dword
(
pdev
,
bridge
->
capndx
+
PCI_AGP_STATUS
,
&
bridge
->
mode
);
/* cache pci_devs of northbridges. */
pci_for_each_dev
(
loop_dev
)
{
...
...
@@ -290,7 +316,7 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
pci_set_drvdata
(
pdev
,
bridge
);
return
agp_add_bridge
(
bridge
);
out_free:
out_free:
agp_put_bridge
(
bridge
);
return
-
ENOMEM
;
}
...
...
drivers/char/agp/generic.c
View file @
5e27cb68
...
...
@@ -270,14 +270,16 @@ EXPORT_SYMBOL_GPL(agp_num_entries);
int
agp_copy_info
(
agp_kern_info
*
info
)
{
memset
(
info
,
0
,
sizeof
(
agp_kern_info
));
if
(
agp_bridge
->
type
==
NOT_SUPPORTED
)
{
info
->
chipset
=
agp_bridge
->
type
;
if
(
!
agp_bridge
||
agp_bridge
->
type
==
NOT_SUPPORTED
||
!
agp_bridge
->
version
)
{
info
->
chipset
=
NOT_SUPPORTED
;
return
-
EIO
;
}
info
->
version
.
major
=
agp_bridge
->
version
->
major
;
info
->
version
.
minor
=
agp_bridge
->
version
->
minor
;
info
->
device
=
agp_bridge
->
dev
;
info
->
chipset
=
agp_bridge
->
type
;
info
->
device
=
agp_bridge
->
dev
;
info
->
mode
=
agp_bridge
->
mode
;
info
->
aper_base
=
agp_bridge
->
gart_bus_addr
;
info
->
aper_size
=
agp_return_size
();
...
...
@@ -366,60 +368,106 @@ EXPORT_SYMBOL(agp_unbind_memory);
/* Generic Agp routines - Start */
static
void
agp_v2_parse_one
(
u32
*
mode
,
u32
*
cmd
,
u32
*
tmp
)
{
/* disable SBA if it's not supported */
if
(
!
((
*
cmd
&
AGPSTAT_SBA
)
&&
(
*
tmp
&
AGPSTAT_SBA
)
&&
(
*
mode
&
AGPSTAT_SBA
)))
*
cmd
&=
~
AGPSTAT_SBA
;
/* disable FW if it's not supported */
if
(
!
((
*
cmd
&
AGPSTAT_FW
)
&&
(
*
tmp
&
AGPSTAT_FW
)
&&
(
*
mode
&
AGPSTAT_FW
)))
*
cmd
&=
~
AGPSTAT_FW
;
/* Set speed */
if
(
!
((
*
cmd
&
AGPSTAT2_4X
)
&&
(
*
tmp
&
AGPSTAT2_4X
)
&&
(
*
mode
&
AGPSTAT2_4X
)))
*
cmd
&=
~
AGPSTAT2_4X
;
if
(
!
((
*
cmd
&
AGPSTAT2_2X
)
&&
(
*
tmp
&
AGPSTAT2_2X
)
&&
(
*
mode
&
AGPSTAT2_2X
)))
*
cmd
&=
~
AGPSTAT2_2X
;
if
(
!
((
*
cmd
&
AGPSTAT2_1X
)
&&
(
*
tmp
&
AGPSTAT2_1X
)
&&
(
*
mode
&
AGPSTAT2_1X
)))
*
cmd
&=
~
AGPSTAT2_1X
;
/* Now we know what mode it should be, clear out the unwanted bits. */
if
(
*
cmd
&
AGPSTAT2_4X
)
*
cmd
&=
~
(
AGPSTAT2_1X
|
AGPSTAT2_2X
);
/* 4X */
if
(
*
cmd
&
AGPSTAT2_2X
)
*
cmd
&=
~
(
AGPSTAT2_1X
|
AGPSTAT2_4X
);
/* 2X */
if
(
*
cmd
&
AGPSTAT2_1X
)
*
cmd
&=
~
(
AGPSTAT2_2X
|
AGPSTAT2_4X
);
/* 1Xf */
}
u32
agp_collect_device_status
(
u32
mode
,
u32
command
)
static
void
agp_v3_parse_one
(
u32
*
mode
,
u32
*
cmd
,
u32
*
tmp
)
{
/* ARQSZ - Set the value to the maximum one.
* Don't allow the mode register to override values. */
*
cmd
=
((
*
cmd
&
~
AGPSTAT_ARQSZ
)
|
max_t
(
u32
,(
*
cmd
&
AGPSTAT_ARQSZ
),(
*
tmp
&
AGPSTAT_ARQSZ
)));
/* Calibration cycle.
* Don't allow the mode register to override values. */
*
cmd
=
((
*
cmd
&
~
AGPSTAT_CAL_MASK
)
|
min_t
(
u32
,(
*
cmd
&
AGPSTAT_CAL_MASK
),(
*
tmp
&
AGPSTAT_CAL_MASK
)));
/* SBA *must* be supported for AGP v3 */
*
cmd
|=
AGPSTAT_SBA
;
/* disable FW if it's not supported */
if
(
!
((
*
cmd
&
AGPSTAT_FW
)
&&
(
*
tmp
&
AGPSTAT_FW
)
&&
(
*
mode
&
AGPSTAT_FW
)))
*
cmd
&=
~
AGPSTAT_FW
;
/* Set speed. */
if
(
!
((
*
cmd
&
AGPSTAT3_8X
)
&&
(
*
tmp
&
AGPSTAT3_8X
)
&&
(
*
mode
&
AGPSTAT3_8X
)))
*
cmd
&=
~
AGPSTAT3_8X
;
if
(
!
((
*
cmd
&
AGPSTAT3_4X
)
&&
(
*
tmp
&
AGPSTAT3_4X
)
&&
(
*
mode
&
AGPSTAT3_4X
)))
*
cmd
&=
~
AGPSTAT3_4X
;
/* Clear out unwanted bits. */
if
(
*
cmd
&
AGPSTAT3_8X
)
*
cmd
*=
~
(
AGPSTAT3_4X
|
AGPSTAT3_RSVD
);
if
(
*
cmd
&
AGPSTAT3_4X
)
*
cmd
*=
~
(
AGPSTAT3_8X
|
AGPSTAT3_RSVD
);
}
//FIXME: This doesn't smell right.
//We need a function we pass an agp_device to.
u32
agp_collect_device_status
(
u32
mode
,
u32
cmd
)
{
struct
pci_dev
*
device
;
u8
agp
;
u32
scratch
;
u8
cap_ptr
;
u32
tmp
;
u32
agp3
;
pci_for_each_dev
(
device
)
{
agp
=
pci_find_capability
(
device
,
PCI_CAP_ID_AGP
);
if
(
!
agp
)
cap_ptr
=
pci_find_capability
(
device
,
PCI_CAP_ID_AGP
);
if
(
!
cap_ptr
)
continue
;
/*
* Ok, here we have a AGP device. Disable impossible
* settings, and adjust the readqueue to the minimum.
*/
pci_read_config_dword
(
device
,
agp
+
PCI_AGP_STATUS
,
&
scratch
);
pci_read_config_dword
(
device
,
cap_ptr
+
PCI_AGP_STATUS
,
&
tmp
);
/* adjust RQ depth */
c
ommand
=
((
comman
d
&
~
AGPSTAT_RQ_DEPTH
)
|
c
md
=
((
cm
d
&
~
AGPSTAT_RQ_DEPTH
)
|
min_t
(
u32
,
(
mode
&
AGPSTAT_RQ_DEPTH
),
min_t
(
u32
,
(
command
&
AGPSTAT_RQ_DEPTH
),
(
scratch
&
AGPSTAT_RQ_DEPTH
))));
/* disable SBA if it's not supported */
if
(
!
((
command
&
AGPSTAT_SBA
)
&&
(
scratch
&
AGPSTAT_SBA
)
&&
(
mode
&
AGPSTAT_SBA
)))
command
&=
~
AGPSTAT_SBA
;
/* disable FW if it's not supported */
if
(
!
((
command
&
AGPSTAT_FW
)
&&
(
scratch
&
AGPSTAT_FW
)
&&
(
mode
&
AGPSTAT_FW
)))
command
&=
~
AGPSTAT_FW
;
/* Set speed */
if
(
!
((
command
&
AGPSTAT2_4X
)
&&
(
scratch
&
AGPSTAT2_4X
)
&&
(
mode
&
AGPSTAT2_4X
)))
command
&=
~
AGPSTAT2_4X
;
min_t
(
u32
,
(
cmd
&
AGPSTAT_RQ_DEPTH
),
(
tmp
&
AGPSTAT_RQ_DEPTH
))));
pci_read_config_dword
(
device
,
cap_ptr
+
AGPSTAT
,
&
agp3
);
if
(
!
((
command
&
AGPSTAT2_2X
)
&&
(
scratch
&
AGPSTAT2_2X
)
&&
(
mode
&
AGPSTAT2_2X
)))
command
&=
~
AGPSTAT2_2X
;
if
(
!
((
command
&
AGPSTAT2_1X
)
&&
(
scratch
&
AGPSTAT2_1X
)
&&
(
mode
&
AGPSTAT2_1X
)))
command
&=
~
AGPSTAT2_1X
;
/* Check to see if we are operating in 3.0 mode */
if
(
agp3
&
AGPSTAT_MODE_3_0
)
{
agp_v3_parse_one
(
&
mode
,
&
cmd
,
&
tmp
);
}
else
{
agp_v2_parse_one
(
&
mode
,
&
cmd
,
&
tmp
);
}
}
/* Now we know what mode it should be, clear out the unwanted bits. */
if
(
command
&
AGPSTAT2_4X
)
command
&=
~
(
AGPSTAT2_1X
|
AGPSTAT2_2X
);
/* 4X */
if
(
command
&
AGPSTAT2_2X
)
command
&=
~
(
AGPSTAT2_1X
|
AGPSTAT2_4X
);
/* 2X */
if
(
command
&
AGPSTAT2_1X
)
command
&=
~
(
AGPSTAT2_2X
|
AGPSTAT2_4X
);
/* 1Xf */
return
command
;
return
cmd
;
}
EXPORT_SYMBOL
(
agp_collect_device_status
);
...
...
@@ -446,29 +494,33 @@ void agp_device_command(u32 command, int agp_v3)
EXPORT_SYMBOL
(
agp_device_command
);
void
agp_generic_enable
(
u32
mod
e
)
void
get_agp_version
(
struct
agp_bridge_data
*
bridg
e
)
{
u32
command
,
ncapid
,
major
,
minor
;
u32
ncapid
;
/* Exit early if already set by errata workarounds. */
if
(
agp_bridge
->
major_version
!=
0
)
return
;
pci_read_config_dword
(
agp_bridge
->
dev
,
agp_bridge
->
capndx
,
&
ncapid
);
major
=
(
ncapid
>>
20
)
&
0xf
;
minor
=
(
ncapid
>>
16
)
&
0xf
;
printk
(
KERN_INFO
PFX
"Found an AGP %d.%d compliant device.
\n
"
,
major
,
minor
);
agp_bridge
->
major_version
=
(
ncapid
>>
AGP_MAJOR_VERSION_SHIFT
)
&
0xf
;
agp_bridge
->
minor_version
=
(
ncapid
>>
AGP_MINOR_VERSION_SHIFT
)
&
0xf
;
}
EXPORT_SYMBOL
(
get_agp_version
);
if
(
major
>=
3
)
{
u32
agp_3_0
;
pci_read_config_dword
(
agp_bridge
->
dev
,
agp_bridge
->
capndx
+
0x4
,
&
agp_3_0
);
/* Check to see if we are operating in 3.0 mode */
if
((
agp_3_0
>>
3
)
&
0x1
)
{
agp_3_0_node_enable
(
agp_bridge
,
mode
,
minor
);
return
;
}
else
{
printk
(
KERN_INFO
PFX
"not in AGP 3.0 mode, falling back to 2.x
\n
"
);
}
}
void
agp_generic_enable
(
u32
mode
)
{
u32
command
;
u32
agp3
;
get_agp_version
(
agp_bridge
);
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
);
/* AGP v<3 */
pci_read_config_dword
(
agp_bridge
->
dev
,
agp_bridge
->
capndx
+
PCI_AGP_STATUS
,
&
command
);
...
...
@@ -477,7 +529,27 @@ void agp_generic_enable(u32 mode)
pci_write_config_dword
(
agp_bridge
->
dev
,
agp_bridge
->
capndx
+
PCI_AGP_COMMAND
,
command
);
agp_device_command
(
command
,
0
);
/* Do AGP version specific frobbing. */
if
(
agp_bridge
->
major_version
>=
3
)
{
pci_read_config_dword
(
agp_bridge
->
dev
,
agp_bridge
->
capndx
+
AGPSTAT
,
&
agp3
);
/* Check to see if we are operating in 3.0 mode */
if
(
agp3
&
AGPSTAT_MODE_3_0
)
{
/* If we have 3.5, we can do the isoch stuff. */
if
(
agp_bridge
->
minor_version
>=
5
)
agp_3_5_enable
(
agp_bridge
,
mode
);
agp_device_command
(
command
,
TRUE
);
return
;
}
else
{
printk
(
KERN_INFO
PFX
"Device is in legacy mode,"
" falling back to 2.x
\n
"
);
}
}
/* AGP v<3 */
agp_device_command
(
command
,
FALSE
);
}
EXPORT_SYMBOL
(
agp_generic_enable
);
...
...
@@ -831,6 +903,7 @@ void agp_enable(u32 mode)
}
EXPORT_SYMBOL
(
agp_enable
);
#ifdef CONFIG_SMP
static
void
ipi_handler
(
void
*
null
)
{
...
...
drivers/char/agp/
generic-3.0
.c
→
drivers/char/agp/
isoch
.c
View file @
5e27cb68
/*
*
Generic routines for AGP 3.0
compliant bridges.
*
Setup routines for AGP 3.5
compliant bridges.
*/
#include <linux/list.h>
...
...
@@ -9,47 +9,47 @@
#include "agp.h"
/* Generic AGP 3.
0
enabling routines */
/* Generic AGP 3.
5
enabling routines */
struct
agp_3_
0
_dev
{
struct
agp_3_
5
_dev
{
struct
list_head
list
;
u8
capndx
;
u32
maxbw
;
struct
pci_dev
*
dev
;
};
static
void
agp_3_
0
_dev_list_insert
(
struct
list_head
*
head
,
struct
list_head
*
new
)
static
void
agp_3_
5
_dev_list_insert
(
struct
list_head
*
head
,
struct
list_head
*
new
)
{
struct
agp_3_
0_dev
*
cur
,
*
n
=
list_entry
(
new
,
struct
agp_3_0
_dev
,
list
);
struct
agp_3_
5_dev
*
cur
,
*
n
=
list_entry
(
new
,
struct
agp_3_5
_dev
,
list
);
struct
list_head
*
pos
;
list_for_each
(
pos
,
head
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
0
_dev
,
list
);
cur
=
list_entry
(
pos
,
struct
agp_3_
5
_dev
,
list
);
if
(
cur
->
maxbw
>
n
->
maxbw
)
break
;
}
list_add_tail
(
new
,
pos
);
}
static
void
agp_3_
0_dev_list_sort
(
struct
agp_3_0
_dev
*
list
,
unsigned
int
ndevs
)
static
void
agp_3_
5_dev_list_sort
(
struct
agp_3_5
_dev
*
list
,
unsigned
int
ndevs
)
{
struct
agp_3_
0
_dev
*
cur
;
struct
agp_3_
5
_dev
*
cur
;
struct
pci_dev
*
dev
;
struct
list_head
*
pos
,
*
tmp
,
*
head
=
&
list
->
list
,
*
start
=
head
->
next
;
u32
nistat
;
INIT_LIST_HEAD
(
head
);
for
(
pos
=
start
;
pos
!=
head
;
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
0
_dev
,
list
);
for
(
pos
=
start
;
pos
!=
head
;
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
5
_dev
,
list
);
dev
=
cur
->
dev
;
pci_read_config_dword
(
dev
,
cur
->
capndx
+
0x0c
,
&
nistat
);
pci_read_config_dword
(
dev
,
cur
->
capndx
+
AGPNISTAT
,
&
nistat
);
cur
->
maxbw
=
(
nistat
>>
16
)
&
0xff
;
tmp
=
pos
;
pos
=
pos
->
next
;
agp_3_
0
_dev_list_insert
(
head
,
tmp
);
agp_3_
5
_dev_list_insert
(
head
,
tmp
);
}
}
...
...
@@ -59,8 +59,8 @@ static void agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs)
* lying behind it...)
*/
static
int
agp_3_
0
_isochronous_node_enable
(
struct
agp_bridge_data
*
bridge
,
struct
agp_3_
0
_dev
*
dev_list
,
unsigned
int
ndevs
)
static
int
agp_3_
5
_isochronous_node_enable
(
struct
agp_bridge_data
*
bridge
,
struct
agp_3_
5
_dev
*
dev_list
,
unsigned
int
ndevs
)
{
/*
* Convenience structure to make the calculations clearer
...
...
@@ -72,12 +72,12 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
u32
y
;
u32
l
;
u32
rq
;
struct
agp_3_
0
_dev
*
dev
;
struct
agp_3_
5
_dev
*
dev
;
};
struct
pci_dev
*
td
=
bridge
->
dev
,
*
dev
;
struct
list_head
*
head
=
&
dev_list
->
list
,
*
pos
;
struct
agp_3_
0
_dev
*
cur
;
struct
agp_3_
5
_dev
*
cur
;
struct
isoch_data
*
master
,
target
;
unsigned
int
cdev
=
0
;
u32
mnistat
,
tnistat
,
tstatus
,
mcmd
;
...
...
@@ -91,7 +91,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
* We'll work with an array of isoch_data's (one for each
* device in dev_list) throughout this function.
*/
if
((
master
=
kmalloc
(
ndevs
*
sizeof
(
*
master
),
GFP_KERNEL
))
==
NULL
)
{
if
((
master
=
kmalloc
(
ndevs
*
sizeof
(
*
master
),
GFP_KERNEL
))
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
get_out
;
}
...
...
@@ -112,9 +112,9 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
* transfers are enabled and consequently whether maxbw will mean
* anything.
*/
agp_3_
0
_dev_list_sort
(
dev_list
,
ndevs
);
agp_3_
5
_dev_list_sort
(
dev_list
,
ndevs
);
pci_read_config_dword
(
td
,
bridge
->
capndx
+
0x0c
,
&
tnistat
);
pci_read_config_dword
(
td
,
bridge
->
capndx
+
AGPNISTAT
,
&
tnistat
);
pci_read_config_dword
(
td
,
bridge
->
capndx
+
AGPSTAT
,
&
tstatus
);
/* Extract power-on defaults from the target */
...
...
@@ -132,12 +132,12 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
* by these devices and the largest requested payload size.
*/
list_for_each
(
pos
,
head
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
0
_dev
,
list
);
cur
=
list_entry
(
pos
,
struct
agp_3_
5
_dev
,
list
);
dev
=
cur
->
dev
;
mcapndx
=
cur
->
capndx
;
pci_read_config_dword
(
dev
,
cur
->
capndx
+
0x0c
,
&
mnistat
);
pci_read_config_dword
(
dev
,
cur
->
capndx
+
AGPNISTAT
,
&
mnistat
);
master
[
cdev
].
maxbw
=
(
mnistat
>>
16
)
&
0xff
;
master
[
cdev
].
n
=
(
mnistat
>>
8
)
&
0xff
;
...
...
@@ -151,7 +151,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
}
/* Check if this configuration has any chance of working */
if
(
tot_bw
>
target
.
maxbw
)
{
if
(
tot_bw
>
target
.
maxbw
)
{
printk
(
KERN_ERR
PFX
"isochronous bandwidth required "
"by AGP 3.0 devices exceeds that which is supported by "
"the AGP 3.0 bridge!
\n
"
);
...
...
@@ -167,17 +167,17 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
* in the target's NISTAT register, so we need to do this now
* to get an accurate value for ISOCH_N later.
*/
pci_read_config_word
(
td
,
bridge
->
capndx
+
0x20
,
&
tnicmd
);
pci_read_config_word
(
td
,
bridge
->
capndx
+
AGPNICMD
,
&
tnicmd
);
tnicmd
&=
~
(
0x3
<<
6
);
tnicmd
|=
target
.
y
<<
6
;
pci_write_config_word
(
td
,
bridge
->
capndx
+
0x20
,
tnicmd
);
pci_write_config_word
(
td
,
bridge
->
capndx
+
AGPNICMD
,
tnicmd
);
/* Reread the target's ISOCH_N */
pci_read_config_dword
(
td
,
bridge
->
capndx
+
0x0c
,
&
tnistat
);
pci_read_config_dword
(
td
,
bridge
->
capndx
+
AGPNISTAT
,
&
tnistat
);
target
.
n
=
(
tnistat
>>
8
)
&
0xff
;
/* Calculate the minimum ISOCH_N needed by each master */
for
(
cdev
=
0
;
cdev
<
ndevs
;
cdev
++
)
{
for
(
cdev
=
0
;
cdev
<
ndevs
;
cdev
++
)
{
master
[
cdev
].
y
=
target
.
y
;
master
[
cdev
].
n
=
master
[
cdev
].
maxbw
/
(
master
[
cdev
].
y
+
1
);
...
...
@@ -186,7 +186,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
/* Exit if the minimal ISOCH_N allocation among the masters is more
* than the target can handle. */
if
(
tot_n
>
target
.
n
)
{
if
(
tot_n
>
target
.
n
)
{
printk
(
KERN_ERR
PFX
"number of isochronous "
"transactions per period required by AGP 3.0 devices "
"exceeds that which is supported by the AGP 3.0 "
...
...
@@ -204,7 +204,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
* Along the way, distribute the extra ISOCH_N capability calculated
* above.
*/
for
(
cdev
=
0
;
cdev
<
ndevs
;
cdev
++
)
{
for
(
cdev
=
0
;
cdev
<
ndevs
;
cdev
++
)
{
/*
* This is a little subtle. If ISOCH_Y > 64B, then ISOCH_Y
* byte isochronous writes will be broken into 64B pieces.
...
...
@@ -213,13 +213,12 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
* many writes on the AGP bus).
*/
master
[
cdev
].
rq
=
master
[
cdev
].
n
;
if
(
master
[
cdev
].
y
>
0x1
)
{
if
(
master
[
cdev
].
y
>
0x1
)
master
[
cdev
].
rq
*=
(
1
<<
(
master
[
cdev
].
y
-
1
));
}
tot_rq
+=
master
[
cdev
].
rq
;
if
(
cdev
==
ndevs
-
1
)
if
(
cdev
==
ndevs
-
1
)
master
[
cdev
].
n
+=
rem
;
}
...
...
@@ -230,7 +229,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
/* Exit if the minimal RQ needs of the masters exceeds what the target
* can provide. */
if
(
tot_rq
>
rq_isoch
)
{
if
(
tot_rq
>
rq_isoch
)
{
printk
(
KERN_ERR
PFX
"number of request queue slots "
"required by the isochronous bandwidth requested by "
"AGP 3.0 devices exceeds the number provided by the "
...
...
@@ -247,7 +246,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
/* Distribute the extra RQ slots calculated above and write our
* isochronous settings out to the actual devices. */
for
(
cdev
=
0
;
cdev
<
ndevs
;
cdev
++
)
{
for
(
cdev
=
0
;
cdev
<
ndevs
;
cdev
++
)
{
cur
=
master
[
cdev
].
dev
;
dev
=
cur
->
dev
;
...
...
@@ -256,7 +255,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
master
[
cdev
].
rq
+=
(
cdev
==
ndevs
-
1
)
?
(
rem_async
+
rem_isoch
)
:
step
;
pci_read_config_word
(
dev
,
cur
->
capndx
+
0x20
,
&
mnicmd
);
pci_read_config_word
(
dev
,
cur
->
capndx
+
AGPNICMD
,
&
mnicmd
);
pci_read_config_dword
(
dev
,
cur
->
capndx
+
AGPCMD
,
&
mcmd
);
mnicmd
&=
~
(
0xff
<<
8
);
...
...
@@ -268,7 +267,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
mcmd
|=
master
[
cdev
].
rq
<<
24
;
pci_write_config_dword
(
dev
,
cur
->
capndx
+
AGPCMD
,
mcmd
);
pci_write_config_word
(
dev
,
cur
->
capndx
+
0x20
,
mnicmd
);
pci_write_config_word
(
dev
,
cur
->
capndx
+
AGPNICMD
,
mnicmd
);
}
free_and_exit:
...
...
@@ -285,24 +284,24 @@ static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
* target by ndevs. Distribute this many slots to each AGP 3.0 device,
* giving any left over slots to the last device in dev_list.
*/
static
void
agp_3_
0
_nonisochronous_node_enable
(
struct
agp_bridge_data
*
bridge
,
struct
agp_3_
0
_dev
*
dev_list
,
unsigned
int
ndevs
)
static
void
agp_3_
5
_nonisochronous_node_enable
(
struct
agp_bridge_data
*
bridge
,
struct
agp_3_
5
_dev
*
dev_list
,
unsigned
int
ndevs
)
{
struct
agp_3_
0
_dev
*
cur
;
struct
agp_3_
5
_dev
*
cur
;
struct
list_head
*
head
=
&
dev_list
->
list
,
*
pos
;
u32
tstatus
,
mcmd
;
u32
trq
,
mrq
,
rem
;
unsigned
int
cdev
=
0
;
pci_read_config_dword
(
bridge
->
dev
,
bridge
->
capndx
+
0x04
,
&
tstatus
);
pci_read_config_dword
(
bridge
->
dev
,
bridge
->
capndx
+
AGPSTAT
,
&
tstatus
);
trq
=
(
tstatus
>>
24
)
&
0xff
;
mrq
=
trq
/
ndevs
;
rem
=
mrq
+
(
trq
%
ndevs
);
for
(
pos
=
head
->
next
;
cdev
<
ndevs
;
cdev
++
,
pos
=
pos
->
next
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
0
_dev
,
list
);
for
(
pos
=
head
->
next
;
cdev
<
ndevs
;
cdev
++
,
pos
=
pos
->
next
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
5
_dev
,
list
);
pci_read_config_dword
(
cur
->
dev
,
cur
->
capndx
+
AGPCMD
,
&
mcmd
);
mcmd
&=
~
(
0xff
<<
24
);
...
...
@@ -315,24 +314,32 @@ static void agp_3_0_nonisochronous_node_enable(struct agp_bridge_data *bridge,
* Fully configure and enable an AGP 3.0 host bridge and all the devices
* lying behind it.
*/
int
agp_3_
0_node_enable
(
struct
agp_bridge_data
*
bridge
,
u32
mode
,
u32
minor
)
int
agp_3_
5_enable
(
struct
agp_bridge_data
*
bridge
,
u32
mode
)
{
struct
pci_dev
*
td
=
bridge
->
dev
,
*
dev
;
u8
mcapndx
;
u32
isoch
,
arqsz
,
cal_cycle
,
tmp
,
rate
;
u32
tstatus
,
tcmd
,
mcmd
,
mstatus
,
ncapid
;
u32
mmajor
,
mminor
;
u32
isoch
,
arqsz
;
u32
tstatus
,
mstatus
,
ncapid
;
u32
mmajor
;
u16
mpstat
;
struct
agp_3_
0
_dev
*
dev_list
,
*
cur
;
struct
agp_3_
5
_dev
*
dev_list
,
*
cur
;
struct
list_head
*
head
,
*
pos
;
unsigned
int
ndevs
=
0
;
int
ret
=
0
;
/* Extract some power-on defaults from the target */
pci_read_config_dword
(
td
,
bridge
->
capndx
+
AGPSTAT
,
&
tstatus
);
isoch
=
(
tstatus
>>
17
)
&
0x1
;
if
(
isoch
==
0
)
/* isoch xfers not available, bail out. */
return
-
ENODEV
;
arqsz
=
(
tstatus
>>
13
)
&
0x7
;
/*
* Allocate a head for our AGP 3.
0 device list (multiple AGP 3.0
* devices are allowed behind a single bridge).
* Allocate a head for our AGP 3.
5 device list
*
(multiple AGP v3
devices are allowed behind a single bridge).
*/
if
((
dev_list
=
kmalloc
(
sizeof
(
*
dev_list
),
GFP_KERNEL
))
==
NULL
)
{
if
((
dev_list
=
kmalloc
(
sizeof
(
*
dev_list
),
GFP_KERNEL
))
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
get_out
;
}
...
...
@@ -342,6 +349,9 @@ int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor)
/* Find all AGP devices, and add them to dev_list. */
pci_for_each_dev
(
dev
)
{
mcapndx
=
pci_find_capability
(
dev
,
PCI_CAP_ID_AGP
);
if
(
mcapndx
==
0
)
continue
;
switch
((
dev
->
class
>>
8
)
&
0xff00
)
{
case
0x0600
:
/* Bridge */
/* Skip bridges. We should call this function for each one. */
...
...
@@ -357,9 +367,6 @@ int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor)
case
0x0300
:
/* Display controller */
case
0x0400
:
/* Multimedia controller */
if
(
mcapndx
==
0
)
continue
;
if
((
cur
=
kmalloc
(
sizeof
(
*
cur
),
GFP_KERNEL
))
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
free_and_exit
;
...
...
@@ -376,51 +383,41 @@ int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor)
}
}
/* Extract some power-on defaults from the target */
pci_read_config_dword
(
td
,
bridge
->
capndx
+
0x04
,
&
tstatus
);
isoch
=
(
tstatus
>>
17
)
&
0x1
;
arqsz
=
(
tstatus
>>
13
)
&
0x7
;
cal_cycle
=
(
tstatus
>>
10
)
&
0x7
;
rate
=
tstatus
&
0x7
;
/*
* Take an initial pass through the devices lying behind our host
* bridge. Make sure each one is actually an AGP 3.0 device, otherwise
* exit with an error message. Along the way store the AGP 3.0
* cap_ptr for each device, the minimum supported cal_cycle, and the
* minimum supported data rate.
* cap_ptr for each device
*/
list_for_each
(
pos
,
head
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
0
_dev
,
list
);
cur
=
list_entry
(
pos
,
struct
agp_3_
5
_dev
,
list
);
dev
=
cur
->
dev
;
pci_read_config_word
(
dev
,
PCI_STATUS
,
&
mpstat
);
if
((
mpstat
&
PCI_STATUS_CAP_LIST
)
==
0
)
if
((
mpstat
&
PCI_STATUS_CAP_LIST
)
==
0
)
continue
;
pci_read_config_byte
(
dev
,
PCI_CAPABILITY_LIST
,
&
mcapndx
);
if
(
mcapndx
!=
0
x00
)
{
if
(
mcapndx
!=
0
)
{
do
{
pci_read_config_dword
(
dev
,
mcapndx
,
&
ncapid
);
if
((
ncapid
&
0xff
)
!=
0x0
2
)
if
((
ncapid
&
0xff
)
!=
2
)
mcapndx
=
(
ncapid
>>
8
)
&
0xff
;
}
while
(((
ncapid
&
0xff
)
!=
0x02
)
&&
(
mcapndx
!=
0x0
0
));
while
(((
ncapid
&
0xff
)
!=
2
)
&&
(
mcapndx
!=
0
));
}
if
(
mcapndx
==
0
)
{
if
(
mcapndx
==
0
)
{
printk
(
KERN_ERR
PFX
"woah! Non-AGP device "
"found on the secondary bus of an AGP 3.
0
bridge!
\n
"
);
"found on the secondary bus of an AGP 3.
5
bridge!
\n
"
);
ret
=
-
ENODEV
;
goto
free_and_exit
;
}
mmajor
=
(
ncapid
>>
AGP_MAJOR_VERSION_SHIFT
)
&
0xf
;
mminor
=
(
ncapid
>>
AGP_MINOR_VERSION_SHIFT
)
&
0xf
;
if
(
mmajor
<
3
)
{
if
(
mmajor
<
3
)
{
printk
(
KERN_ERR
PFX
"woah! AGP 2.0 device "
"found on the secondary bus of an AGP 3.
0
"
"found on the secondary bus of an AGP 3.
5
"
"bridge operating with AGP 3.0 electricals!
\n
"
);
ret
=
-
ENODEV
;
goto
free_and_exit
;
...
...
@@ -428,101 +425,37 @@ int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor)
cur
->
capndx
=
mcapndx
;
pci_read_config_dword
(
dev
,
cur
->
capndx
+
0x04
,
&
mstatus
);
pci_read_config_dword
(
dev
,
cur
->
capndx
+
AGPSTAT
,
&
mstatus
);
if
(((
mstatus
>>
3
)
&
0x1
)
==
0
)
{
printk
(
KERN_ERR
PFX
"woah! AGP 3.
0
device "
"not operating in AGP 3.
0
mode found on the "
"secondary bus of an AGP 3.
0
bridge operating "
if
(((
mstatus
>>
3
)
&
0x1
)
==
0
)
{
printk
(
KERN_ERR
PFX
"woah! AGP 3.
x
device "
"not operating in AGP 3.
x
mode found on the "
"secondary bus of an AGP 3.
5
bridge operating "
"with AGP 3.0 electricals!
\n
"
);
ret
=
-
ENODEV
;
goto
free_and_exit
;
}
tmp
=
(
mstatus
>>
10
)
&
0x7
;
cal_cycle
=
min
(
cal_cycle
,
tmp
);
/* figure the lesser rate */
tmp
=
mstatus
&
0x7
;
if
(
tmp
<
rate
)
rate
=
tmp
;
}
/* Turn rate into something we can actually write out to AGPCMD */
switch
(
rate
)
{
case
0x1
:
case
0x2
:
break
;
case
0x3
:
rate
=
0x2
;
break
;
default:
printk
(
KERN_ERR
PFX
"woah! Bogus AGP rate (%d) "
"value found advertised behind an AGP 3.0 bridge!
\n
"
,
rate
);
ret
=
-
ENODEV
;
goto
free_and_exit
;
}
/*
* Call functions to divide target resources amongst the AGP 3.0
* masters. This process is dramatically different depending on
* whether isochronous transfers are supported.
*/
if
(
isoch
)
{
ret
=
agp_3_
0
_isochronous_node_enable
(
bridge
,
dev_list
,
ndevs
);
ret
=
agp_3_
5
_isochronous_node_enable
(
bridge
,
dev_list
,
ndevs
);
if
(
ret
)
{
printk
(
KERN_INFO
PFX
"Something bad happened setting "
"up isochronous xfers. Falling back to "
"non-isochronous xfer mode.
\n
"
);
}
}
agp_3_0_nonisochronous_node_enable
(
bridge
,
dev_list
,
ndevs
);
/*
* Set the calculated minimum supported cal_cycle and minimum
* supported transfer rate in the target's AGPCMD register.
* Also set the AGP_ENABLE bit, effectively 'turning on' the
* target (this has to be done _before_ turning on the masters).
*/
pci_read_config_dword
(
td
,
bridge
->
capndx
+
AGPCMD
,
&
tcmd
);
tcmd
&=
~
(
0x7
<<
10
);
tcmd
&=
~
0x7
;
tcmd
|=
cal_cycle
<<
10
;
tcmd
|=
0x1
<<
8
;
tcmd
|=
rate
;
pci_write_config_dword
(
td
,
bridge
->
capndx
+
AGPCMD
,
tcmd
);
/*
* Set the target's advertised arqsz value, the minimum supported
* transfer rate, and the AGP_ENABLE bit in each master's AGPCMD
* register.
*/
list_for_each
(
pos
,
head
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_0_dev
,
list
);
dev
=
cur
->
dev
;
mcapndx
=
cur
->
capndx
;
pci_read_config_dword
(
dev
,
cur
->
capndx
+
AGPCMD
,
&
mcmd
);
mcmd
&=
~
(
0x7
<<
AGPSTAT_ARQSZ_SHIFT
);
mcmd
&=
~
0x7
;
mcmd
|=
arqsz
<<
13
;
mcmd
|=
AGPSTAT_AGP_ENABLE
;
mcmd
|=
rate
;
pci_write_config_dword
(
dev
,
cur
->
capndx
+
AGPCMD
,
mcmd
);
}
agp_3_5_nonisochronous_node_enable
(
bridge
,
dev_list
,
ndevs
);
free_and_exit:
/* Be sure to free the dev_list */
for
(
pos
=
head
->
next
;
pos
!=
head
;
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
0
_dev
,
list
);
for
(
pos
=
head
->
next
;
pos
!=
head
;
)
{
cur
=
list_entry
(
pos
,
struct
agp_3_
5
_dev
,
list
);
pos
=
pos
->
next
;
kfree
(
cur
);
...
...
@@ -533,5 +466,3 @@ int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor)
return
ret
;
}
EXPORT_SYMBOL_GPL
(
agp_3_0_node_enable
);
drivers/char/drm/Kconfig
View file @
5e27cb68
...
...
@@ -49,7 +49,7 @@ config DRM_RADEON
config DRM_I810
tristate "Intel I810"
depends on DRM && AGP
depends on DRM && AGP
&& AGP_INTEL
help
Choose this option if you have an Intel I810 graphics card. If M is
selected, the module will be called i810. AGP support is required
...
...
@@ -57,7 +57,7 @@ config DRM_I810
config DRM_I830
tristate "Intel 830M, 845G, 852GM, 855GM, 865G"
depends on DRM && AGP
depends on DRM && AGP
&& AGP_INTEL
help
Choose this option if you have a system that has Intel 830M, 845G,
852GM, 855GM or 865G integrated graphics. If M is selected, the
...
...
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