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
1f5ff7f5
Commit
1f5ff7f5
authored
Mar 11, 2016
by
Ben Skeggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm/nouveau/fifo/gk104: make use of topology info during gpfifo construction
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
19f89279
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
127 additions
and
64 deletions
+127
-64
drivers/gpu/drm/nouveau/include/nvif/cla06f.h
drivers/gpu/drm/nouveau/include/nvif/cla06f.h
+12
-9
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_abi16.c
+14
-4
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nouveau_chan.c
+1
-1
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nouveau_drm.c
+3
-3
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
+97
-47
No files found.
drivers/gpu/drm/nouveau/include/nvif/cla06f.h
View file @
1f5ff7f5
...
@@ -3,19 +3,22 @@
...
@@ -3,19 +3,22 @@
struct
kepler_channel_gpfifo_a_v0
{
struct
kepler_channel_gpfifo_a_v0
{
__u8
version
;
__u8
version
;
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR 0x01
__u8
pad01
[
5
];
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPDEC 0x02
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPPP 0x04
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSVLD 0x08
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0 0x10
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1 0x20
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40
__u8
engine
;
__u16
chid
;
__u16
chid
;
#define NVA06F_V0_ENGINE_SW 0x00000001
#define NVA06F_V0_ENGINE_GR 0x00000002
#define NVA06F_V0_ENGINE_MSVLD 0x00000010
#define NVA06F_V0_ENGINE_MSPDEC 0x00000020
#define NVA06F_V0_ENGINE_MSPPP 0x00000040
#define NVA06F_V0_ENGINE_MSENC 0x00000080
#define NVA06F_V0_ENGINE_CE0 0x00010000
#define NVA06F_V0_ENGINE_CE1 0x00020000
#define NVA06F_V0_ENGINE_CE2 0x00040000
__u32
engines
;
__u32
ilength
;
__u32
ilength
;
__u64
ioffset
;
__u64
ioffset
;
__u64
vm
;
__u64
vm
;
};
};
#define
KEPLER_CHANNEL_GPFIFO_A_V0_NTFY_UEVENT
0x00
#define
NVA06F_V0_NTFY_UEVENT
0x00
#endif
#endif
drivers/gpu/drm/nouveau/nouveau_abi16.c
View file @
1f5ff7f5
...
@@ -263,13 +263,23 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
...
@@ -263,13 +263,23 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
/* hack to allow channel engine type specification on kepler */
/* hack to allow channel engine type specification on kepler */
if
(
device
->
info
.
family
>=
NV_DEVICE_INFO_V0_KEPLER
)
{
if
(
device
->
info
.
family
>=
NV_DEVICE_INFO_V0_KEPLER
)
{
if
(
init
->
fb_ctxdma_handle
!=
~
0
)
if
(
init
->
fb_ctxdma_handle
!=
~
0
)
init
->
fb_ctxdma_handle
=
KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR
;
init
->
fb_ctxdma_handle
=
NVA06F_V0_ENGINE_GR
;
else
else
{
init
->
fb_ctxdma_handle
=
init
->
tt_ctxdma_handle
;
init
->
fb_ctxdma_handle
=
0
;
#define _(A,B) if (init->tt_ctxdma_handle & (A)) init->fb_ctxdma_handle |= (B)
_
(
0x01
,
NVA06F_V0_ENGINE_GR
);
_
(
0x02
,
NVA06F_V0_ENGINE_MSPDEC
);
_
(
0x04
,
NVA06F_V0_ENGINE_MSPPP
);
_
(
0x08
,
NVA06F_V0_ENGINE_MSVLD
);
_
(
0x10
,
NVA06F_V0_ENGINE_CE0
);
_
(
0x20
,
NVA06F_V0_ENGINE_CE1
);
_
(
0x40
,
NVA06F_V0_ENGINE_MSENC
);
#undef _
}
/* allow flips to be executed if this is a graphics channel */
/* allow flips to be executed if this is a graphics channel */
init
->
tt_ctxdma_handle
=
0
;
init
->
tt_ctxdma_handle
=
0
;
if
(
init
->
fb_ctxdma_handle
==
KEPLER_CHANNEL_GPFIFO_A
_V0_ENGINE_GR
)
if
(
init
->
fb_ctxdma_handle
==
NVA06F
_V0_ENGINE_GR
)
init
->
tt_ctxdma_handle
=
1
;
init
->
tt_ctxdma_handle
=
1
;
}
}
...
...
drivers/gpu/drm/nouveau/nouveau_chan.c
View file @
1f5ff7f5
...
@@ -217,7 +217,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
...
@@ -217,7 +217,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
do
{
do
{
if
(
oclass
[
0
]
>=
KEPLER_CHANNEL_GPFIFO_A
)
{
if
(
oclass
[
0
]
>=
KEPLER_CHANNEL_GPFIFO_A
)
{
args
.
kepler
.
version
=
0
;
args
.
kepler
.
version
=
0
;
args
.
kepler
.
engine
=
engine
;
args
.
kepler
.
engine
s
=
engine
;
args
.
kepler
.
ilength
=
0x02000
;
args
.
kepler
.
ilength
=
0x02000
;
args
.
kepler
.
ioffset
=
0x10000
+
chan
->
push
.
vma
.
offset
;
args
.
kepler
.
ioffset
=
0x10000
+
chan
->
push
.
vma
.
offset
;
args
.
kepler
.
vm
=
0
;
args
.
kepler
.
vm
=
0
;
...
...
drivers/gpu/drm/nouveau/nouveau_drm.c
View file @
1f5ff7f5
...
@@ -215,13 +215,13 @@ nouveau_accel_init(struct nouveau_drm *drm)
...
@@ -215,13 +215,13 @@ nouveau_accel_init(struct nouveau_drm *drm)
if
(
device
->
info
.
family
>=
NV_DEVICE_INFO_V0_KEPLER
)
{
if
(
device
->
info
.
family
>=
NV_DEVICE_INFO_V0_KEPLER
)
{
ret
=
nouveau_channel_new
(
drm
,
&
drm
->
device
,
ret
=
nouveau_channel_new
(
drm
,
&
drm
->
device
,
KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0
|
NVA06F_V0_ENGINE_CE0
|
KEPLER_CHANNEL_GPFIFO_A
_V0_ENGINE_CE1
,
NVA06F
_V0_ENGINE_CE1
,
0
,
&
drm
->
cechan
);
0
,
&
drm
->
cechan
);
if
(
ret
)
if
(
ret
)
NV_ERROR
(
drm
,
"failed to create ce channel, %d
\n
"
,
ret
);
NV_ERROR
(
drm
,
"failed to create ce channel, %d
\n
"
,
ret
);
arg0
=
KEPLER_CHANNEL_GPFIFO_A
_V0_ENGINE_GR
;
arg0
=
NVA06F
_V0_ENGINE_GR
;
arg1
=
1
;
arg1
=
1
;
}
else
}
else
if
(
device
->
info
.
chipset
>=
0xa3
&&
if
(
device
->
info
.
chipset
>=
0xa3
&&
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
View file @
1f5ff7f5
...
@@ -202,73 +202,79 @@ gk104_fifo_gpfifo_func = {
...
@@ -202,73 +202,79 @@ gk104_fifo_gpfifo_func = {
.
engine_fini
=
gk104_fifo_gpfifo_engine_fini
,
.
engine_fini
=
gk104_fifo_gpfifo_engine_fini
,
};
};
int
struct
gk104_fifo_chan_func
{
gk104_fifo_gpfifo_new
(
struct
nvkm_fifo
*
base
,
const
struct
nvkm_oclass
*
oclass
,
u32
engine
;
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
u64
subdev
;
};
static
int
gk104_fifo_gpfifo_new_
(
const
struct
gk104_fifo_chan_func
*
func
,
struct
gk104_fifo
*
fifo
,
u32
*
engmask
,
u16
*
chid
,
u64
vm
,
u64
ioffset
,
u64
ilength
,
const
struct
nvkm_oclass
*
oclass
,
struct
nvkm_object
**
pobject
)
{
{
union
{
struct
kepler_channel_gpfifo_a_v0
v0
;
}
*
args
=
data
;
struct
gk104_fifo
*
fifo
=
gk104_fifo
(
base
);
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_object
*
parent
=
oclass
->
parent
;
struct
gk104_fifo_chan
*
chan
;
struct
gk104_fifo_chan
*
chan
;
u64
usermem
,
ioffset
,
ilength
;
int
runlist
=
-
1
,
ret
=
-
ENOSYS
,
i
,
j
;
u32
engines
;
u32
engines
=
0
,
present
=
0
;
int
ret
=
-
ENOSYS
,
i
;
u64
subdevs
=
0
;
u64
usermem
;
nvif_ioctl
(
parent
,
"create channel gpfifo size %d
\n
"
,
size
);
if
(
!
(
ret
=
nvif_unpack
(
ret
,
&
data
,
&
size
,
args
->
v0
,
0
,
0
,
false
)))
{
/* Determine which downstream engines are present */
nvif_ioctl
(
parent
,
"create channel gpfifo vers %d vm %llx "
for
(
i
=
0
;
i
<
fifo
->
engine_nr
;
i
++
)
{
"ioffset %016llx ilength %08x engine %08x
\n
"
,
struct
nvkm_engine
*
engine
=
fifo
->
engine
[
i
].
engine
;
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
ioffset
,
if
(
engine
)
{
args
->
v0
.
ilength
,
args
->
v0
.
engine
);
u64
submask
=
BIT_ULL
(
engine
->
subdev
.
index
);
}
else
for
(
j
=
0
;
func
[
j
].
subdev
;
j
++
)
{
return
ret
;
if
(
func
[
j
].
subdev
&
submask
)
{
present
|=
func
[
j
].
engine
;
/* determine which downstream engines are present */
break
;
for
(
i
=
0
,
engines
=
0
;
i
<
fifo
->
runlist_nr
;
i
++
)
{
}
u64
subdevs
=
gk104_fifo_engine_subdev
(
i
);
}
if
(
!
nvkm_device_engine
(
device
,
__ffs64
(
subdevs
)))
continue
;
if
(
!
func
[
j
].
subdev
)
engines
|=
(
1
<<
i
);
continue
;
if
(
runlist
<
0
&&
(
*
engmask
&
present
))
runlist
=
fifo
->
engine
[
i
].
runl
;
if
(
runlist
==
fifo
->
engine
[
i
].
runl
)
{
engines
|=
func
[
j
].
engine
;
subdevs
|=
func
[
j
].
subdev
;
}
}
}
}
/*
if this is an engine mask query, we're done
*/
/*
Just an engine mask query? All done here!
*/
if
(
!
args
->
v0
.
engine
)
{
if
(
!
*
engmask
)
{
args
->
v0
.
engine
=
engines
;
*
engmask
=
present
;
return
nvkm_object_new
(
oclass
,
NULL
,
0
,
pobject
);
return
nvkm_object_new
(
oclass
,
NULL
,
0
,
pobject
);
}
}
/* check that we support a requested engine - note that the user
/* No runlist? No supported engines. */
* argument is a mask in order to allow the user to request (for
*
engmask
=
present
;
* example) *any* copy engine, but doesn't matter which.
if
(
runlist
<
0
)
*/
args
->
v0
.
engine
&=
engines
;
if
(
!
args
->
v0
.
engine
)
{
nvif_ioctl
(
parent
,
"no supported engine
\n
"
);
return
-
ENODEV
;
return
-
ENODEV
;
}
*
engmask
=
engines
;
/*
allocate the channel
*/
/*
Allocate the channel.
*/
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
*
pobject
=
&
chan
->
base
.
object
;
chan
->
fifo
=
fifo
;
chan
->
fifo
=
fifo
;
chan
->
runl
=
__ffs
(
args
->
v0
.
engine
)
;
chan
->
runl
=
runlist
;
INIT_LIST_HEAD
(
&
chan
->
head
);
INIT_LIST_HEAD
(
&
chan
->
head
);
ret
=
nvkm_fifo_chan_ctor
(
&
gk104_fifo_gpfifo_func
,
&
fifo
->
base
,
ret
=
nvkm_fifo_chan_ctor
(
&
gk104_fifo_gpfifo_func
,
&
fifo
->
base
,
0x1000
,
0x1000
,
true
,
args
->
v0
.
vm
,
0
,
0x1000
,
0x1000
,
true
,
vm
,
0
,
subdevs
,
gk104_fifo_engine_subdev
(
chan
->
runl
),
1
,
fifo
->
user
.
bar
.
offset
,
0x200
,
1
,
fifo
->
user
.
bar
.
offset
,
0x200
,
oclass
,
&
chan
->
base
);
oclass
,
&
chan
->
base
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
*
chid
=
chan
->
base
.
chid
;
/*
page directory
*/
/*
Page directory.
*/
ret
=
nvkm_gpuobj_new
(
device
,
0x10000
,
0x1000
,
false
,
NULL
,
&
chan
->
pgd
);
ret
=
nvkm_gpuobj_new
(
device
,
0x10000
,
0x1000
,
false
,
NULL
,
&
chan
->
pgd
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
...
@@ -284,10 +290,9 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
...
@@ -284,10 +290,9 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
/*
clear channel control registers
*/
/*
Clear channel control registers.
*/
usermem
=
chan
->
base
.
chid
*
0x200
;
usermem
=
chan
->
base
.
chid
*
0x200
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
ilength
/
8
);
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
nvkm_kmap
(
fifo
->
user
.
mem
);
nvkm_kmap
(
fifo
->
user
.
mem
);
for
(
i
=
0
;
i
<
0x200
;
i
+=
4
)
for
(
i
=
0
;
i
<
0x200
;
i
+=
4
)
...
@@ -316,6 +321,51 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
...
@@ -316,6 +321,51 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
return
0
;
return
0
;
}
}
static
const
struct
gk104_fifo_chan_func
gk104_fifo_gpfifo
[]
=
{
{
NVA06F_V0_ENGINE_SW
|
NVA06F_V0_ENGINE_GR
,
BIT_ULL
(
NVKM_ENGINE_SW
)
|
BIT_ULL
(
NVKM_ENGINE_GR
)
},
{
NVA06F_V0_ENGINE_MSVLD
,
BIT_ULL
(
NVKM_ENGINE_MSVLD
)
},
{
NVA06F_V0_ENGINE_MSPDEC
,
BIT_ULL
(
NVKM_ENGINE_MSPDEC
)
},
{
NVA06F_V0_ENGINE_MSPPP
,
BIT_ULL
(
NVKM_ENGINE_MSPPP
)
},
{
NVA06F_V0_ENGINE_MSENC
,
BIT_ULL
(
NVKM_ENGINE_MSENC
)
},
{
NVA06F_V0_ENGINE_CE0
,
BIT_ULL
(
NVKM_ENGINE_CE0
)
},
{
NVA06F_V0_ENGINE_CE1
,
BIT_ULL
(
NVKM_ENGINE_CE1
)
},
{
NVA06F_V0_ENGINE_CE2
,
BIT_ULL
(
NVKM_ENGINE_CE2
)
},
{}
};
int
gk104_fifo_gpfifo_new
(
struct
nvkm_fifo
*
base
,
const
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nvkm_object
*
parent
=
oclass
->
parent
;
union
{
struct
kepler_channel_gpfifo_a_v0
v0
;
}
*
args
=
data
;
struct
gk104_fifo
*
fifo
=
gk104_fifo
(
base
);
int
ret
=
-
ENOSYS
;
nvif_ioctl
(
parent
,
"create channel gpfifo size %d
\n
"
,
size
);
if
(
!
(
ret
=
nvif_unpack
(
ret
,
&
data
,
&
size
,
args
->
v0
,
0
,
0
,
false
)))
{
nvif_ioctl
(
parent
,
"create channel gpfifo vers %d vm %llx "
"ioffset %016llx ilength %08x engine %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
,
args
->
v0
.
engines
);
return
gk104_fifo_gpfifo_new_
(
gk104_fifo_gpfifo
,
fifo
,
&
args
->
v0
.
engines
,
&
args
->
v0
.
chid
,
args
->
v0
.
vm
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
,
oclass
,
pobject
);
}
return
ret
;
}
const
struct
nvkm_fifo_chan_oclass
const
struct
nvkm_fifo_chan_oclass
gk104_fifo_gpfifo_oclass
=
{
gk104_fifo_gpfifo_oclass
=
{
.
base
.
oclass
=
KEPLER_CHANNEL_GPFIFO_A
,
.
base
.
oclass
=
KEPLER_CHANNEL_GPFIFO_A
,
...
...
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