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
8f0649b5
Commit
8f0649b5
authored
Aug 20, 2015
by
Ben Skeggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm/nouveau/fifo: convert user classes to new-style nvkm_object
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
9a65a38c
Changes
61
Hide whitespace changes
Inline
Side-by-side
Showing
61 changed files
with
2025 additions
and
2121 deletions
+2025
-2121
drivers/gpu/drm/nouveau/include/nvif/device.h
drivers/gpu/drm/nouveau/include/nvif/device.h
+1
-1
drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
+0
-3
drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
+1
-0
drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
+0
-1
drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h
drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h
+0
-52
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
+34
-26
drivers/gpu/drm/nouveau/nv84_fence.c
drivers/gpu/drm/nouveau/nv84_fence.c
+1
-1
drivers/gpu/drm/nouveau/nvkm/core/Kbuild
drivers/gpu/drm/nouveau/nvkm/core/Kbuild
+0
-1
drivers/gpu/drm/nouveau/nvkm/core/engctx.c
drivers/gpu/drm/nouveau/nvkm/core/engctx.c
+1
-74
drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
+10
-0
drivers/gpu/drm/nouveau/nvkm/core/handle.c
drivers/gpu/drm/nouveau/nvkm/core/handle.c
+2
-50
drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
+1
-1
drivers/gpu/drm/nouveau/nvkm/core/namedb.c
drivers/gpu/drm/nouveau/nvkm/core/namedb.c
+0
-201
drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
+2
-1
drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
+4
-3
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c
+1
-1
drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c
drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c
+23
-83
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
+65
-43
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
+405
-72
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
+24
-20
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
+193
-134
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h
+13
-12
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h
+17
-15
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv04.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv04.h
+12
-12
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c
+157
-136
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h
+20
-27
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c
+34
-68
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
+77
-139
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.c
+27
-34
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.c
+28
-36
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.c
+134
-106
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c
+32
-56
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
+11
-2
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
+39
-22
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h
+5
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
+48
-66
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
+42
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm204.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm204.c
+9
-1
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c
+31
-59
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
+184
-190
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
+189
-218
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm204.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm204.c
+6
-4
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c
+29
-47
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
+27
-13
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
+1
-8
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
+7
-12
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
+11
-16
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
+11
-16
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
+12
-3
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
+0
-1
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+11
-8
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
+2
-1
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
+2
-1
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
+13
-11
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
+2
-2
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
+2
-3
drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
+2
-1
drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c
+2
-2
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
+1
-1
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
+6
-4
No files found.
drivers/gpu/drm/nouveau/include/nvif/device.h
View file @
8f0649b5
...
...
@@ -64,6 +64,6 @@ u64 nvif_device_time(struct nvif_device *);
#include <engine/gr.h>
#include <engine/sw.h>
#define nvxx_fifo(a) nv
km_fifo(nvxx_device(a))
#define nvxx_fifo(a) nv
xx_device(a)->fifo
#define nvxx_gr(a) nvkm_gr(nvxx_device(a))
#endif
drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
View file @
8f0649b5
...
...
@@ -45,7 +45,4 @@ int _nvkm_engctx_init(struct nvkm_object *);
int
_nvkm_engctx_fini
(
struct
nvkm_object
*
,
bool
suspend
);
#define _nvkm_engctx_rd32 _nvkm_gpuobj_rd32
#define _nvkm_engctx_wr32 _nvkm_gpuobj_wr32
struct
nvkm_object
*
nvkm_engctx_get
(
struct
nvkm_engine
*
,
u64
addr
);
void
nvkm_engctx_put
(
struct
nvkm_object
*
);
#endif
drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
View file @
8f0649b5
...
...
@@ -42,6 +42,7 @@ struct nvkm_engine_func {
int
(
*
sclass
)(
struct
nvkm_oclass
*
,
int
index
);
}
fifo
;
const
struct
nvkm_object_func
*
cclass
;
struct
nvkm_sclass
sclass
[];
};
...
...
drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
View file @
8f0649b5
...
...
@@ -4,7 +4,6 @@
struct
nvkm_object
;
struct
nvkm_handle
{
struct
nvkm_namedb
*
namedb
;
struct
list_head
node
;
struct
list_head
head
;
...
...
drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h
deleted
100644 → 0
View file @
9a65a38c
#ifndef __NVKM_NAMEDB_H__
#define __NVKM_NAMEDB_H__
#include <core/parent.h>
struct
nvkm_handle
;
struct
nvkm_namedb
{
struct
nvkm_parent
parent
;
rwlock_t
lock
;
struct
list_head
list
;
};
static
inline
struct
nvkm_namedb
*
nv_namedb
(
void
*
obj
)
{
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
BUG_ON
(
!
nv_iclass
(
obj
,
NV_NAMEDB_CLASS
));
#endif
return
obj
;
}
#define nvkm_namedb_create(p,e,c,v,s,m,d) \
nvkm_namedb_create_((p), (e), (c), (v), (s), (m), \
sizeof(**d), (void **)d)
#define nvkm_namedb_init(p) \
nvkm_parent_init(&(p)->parent)
#define nvkm_namedb_fini(p,s) \
nvkm_parent_fini(&(p)->parent, (s))
#define nvkm_namedb_destroy(p) \
nvkm_parent_destroy(&(p)->parent)
int
nvkm_namedb_create_
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
struct
nvkm_oclass
*
,
u32
pclass
,
struct
nvkm_oclass
*
,
u64
engcls
,
int
size
,
void
**
);
int
_nvkm_namedb_ctor
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
struct
nvkm_oclass
*
,
void
*
,
u32
,
struct
nvkm_object
**
);
#define _nvkm_namedb_dtor _nvkm_parent_dtor
#define _nvkm_namedb_init _nvkm_parent_init
#define _nvkm_namedb_fini _nvkm_parent_fini
int
nvkm_namedb_insert
(
struct
nvkm_namedb
*
,
u32
name
,
struct
nvkm_object
*
,
struct
nvkm_handle
*
);
void
nvkm_namedb_remove
(
struct
nvkm_handle
*
);
struct
nvkm_handle
*
nvkm_namedb_get
(
struct
nvkm_namedb
*
,
u32
);
struct
nvkm_handle
*
nvkm_namedb_get_class
(
struct
nvkm_namedb
*
,
s32
);
struct
nvkm_handle
*
nvkm_namedb_get_vinst
(
struct
nvkm_namedb
*
,
u64
);
struct
nvkm_handle
*
nvkm_namedb_get_cinst
(
struct
nvkm_namedb
*
,
u32
);
void
nvkm_namedb_put
(
struct
nvkm_handle
*
);
#endif
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
View file @
8f0649b5
#ifndef __NVKM_FIFO_H__
#define __NVKM_FIFO_H__
#include <core/namedb.h>
#define nvkm_fifo_chan(p) container_of((p), struct nvkm_fifo_chan, object)
#define nvkm_fifo(p) container_of((p), struct nvkm_fifo, engine)
#include <core/engine.h>
#include <core/event.h>
#define NVKM_FIFO_CHID_NR 4096
struct
nvkm_fifo_engn
{
struct
nvkm_object
*
object
;
int
refcount
;
int
usecount
;
};
struct
nvkm_fifo_chan
{
struct
nvkm_namedb
namedb
;
struct
nvkm_gpuobj
*
pushgpu
;
const
struct
nvkm_fifo_chan_func
*
func
;
struct
nvkm_fifo
*
fifo
;
u64
engines
;
struct
nvkm_object
object
;
struct
list_head
head
;
u16
chid
;
struct
nvkm_gpuobj
*
inst
;
struct
nvkm_gpuobj
*
push
;
struct
nvkm_vm
*
vm
;
void
__iomem
*
user
;
u64
addr
;
u32
size
;
u16
chid
;
u64
inst
;
struct
nvkm_fifo_engn
engn
[
NVDEV_SUBDEV_NR
]
;
};
static
inline
struct
nvkm_fifo_chan
*
nvkm_fifo_chan
(
void
*
obj
)
{
return
(
void
*
)
nv_namedb
(
obj
);
}
extern
const
struct
nvkm_object_func
nvkm_fifo_chan_func
;
#include <core/gpuobj.h>
struct
nvkm_fifo_base
{
struct
nvkm_gpuobj
gpuobj
;
};
...
...
@@ -39,25 +53,27 @@ struct nvkm_fifo_base {
#define _nvkm_fifo_context_rd32 _nvkm_gpuobj_rd32
#define _nvkm_fifo_context_wr32 _nvkm_gpuobj_wr32
#include <core/engine.h>
#include <core/event.h>
struct
nvkm_fifo
{
struct
nvkm_engine
engine
;
const
struct
nvkm_fifo_func
*
func
;
struct
nvkm_event
cevent
;
/* channel creation event */
struct
nvkm_event
uevent
;
/* async user trigger */
struct
nvkm_object
**
channel
;
DECLARE_BITMAP
(
mask
,
NVKM_FIFO_CHID_NR
);
int
nr
;
struct
list_head
chan
;
spinlock_t
lock
;
u16
min
;
u16
max
;
int
(
*
chid
)(
struct
nvkm_fifo
*
,
struct
nvkm_object
*
);
void
(
*
pause
)(
struct
nvkm_fifo
*
,
unsigned
long
*
);
void
(
*
start
)(
struct
nvkm_fifo
*
,
unsigned
long
*
);
};
struct
nvkm_fifo_func
{
void
*
(
*
dtor
)(
struct
nvkm_fifo
*
);
const
struct
nvkm_fifo_chan_oclass
*
chan
[];
};
void
nvkm_fifo_chan_put
(
struct
nvkm_fifo
*
,
unsigned
long
flags
,
struct
nvkm_fifo_chan
**
);
struct
nvkm_fifo_chan
*
...
...
@@ -65,12 +81,6 @@ nvkm_fifo_chan_inst(struct nvkm_fifo *, u64 inst, unsigned long *flags);
struct
nvkm_fifo_chan
*
nvkm_fifo_chan_chid
(
struct
nvkm_fifo
*
,
int
chid
,
unsigned
long
*
flags
);
static
inline
struct
nvkm_fifo
*
nvkm_fifo
(
void
*
obj
)
{
return
(
void
*
)
nvkm_engine
(
obj
,
NVDEV_ENGINE_FIFO
);
}
#define nvkm_fifo_create(o,e,c,fc,lc,d) \
nvkm_fifo_create_((o), (e), (c), (fc), (lc), sizeof(**d), (void **)d)
#define nvkm_fifo_init(p) \
...
...
@@ -82,8 +92,6 @@ int nvkm_fifo_create_(struct nvkm_object *, struct nvkm_object *,
struct
nvkm_oclass
*
,
int
min
,
int
max
,
int
size
,
void
**
);
void
nvkm_fifo_destroy
(
struct
nvkm_fifo
*
);
const
char
*
nvkm_client_name_for_fifo_chid
(
struct
nvkm_fifo
*
fifo
,
u32
chid
);
#define _nvkm_fifo_init _nvkm_engine_init
#define _nvkm_fifo_fini _nvkm_engine_fini
...
...
drivers/gpu/drm/nouveau/nv84_fence.c
View file @
8f0649b5
...
...
@@ -228,7 +228,7 @@ nv84_fence_create(struct nouveau_drm *drm)
priv
->
base
.
context_new
=
nv84_fence_context_new
;
priv
->
base
.
context_del
=
nv84_fence_context_del
;
priv
->
base
.
contexts
=
fifo
->
max
+
1
;
priv
->
base
.
contexts
=
fifo
->
nr
;
priv
->
base
.
context_base
=
fence_context_alloc
(
priv
->
base
.
contexts
);
priv
->
base
.
uevent
=
true
;
...
...
drivers/gpu/drm/nouveau/nvkm/core/Kbuild
View file @
8f0649b5
...
...
@@ -8,7 +8,6 @@ nvkm-y += nvkm/core/handle.o
nvkm-y += nvkm/core/ioctl.o
nvkm-y += nvkm/core/memory.o
nvkm-y += nvkm/core/mm.o
nvkm-y += nvkm/core/namedb.o
nvkm-y += nvkm/core/notify.o
nvkm-y += nvkm/core/object.o
nvkm-y += nvkm/core/oproxy.o
...
...
drivers/gpu/drm/nouveau/nvkm/core/engctx.c
View file @
8f0649b5
...
...
@@ -124,58 +124,12 @@ nvkm_engctx_destroy(struct nvkm_engctx *engctx)
int
nvkm_engctx_init
(
struct
nvkm_engctx
*
engctx
)
{
struct
nvkm_object
*
object
=
nv_object
(
engctx
);
struct
nvkm_subdev
*
subdev
=
nv_subdev
(
object
->
engine
);
struct
nvkm_object
*
parent
;
struct
nvkm_subdev
*
pardev
;
int
ret
;
ret
=
nvkm_gpuobj_init
(
&
engctx
->
gpuobj
);
if
(
ret
)
return
ret
;
parent
=
nv_pclass
(
object
->
parent
,
NV_PARENT_CLASS
);
pardev
=
nv_subdev
(
parent
->
engine
);
if
(
nv_parent
(
parent
)
->
context_attach
)
{
mutex_lock
(
&
pardev
->
mutex
);
ret
=
nv_parent
(
parent
)
->
context_attach
(
parent
,
object
);
mutex_unlock
(
&
pardev
->
mutex
);
}
if
(
ret
)
{
nvkm_error
(
pardev
,
"failed to attach %s context, %d
\n
"
,
nvkm_subdev_name
[
subdev
->
index
],
ret
);
return
ret
;
}
nvkm_trace
(
pardev
,
"attached %s context
\n
"
,
nvkm_subdev_name
[
subdev
->
index
]);
return
0
;
return
nvkm_gpuobj_init
(
&
engctx
->
gpuobj
);
}
int
nvkm_engctx_fini
(
struct
nvkm_engctx
*
engctx
,
bool
suspend
)
{
struct
nvkm_object
*
object
=
nv_object
(
engctx
);
struct
nvkm_subdev
*
subdev
=
nv_subdev
(
object
->
engine
);
struct
nvkm_object
*
parent
;
struct
nvkm_subdev
*
pardev
;
int
ret
=
0
;
parent
=
nv_pclass
(
object
->
parent
,
NV_PARENT_CLASS
);
pardev
=
nv_subdev
(
parent
->
engine
);
if
(
nv_parent
(
parent
)
->
context_detach
)
{
mutex_lock
(
&
pardev
->
mutex
);
ret
=
nv_parent
(
parent
)
->
context_detach
(
parent
,
suspend
,
object
);
mutex_unlock
(
&
pardev
->
mutex
);
}
if
(
ret
)
{
nvkm_error
(
pardev
,
"failed to detach %s context, %d
\n
"
,
nvkm_subdev_name
[
subdev
->
index
],
ret
);
return
ret
;
}
nvkm_trace
(
pardev
,
"detached %s context
\n
"
,
nvkm_subdev_name
[
subdev
->
index
]);
return
nvkm_gpuobj_fini
(
&
engctx
->
gpuobj
,
suspend
);
}
...
...
@@ -210,30 +164,3 @@ _nvkm_engctx_fini(struct nvkm_object *object, bool suspend)
{
return
nvkm_engctx_fini
(
nv_engctx
(
object
),
suspend
);
}
struct
nvkm_object
*
nvkm_engctx_get
(
struct
nvkm_engine
*
engine
,
u64
addr
)
{
struct
nvkm_engctx
*
engctx
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
engine
->
lock
,
flags
);
list_for_each_entry
(
engctx
,
&
engine
->
contexts
,
head
)
{
if
(
engctx
->
addr
==
addr
)
{
engctx
->
save
=
flags
;
return
nv_object
(
engctx
);
}
}
spin_unlock_irqrestore
(
&
engine
->
lock
,
flags
);
return
NULL
;
}
void
nvkm_engctx_put
(
struct
nvkm_object
*
object
)
{
if
(
object
)
{
struct
nvkm_engine
*
engine
=
nv_engine
(
object
->
engine
);
struct
nvkm_engctx
*
engctx
=
nv_engctx
(
object
);
spin_unlock_irqrestore
(
&
engine
->
lock
,
engctx
->
save
);
}
}
drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
View file @
8f0649b5
...
...
@@ -231,6 +231,8 @@ nvkm_gpuobj_destroy(struct nvkm_gpuobj *gpuobj)
nvkm_object_destroy
(
&
gpuobj
->
object
);
}
#include <engine/fifo.h>
int
nvkm_gpuobj_create_
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
u32
pclass
,
...
...
@@ -240,11 +242,19 @@ nvkm_gpuobj_create_(struct nvkm_object *parent, struct nvkm_object *engine,
struct
nvkm_device
*
device
=
nv_device
(
parent
);
struct
nvkm_gpuobj
*
pargpu
=
NULL
;
struct
nvkm_gpuobj
*
gpuobj
;
struct
nvkm_object
*
object
=
objgpu
;
const
bool
zero
=
(
flags
&
NVOBJ_FLAG_ZERO_ALLOC
);
int
ret
;
*
pobject
=
NULL
;
while
(
object
&&
object
->
func
!=
&
nvkm_fifo_chan_func
)
object
=
object
->
parent
;
if
(
object
)
{
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
);
pargpu
=
chan
->
inst
;
}
else
if
(
objgpu
)
{
while
((
objgpu
=
nv_pclass
(
objgpu
,
NV_GPUOBJ_CLASS
)))
{
if
(
nv_gpuobj
(
objgpu
)
->
heap
.
block_size
)
...
...
drivers/gpu/drm/nouveau/nvkm/core/handle.c
View file @
8f0649b5
...
...
@@ -23,7 +23,7 @@
*/
#include <core/handle.h>
#include <core/client.h>
#include <core/
namedb
.h>
#include <core/
parent
.h>
#define hprintk(h,l,f,a...) do { \
struct nvkm_handle *p = (h)->parent; u32 n = p ? p->name : ~0; \
...
...
@@ -98,14 +98,9 @@ int
nvkm_handle_create
(
struct
nvkm_handle
*
parent
,
u32
_handle
,
struct
nvkm_object
*
object
,
struct
nvkm_handle
**
phandle
)
{
struct
nvkm_object
*
namedb
;
struct
nvkm_handle
*
handle
;
int
ret
;
namedb
=
parent
?
parent
->
object
:
NULL
;
while
(
namedb
&&
!
nv_iclass
(
namedb
,
NV_NAMEDB_CLASS
))
namedb
=
namedb
->
parent
;
handle
=
kzalloc
(
sizeof
(
*
handle
),
GFP_KERNEL
);
if
(
!
handle
)
return
-
ENOMEM
;
...
...
@@ -118,15 +113,6 @@ nvkm_handle_create(struct nvkm_handle *parent, u32 _handle,
handle
->
parent
=
parent
;
nvkm_object_ref
(
object
,
&
handle
->
object
);
if
(
namedb
)
{
ret
=
nvkm_namedb_insert
(
nv_namedb
(
namedb
),
_handle
,
object
,
handle
);
if
(
ret
)
{
kfree
(
handle
);
return
ret
;
}
}
if
(
parent
)
{
if
(
nv_iclass
(
parent
->
object
,
NV_PARENT_CLASS
)
&&
nv_parent
(
parent
->
object
)
->
object_attach
)
{
...
...
@@ -168,40 +154,6 @@ nvkm_handle_destroy(struct nvkm_handle *handle)
}
hprintk
(
handle
,
TRACE
,
"destroy completed
\n
"
);
nvkm_
namedb_remove
(
handle
);
nvkm_
object_ref
(
NULL
,
&
handle
->
object
);
kfree
(
handle
);
}
struct
nvkm_handle
*
nvkm_handle_get_class
(
struct
nvkm_object
*
engctx
,
u16
oclass
)
{
struct
nvkm_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nvkm_namedb_get_class
(
namedb
,
oclass
);
return
NULL
;
}
struct
nvkm_handle
*
nvkm_handle_get_vinst
(
struct
nvkm_object
*
engctx
,
u64
vinst
)
{
struct
nvkm_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nvkm_namedb_get_vinst
(
namedb
,
vinst
);
return
NULL
;
}
struct
nvkm_handle
*
nvkm_handle_get_cinst
(
struct
nvkm_object
*
engctx
,
u32
cinst
)
{
struct
nvkm_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nvkm_namedb_get_cinst
(
namedb
,
cinst
);
return
NULL
;
}
void
nvkm_handle_put
(
struct
nvkm_handle
*
handle
)
{
if
(
handle
)
nvkm_namedb_put
(
handle
);
}
drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
View file @
8f0649b5
...
...
@@ -25,7 +25,7 @@
#include <core/client.h>
#include <core/engine.h>
#include <core/handle.h>
#include <core/
namedb
.h>
#include <core/
parent
.h>
#include <nvif/unpack.h>
#include <nvif/ioctl.h>
...
...
drivers/gpu/drm/nouveau/nvkm/core/namedb.c
deleted
100644 → 0
View file @
9a65a38c
/*
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include <core/namedb.h>
#include <core/gpuobj.h>
#include <core/handle.h>
static
struct
nvkm_handle
*
nvkm_namedb_lookup
(
struct
nvkm_namedb
*
namedb
,
u32
name
)
{
struct
nvkm_handle
*
handle
;
list_for_each_entry
(
handle
,
&
namedb
->
list
,
node
)
{
if
(
handle
->
name
==
name
)
return
handle
;
}
return
NULL
;
}
static
struct
nvkm_handle
*
nvkm_namedb_lookup_class
(
struct
nvkm_namedb
*
namedb
,
s32
oclass
)
{
struct
nvkm_handle
*
handle
;
list_for_each_entry
(
handle
,
&
namedb
->
list
,
node
)
{
if
(
nv_mclass
(
handle
->
object
)
==
oclass
)
return
handle
;
}
return
NULL
;
}
static
struct
nvkm_handle
*
nvkm_namedb_lookup_vinst
(
struct
nvkm_namedb
*
namedb
,
u64
vinst
)
{
struct
nvkm_handle
*
handle
;
list_for_each_entry
(
handle
,
&
namedb
->
list
,
node
)
{
if
(
nv_iclass
(
handle
->
object
,
NV_GPUOBJ_CLASS
))
{
if
(
nv_gpuobj
(
handle
->
object
)
->
addr
==
vinst
)
return
handle
;
}
}
return
NULL
;
}
static
struct
nvkm_handle
*
nvkm_namedb_lookup_cinst
(
struct
nvkm_namedb
*
namedb
,
u32
cinst
)
{
struct
nvkm_handle
*
handle
;
list_for_each_entry
(
handle
,
&
namedb
->
list
,
node
)
{
if
(
nv_iclass
(
handle
->
object
,
NV_GPUOBJ_CLASS
))
{
if
(
nv_gpuobj
(
handle
->
object
)
->
node
&&
nv_gpuobj
(
handle
->
object
)
->
node
->
offset
==
cinst
)
return
handle
;
}
}
return
NULL
;
}
int
nvkm_namedb_insert
(
struct
nvkm_namedb
*
namedb
,
u32
name
,
struct
nvkm_object
*
object
,
struct
nvkm_handle
*
handle
)
{
int
ret
=
-
EEXIST
;
write_lock_irq
(
&
namedb
->
lock
);
if
(
!
nvkm_namedb_lookup
(
namedb
,
name
))
{
nvkm_object_ref
(
object
,
&
handle
->
object
);
handle
->
namedb
=
namedb
;
list_add
(
&
handle
->
node
,
&
namedb
->
list
);
ret
=
0
;
}
write_unlock_irq
(
&
namedb
->
lock
);
return
ret
;
}
void
nvkm_namedb_remove
(
struct
nvkm_handle
*
handle
)
{
struct
nvkm_namedb
*
namedb
=
handle
->
namedb
;
struct
nvkm_object
*
object
=
handle
->
object
;
if
(
handle
->
namedb
)
{
write_lock_irq
(
&
namedb
->
lock
);
list_del
(
&
handle
->
node
);
write_unlock_irq
(
&
namedb
->
lock
);
}
nvkm_object_ref
(
NULL
,
&
object
);
}
struct
nvkm_handle
*
nvkm_namedb_get
(
struct
nvkm_namedb
*
namedb
,
u32
name
)
{
struct
nvkm_handle
*
handle
;
read_lock
(
&
namedb
->
lock
);
handle
=
nvkm_namedb_lookup
(
namedb
,
name
);
if
(
handle
==
NULL
)
read_unlock
(
&
namedb
->
lock
);
return
handle
;
}
struct
nvkm_handle
*
nvkm_namedb_get_class
(
struct
nvkm_namedb
*
namedb
,
s32
oclass
)
{
struct
nvkm_handle
*
handle
;
read_lock
(
&
namedb
->
lock
);
handle
=
nvkm_namedb_lookup_class
(
namedb
,
oclass
);
if
(
handle
==
NULL
)
read_unlock
(
&
namedb
->
lock
);
return
handle
;
}
struct
nvkm_handle
*
nvkm_namedb_get_vinst
(
struct
nvkm_namedb
*
namedb
,
u64
vinst
)
{
struct
nvkm_handle
*
handle
;
read_lock
(
&
namedb
->
lock
);
handle
=
nvkm_namedb_lookup_vinst
(
namedb
,
vinst
);
if
(
handle
==
NULL
)
read_unlock
(
&
namedb
->
lock
);
return
handle
;
}
struct
nvkm_handle
*
nvkm_namedb_get_cinst
(
struct
nvkm_namedb
*
namedb
,
u32
cinst
)
{
struct
nvkm_handle
*
handle
;
read_lock
(
&
namedb
->
lock
);
handle
=
nvkm_namedb_lookup_cinst
(
namedb
,
cinst
);
if
(
handle
==
NULL
)
read_unlock
(
&
namedb
->
lock
);
return
handle
;
}
void
nvkm_namedb_put
(
struct
nvkm_handle
*
handle
)
{
if
(
handle
)
read_unlock
(
&
handle
->
namedb
->
lock
);
}
int
nvkm_namedb_create_
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
u32
pclass
,
struct
nvkm_oclass
*
sclass
,
u64
engcls
,
int
length
,
void
**
pobject
)
{
struct
nvkm_namedb
*
namedb
;
int
ret
;
ret
=
nvkm_parent_create_
(
parent
,
engine
,
oclass
,
pclass
|
NV_NAMEDB_CLASS
,
sclass
,
engcls
,
length
,
pobject
);
namedb
=
*
pobject
;
if
(
ret
)
return
ret
;
rwlock_init
(
&
namedb
->
lock
);
INIT_LIST_HEAD
(
&
namedb
->
list
);
return
0
;
}
int
_nvkm_namedb_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nvkm_namedb
*
object
;
int
ret
;
ret
=
nvkm_namedb_create
(
parent
,
engine
,
oclass
,
0
,
NULL
,
0
,
&
object
);
*
pobject
=
nv_object
(
object
);
if
(
ret
)
return
ret
;
return
0
;
}
drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
View file @
8f0649b5
...
...
@@ -85,7 +85,8 @@ gt215_ce_intr(struct nvkm_falcon *ce, struct nvkm_fifo_chan *chan)
nvkm_error
(
subdev
,
"DISPATCH_ERROR %04x [%s] ch %d [%010llx %s] "
"subc %d mthd %04x data %08x
\n
"
,
ssta
,
en
?
en
->
name
:
""
,
chan
?
chan
->
chid
:
-
1
,
chan
?
chan
->
inst
:
0
,
nvkm_client_name
(
chan
),
chan
?
chan
->
inst
->
addr
:
0
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
subc
,
mthd
,
data
);
}
...
...
drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
View file @
8f0649b5
...
...
@@ -121,9 +121,10 @@ g84_cipher_intr(struct nvkm_subdev *subdev)
if
(
stat
)
{
nvkm_snprintbf
(
msg
,
sizeof
(
msg
),
g84_cipher_intr_mask
,
stat
);
nvkm_error
(
subdev
,
"%08x [%s] ch %d [%010llx %s] "
"mthd %04x data %08x
\n
"
,
stat
,
msg
,
chan
?
chan
->
chid
:
-
1
,
(
u64
)
inst
<<
12
,
nvkm_client_name
(
chan
),
mthd
,
data
);
"mthd %04x data %08x
\n
"
,
stat
,
msg
,
chan
?
chan
->
chid
:
-
1
,
(
u64
)
inst
<<
12
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
mthd
,
data
);
}
nvkm_fifo_chan_put
(
fifo
,
flags
,
&
chan
);
...
...
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c
View file @
8f0649b5
...
...
@@ -21,7 +21,7 @@
*
* Authors: Ben Skeggs
*/
#define nv04_disp_root(p) container_of((p), struct nv04_disp_root, object)
;
#define nv04_disp_root(p) container_of((p), struct nv04_disp_root, object)
#include "priv.h"
#include <core/client.h>
...
...
drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c
View file @
8f0649b5
...
...
@@ -24,6 +24,7 @@
#include "priv.h"
#include <core/client.h>
#include <engine/fifo.h>
#include <nvif/class.h>
...
...
@@ -88,11 +89,19 @@ nvkm_dma_oclass_base = {
.
ctor
=
nvkm_dma_oclass_new
,
};
static
int
nvkm_dma_oclass_fifo_new
(
const
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
return
nvkm_dma_oclass_new
(
oclass
->
engine
->
subdev
.
device
,
oclass
,
data
,
size
,
pobject
);
}
static
const
struct
nvkm_sclass
nvkm_dma_sclass
[]
=
{
{
0
,
0
,
NV_DMA_FROM_MEMORY
},
{
0
,
0
,
NV_DMA_TO_MEMORY
},
{
0
,
0
,
NV_DMA_IN_MEMORY
},
{
0
,
0
,
NV_DMA_FROM_MEMORY
,
NULL
,
nvkm_dma_oclass_fifo_new
},
{
0
,
0
,
NV_DMA_TO_MEMORY
,
NULL
,
nvkm_dma_oclass_fifo_new
},
{
0
,
0
,
NV_DMA_IN_MEMORY
,
NULL
,
nvkm_dma_oclass_fifo_new
},
};
static
int
...
...
@@ -110,89 +119,21 @@ nvkm_dma_oclass_base_get(struct nvkm_oclass *sclass, int index,
return
count
;
}
static
const
struct
nvkm_engine_func
nvkm_dma
=
{
.
base
.
sclass
=
nvkm_dma_oclass_base_get
,
};
#include <core/gpuobj.h>
static
struct
nvkm_oclass
empty
=
{
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
dtor
=
nvkm_object_destroy
,
.
init
=
_nvkm_object_init
,
.
fini
=
_nvkm_object_fini
,
},
};
static
int
nvkm_dmaobj_compat_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nvkm_oclass
hack
=
{
.
base
.
oclass
=
oclass
->
handle
,
.
client
=
nvkm_client
(
parent
),
.
parent
=
parent
,
.
engine
=
nv_engine
(
engine
),
};
struct
nvkm_dma
*
dma
=
(
void
*
)
engine
;
struct
nvkm_dma_impl
*
impl
=
(
void
*
)
dma
->
engine
.
subdev
.
object
.
oclass
;
struct
nvkm_dmaobj
*
dmaobj
=
NULL
;
struct
nvkm_gpuobj
*
gpuobj
;
int
ret
;
ret
=
impl
->
class_new
(
dma
,
&
hack
,
data
,
size
,
&
dmaobj
);
if
(
dmaobj
)
*
pobject
=
&
dmaobj
->
object
;
if
(
ret
)
return
ret
;
gpuobj
=
(
void
*
)
nv_pclass
(
parent
,
NV_GPUOBJ_CLASS
);
ret
=
dmaobj
->
func
->
bind
(
dmaobj
,
gpuobj
,
16
,
&
gpuobj
);
nvkm_object_ref
(
NULL
,
pobject
);
if
(
ret
)
return
ret
;
ret
=
nvkm_object_create
(
parent
,
engine
,
&
empty
,
0
,
pobject
);
if
(
ret
)
return
ret
;
gpuobj
->
object
.
parent
=
*
pobject
;
gpuobj
->
object
.
engine
=
&
dma
->
engine
;
gpuobj
->
object
.
oclass
=
oclass
;
gpuobj
->
object
.
pclass
=
NV_GPUOBJ_CLASS
;
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
gpuobj
->
object
.
_magic
=
NVKM_OBJECT_MAGIC
;
#endif
*
pobject
=
&
gpuobj
->
object
;
return
0
;
}
static
void
nvkm_dmaobj_compat_dtor
(
struct
nvkm_object
*
object
)
nvkm_dma_oclass_fifo_get
(
struct
nvkm_oclass
*
oclass
,
int
index
)
{
struct
nvkm_object
*
parent
=
object
->
parent
;
struct
nvkm_gpuobj
*
gpuobj
=
(
void
*
)
object
;
nvkm_gpuobj_del
(
&
gpuobj
);
nvkm_object_ref
(
NULL
,
&
parent
);
const
int
count
=
ARRAY_SIZE
(
nvkm_dma_sclass
);
if
(
index
<
count
)
{
oclass
->
base
=
nvkm_dma_sclass
[
index
];
return
index
;
}
return
count
;
}
static
struct
nvkm_ofuncs
nvkm_dmaobj_compat_ofuncs
=
{
.
ctor
=
nvkm_dmaobj_compat_ctor
,
.
dtor
=
nvkm_dmaobj_compat_dtor
,
.
init
=
_nvkm_object_init
,
.
fini
=
_nvkm_object_fini
,
};
static
struct
nvkm_oclass
nvkm_dma_compat_sclass
[]
=
{
{
NV_DMA_FROM_MEMORY
,
&
nvkm_dmaobj_compat_ofuncs
},
{
NV_DMA_TO_MEMORY
,
&
nvkm_dmaobj_compat_ofuncs
},
{
NV_DMA_IN_MEMORY
,
&
nvkm_dmaobj_compat_ofuncs
},
{}
static
const
struct
nvkm_engine_func
nvkm_dma
=
{
.
base
.
sclass
=
nvkm_dma_oclass_base_get
,
.
fifo
.
sclass
=
nvkm_dma_oclass_fifo_get
,
};
int
...
...
@@ -209,7 +150,6 @@ _nvkm_dma_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
dmaeng
->
engine
.
sclass
=
nvkm_dma_compat_sclass
;
dmaeng
->
engine
.
func
=
&
nvkm_dma
;
return
0
;
}
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
View file @
8f0649b5
...
...
@@ -44,12 +44,13 @@ nvkm_fifo_chan_put(struct nvkm_fifo *fifo, unsigned long flags,
struct
nvkm_fifo_chan
*
nvkm_fifo_chan_inst
(
struct
nvkm_fifo
*
fifo
,
u64
inst
,
unsigned
long
*
rflags
)
{
struct
nvkm_fifo_chan
*
chan
;
unsigned
long
flags
;
int
i
;
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
for
(
i
=
fifo
->
min
;
i
<
fifo
->
max
;
i
++
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
fifo
->
channel
[
i
];
if
(
chan
&&
chan
->
inst
==
inst
)
{
list_for_each_entry
(
chan
,
&
fifo
->
chan
,
head
)
{
if
(
chan
->
inst
->
addr
==
inst
)
{
list_del
(
&
chan
->
head
);
list_add
(
&
chan
->
head
,
&
fifo
->
chan
);
*
rflags
=
flags
;
return
chan
;
}
...
...
@@ -61,45 +62,21 @@ nvkm_fifo_chan_inst(struct nvkm_fifo *fifo, u64 inst, unsigned long *rflags)
struct
nvkm_fifo_chan
*
nvkm_fifo_chan_chid
(
struct
nvkm_fifo
*
fifo
,
int
chid
,
unsigned
long
*
rflags
)
{
struct
nvkm_fifo_chan
*
chan
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
if
(
fifo
->
channel
[
chid
])
{
*
rflags
=
flags
;
return
(
void
*
)
fifo
->
channel
[
chid
];
list_for_each_entry
(
chan
,
&
fifo
->
chan
,
head
)
{
if
(
chan
->
chid
==
chid
)
{
list_del
(
&
chan
->
head
);
list_add
(
&
chan
->
head
,
&
fifo
->
chan
);
*
rflags
=
flags
;
return
chan
;
}
}
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
return
NULL
;
}
static
int
nvkm_fifo_chid
(
struct
nvkm_fifo
*
fifo
,
struct
nvkm_object
*
object
)
{
int
engidx
=
nv_hclass
(
fifo
)
&
0xff
;
while
(
object
&&
object
->
parent
)
{
if
(
nv_iclass
(
object
->
parent
,
NV_ENGCTX_CLASS
)
&&
(
nv_hclass
(
object
->
parent
)
&
0xff
)
==
engidx
)
return
nvkm_fifo_chan
(
object
)
->
chid
;
object
=
object
->
parent
;
}
return
-
1
;
}
const
char
*
nvkm_client_name_for_fifo_chid
(
struct
nvkm_fifo
*
fifo
,
u32
chid
)
{
struct
nvkm_fifo_chan
*
chan
=
NULL
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
if
(
chid
>=
fifo
->
min
&&
chid
<=
fifo
->
max
)
chan
=
(
void
*
)
fifo
->
channel
[
chid
];
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
return
nvkm_client_name
(
chan
);
}
static
int
nvkm_fifo_event_ctor
(
struct
nvkm_object
*
object
,
void
*
data
,
u32
size
,
struct
nvkm_notify
*
notify
)
...
...
@@ -144,21 +121,62 @@ nvkm_fifo_uevent(struct nvkm_fifo *fifo)
nvkm_event_send
(
&
fifo
->
uevent
,
1
,
0
,
&
rep
,
sizeof
(
rep
));
}
static
int
nvkm_fifo_class_new
(
struct
nvkm_device
*
device
,
const
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
const
struct
nvkm_fifo_chan_oclass
*
sclass
=
oclass
->
engn
;
struct
nvkm_fifo
*
fifo
=
nvkm_fifo
(
oclass
->
engine
);
return
sclass
->
ctor
(
fifo
,
oclass
,
data
,
size
,
pobject
);
}
static
const
struct
nvkm_device_oclass
nvkm_fifo_class
=
{
.
ctor
=
nvkm_fifo_class_new
,
};
static
int
nvkm_fifo_class_get
(
struct
nvkm_oclass
*
oclass
,
int
index
,
const
struct
nvkm_device_oclass
**
class
)
{
struct
nvkm_fifo
*
fifo
=
nvkm_fifo
(
oclass
->
engine
);
const
struct
nvkm_fifo_chan_oclass
*
sclass
;
int
c
=
0
;
while
((
sclass
=
fifo
->
func
->
chan
[
c
]))
{
if
(
c
++
==
index
)
{
oclass
->
base
=
sclass
->
base
;
oclass
->
engn
=
sclass
;
*
class
=
&
nvkm_fifo_class
;
return
0
;
}
}
return
c
;
}
void
nvkm_fifo_destroy
(
struct
nvkm_fifo
*
fifo
)
{
kfree
(
fifo
->
channel
);
nvkm_event_fini
(
&
fifo
->
uevent
);
nvkm_event_fini
(
&
fifo
->
cevent
);
nvkm_engine_destroy
(
&
fifo
->
engine
);
}
static
const
struct
nvkm_engine_func
nvkm_fifo_func
=
{
.
base
.
sclass
=
nvkm_fifo_class_get
,
};
int
nvkm_fifo_create_
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
int
min
,
int
max
,
int
length
,
void
**
pobject
)
{
struct
nvkm_fifo
*
fifo
;
int
nr
=
max
+
1
;
int
cnt
=
nr
-
min
;
int
ret
;
ret
=
nvkm_engine_create_
(
parent
,
engine
,
oclass
,
true
,
"PFIFO"
,
...
...
@@ -167,17 +185,21 @@ nvkm_fifo_create_(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
min
=
min
;
fifo
->
max
=
max
;
fifo
->
channel
=
kzalloc
(
sizeof
(
*
fifo
->
channel
)
*
(
max
+
1
),
GFP_KERNEL
);
if
(
!
fifo
->
channel
)
return
-
ENOMEM
;
fifo
->
engine
.
func
=
&
nvkm_fifo_func
;
INIT_LIST_HEAD
(
&
fifo
->
chan
);
fifo
->
nr
=
nr
;
if
(
WARN_ON
(
fifo
->
nr
>
NVKM_FIFO_CHID_NR
))
{
fifo
->
nr
=
NVKM_FIFO_CHID_NR
;
cnt
=
fifo
->
nr
-
min
;
}
bitmap_fill
(
fifo
->
mask
,
NVKM_FIFO_CHID_NR
);
bitmap_clear
(
fifo
->
mask
,
min
,
cnt
);
ret
=
nvkm_event_init
(
&
nvkm_fifo_event_func
,
1
,
1
,
&
fifo
->
cevent
);
if
(
ret
)
return
ret
;
fifo
->
chid
=
nvkm_fifo_chid
;
spin_lock_init
(
&
fifo
->
lock
);
return
0
;
}
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
View file @
8f0649b5
...
...
@@ -24,139 +24,472 @@
#include "chan.h"
#include <core/client.h>
#include <core/oproxy.h>
#include <subdev/mmu.h>
#include <engine/dma.h>
#include <nvif/class.h>
struct
nvkm_fifo_chan_object
{
struct
nvkm_oproxy
oproxy
;
struct
nvkm_fifo_chan
*
chan
;
int
hash
;
};
int
_nvkm_fifo_channel_ntfy
(
struct
nvkm_object
*
object
,
u32
type
,
struct
nvkm_event
**
event
)
static
int
nvkm_fifo_chan_child_fini
(
struct
nvkm_oproxy
*
base
,
bool
suspend
)
{
struct
nvkm_fifo_chan_object
*
object
=
container_of
(
base
,
typeof
(
*
object
),
oproxy
);
struct
nvkm_engine
*
engine
=
object
->
oproxy
.
object
->
engine
;
struct
nvkm_fifo_chan
*
chan
=
object
->
chan
;
struct
nvkm_fifo_engn
*
engn
=
&
chan
->
engn
[
engine
->
subdev
.
index
];
const
char
*
name
=
nvkm_subdev_name
[
engine
->
subdev
.
index
];
int
ret
=
0
;
if
(
--
engn
->
usecount
)
return
0
;
if
(
chan
->
func
->
engine_fini
)
{
ret
=
chan
->
func
->
engine_fini
(
chan
,
engine
,
suspend
);
if
(
ret
)
{
nvif_error
(
&
chan
->
object
,
"detach %s failed, %d
\n
"
,
name
,
ret
);
return
ret
;
}
}
if
(
engn
->
object
)
{
ret
=
nvkm_object_fini
(
engn
->
object
,
suspend
);
if
(
ret
&&
suspend
)
return
ret
;
}
nvif_trace
(
&
chan
->
object
,
"detached %s
\n
"
,
name
);
return
ret
;
}
static
int
nvkm_fifo_chan_child_init
(
struct
nvkm_oproxy
*
base
)
{
struct
nvkm_fifo_chan_object
*
object
=
container_of
(
base
,
typeof
(
*
object
),
oproxy
);
struct
nvkm_engine
*
engine
=
object
->
oproxy
.
object
->
engine
;
struct
nvkm_fifo_chan
*
chan
=
object
->
chan
;
struct
nvkm_fifo_engn
*
engn
=
&
chan
->
engn
[
engine
->
subdev
.
index
];
const
char
*
name
=
nvkm_subdev_name
[
engine
->
subdev
.
index
];
int
ret
;
if
(
engn
->
usecount
++
)
return
0
;
if
(
engn
->
object
)
{
ret
=
nvkm_object_init
(
engn
->
object
);
if
(
ret
)
return
ret
;
}
if
(
chan
->
func
->
engine_init
)
{
ret
=
chan
->
func
->
engine_init
(
chan
,
engine
);
if
(
ret
)
{
nvif_error
(
&
chan
->
object
,
"attach %s failed, %d
\n
"
,
name
,
ret
);
return
ret
;
}
}
nvif_trace
(
&
chan
->
object
,
"attached %s
\n
"
,
name
);
return
0
;
}
static
void
nvkm_fifo_chan_child_del
(
struct
nvkm_oproxy
*
base
)
{
struct
nvkm_fifo_chan_object
*
object
=
container_of
(
base
,
typeof
(
*
object
),
oproxy
);
struct
nvkm_engine
*
engine
=
object
->
oproxy
.
base
.
engine
;
struct
nvkm_fifo_chan
*
chan
=
object
->
chan
;
struct
nvkm_fifo_engn
*
engn
=
&
chan
->
engn
[
engine
->
subdev
.
index
];
if
(
chan
->
func
->
object_dtor
)
chan
->
func
->
object_dtor
(
chan
,
object
->
hash
);
if
(
!--
engn
->
refcount
)
{
if
(
chan
->
func
->
engine_dtor
)
chan
->
func
->
engine_dtor
(
chan
,
engine
);
nvkm_object_ref
(
NULL
,
&
engn
->
object
);
if
(
chan
->
vm
)
atomic_dec
(
&
chan
->
vm
->
engref
[
engine
->
subdev
.
index
]);
}
}
static
const
struct
nvkm_oproxy_func
nvkm_fifo_chan_child_func
=
{
.
dtor
[
0
]
=
nvkm_fifo_chan_child_del
,
.
init
[
0
]
=
nvkm_fifo_chan_child_init
,
.
fini
[
0
]
=
nvkm_fifo_chan_child_fini
,
};
static
int
nvkm_fifo_chan_child_old
(
const
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nvkm_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
switch
(
type
)
{
case
G82_CHANNEL_DMA_V0_NTFY_UEVENT
:
if
(
nv_mclass
(
object
)
>=
G82_CHANNEL_DMA
)
{
*
event
=
&
fifo
->
uevent
;
return
0
;
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
oclass
->
parent
);
struct
nvkm_object
*
parent
=
&
chan
->
object
;
struct
nvkm_engine
*
engine
=
oclass
->
engine
;
struct
nvkm_oclass
*
eclass
=
(
void
*
)
oclass
->
priv
;
struct
nvkm_object
*
engctx
=
NULL
;
struct
nvkm_fifo_chan_object
*
object
;
struct
nvkm_fifo_engn
*
engn
=
&
chan
->
engn
[
engine
->
subdev
.
index
];
int
ret
;
if
(
!
(
object
=
kzalloc
(
sizeof
(
*
object
),
GFP_KERNEL
)))
return
-
ENOMEM
;
nvkm_oproxy_ctor
(
&
nvkm_fifo_chan_child_func
,
oclass
,
&
object
->
oproxy
);
*
pobject
=
&
object
->
oproxy
.
base
;
object
->
chan
=
chan
;
if
(
!
engn
->
refcount
++
)
{
if
(
chan
->
vm
)
atomic_inc
(
&
chan
->
vm
->
engref
[
engine
->
subdev
.
index
]);
if
(
engine
->
cclass
&&
!
engn
->
object
)
{
ret
=
nvkm_object_old
(
parent
,
&
engine
->
subdev
.
object
,
engine
->
cclass
,
NULL
,
0
,
&
engn
->
object
);
if
(
ret
)
{
nvkm_engine_unref
(
&
engine
);
return
ret
;
}
}
else
{
nvkm_object_ref
(
parent
,
&
engn
->
object
);
}
break
;
default:
break
;
if
(
chan
->
func
->
engine_ctor
)
{
ret
=
chan
->
func
->
engine_ctor
(
chan
,
engine
,
engn
->
object
);
if
(
ret
)
return
ret
;
}
}
nvkm_object_ref
(
engn
->
object
,
&
engctx
);
ret
=
nvkm_object_old
(
engctx
,
&
engine
->
subdev
.
object
,
eclass
,
data
,
size
,
&
object
->
oproxy
.
object
);
nvkm_object_ref
(
NULL
,
&
engctx
);
if
(
ret
)
return
ret
;
object
->
oproxy
.
object
->
handle
=
oclass
->
handle
;
if
(
chan
->
func
->
object_ctor
)
{
object
->
hash
=
chan
->
func
->
object_ctor
(
chan
,
object
->
oproxy
.
object
);
if
(
object
->
hash
<
0
)
return
object
->
hash
;
}
return
0
;
}
static
int
nvkm_fifo_chan_child_new
(
const
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nvkm_engine
*
engine
=
oclass
->
engine
;
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
oclass
->
parent
);
struct
nvkm_fifo_engn
*
engn
=
&
chan
->
engn
[
engine
->
subdev
.
index
];
struct
nvkm_fifo_chan_object
*
object
;
int
ret
=
0
;
if
(
!
(
object
=
kzalloc
(
sizeof
(
*
object
),
GFP_KERNEL
)))
return
-
ENOMEM
;
nvkm_oproxy_ctor
(
&
nvkm_fifo_chan_child_func
,
oclass
,
&
object
->
oproxy
);
object
->
chan
=
chan
;
*
pobject
=
&
object
->
oproxy
.
base
;
if
(
!
engn
->
refcount
++
)
{
struct
nvkm_oclass
cclass
=
{
.
client
=
oclass
->
client
,
.
engine
=
oclass
->
engine
,
};
if
(
chan
->
vm
)
atomic_inc
(
&
chan
->
vm
->
engref
[
engine
->
subdev
.
index
]);
if
(
engine
->
func
->
fifo
.
cclass
)
{
ret
=
engine
->
func
->
fifo
.
cclass
(
chan
,
&
cclass
,
&
engn
->
object
);
}
else
if
(
engine
->
func
->
cclass
)
{
ret
=
nvkm_object_new_
(
engine
->
func
->
cclass
,
&
cclass
,
NULL
,
0
,
&
engn
->
object
);
}
if
(
ret
)
return
ret
;
if
(
chan
->
func
->
engine_ctor
)
{
ret
=
chan
->
func
->
engine_ctor
(
chan
,
oclass
->
engine
,
engn
->
object
);
if
(
ret
)
return
ret
;
}
}
ret
=
oclass
->
base
.
ctor
(
&
(
const
struct
nvkm_oclass
)
{
.
base
=
oclass
->
base
,
.
engn
=
oclass
->
engn
,
.
handle
=
oclass
->
handle
,
.
object
=
oclass
->
object
,
.
client
=
oclass
->
client
,
.
parent
=
engn
->
object
?
engn
->
object
:
oclass
->
parent
,
.
engine
=
engine
,
},
data
,
size
,
&
object
->
oproxy
.
object
);
if
(
ret
)
return
ret
;
if
(
chan
->
func
->
object_ctor
)
{
object
->
hash
=
chan
->
func
->
object_ctor
(
chan
,
object
->
oproxy
.
object
);
if
(
object
->
hash
<
0
)
return
object
->
hash
;
}
return
0
;
}
static
int
nvkm_fifo_chan_child_get
(
struct
nvkm_object
*
object
,
int
index
,
struct
nvkm_oclass
*
oclass
)
{
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
);
struct
nvkm_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
struct
nvkm_engine
*
engine
;
u64
mask
=
chan
->
engines
;
int
ret
,
i
,
c
;
for
(;
c
=
0
,
i
=
__ffs64
(
mask
),
mask
;
mask
&=
~
(
1ULL
<<
i
))
{
if
((
engine
=
nvkm_device_engine
(
device
,
i
))
&&
!
engine
->
func
)
{
struct
nvkm_oclass
*
sclass
=
engine
->
sclass
;
int
c
=
0
;
while
(
sclass
&&
sclass
->
ofuncs
)
{
if
(
c
++
==
index
)
{
oclass
->
base
.
oclass
=
sclass
->
handle
;
oclass
->
base
.
minver
=
-
2
;
oclass
->
base
.
maxver
=
-
2
;
oclass
->
ctor
=
nvkm_fifo_chan_child_old
;
oclass
->
priv
=
sclass
;
oclass
->
engine
=
engine
;
return
0
;
}
sclass
++
;
}
index
-=
c
;
continue
;
}
if
(
!
(
engine
=
nvkm_device_engine
(
device
,
i
)))
continue
;
oclass
->
engine
=
engine
;
oclass
->
base
.
oclass
=
0
;
if
(
engine
->
func
->
fifo
.
sclass
)
{
ret
=
engine
->
func
->
fifo
.
sclass
(
oclass
,
index
);
if
(
oclass
->
base
.
oclass
)
{
if
(
!
oclass
->
base
.
ctor
)
oclass
->
base
.
ctor
=
nvkm_object_new
;
oclass
->
ctor
=
nvkm_fifo_chan_child_new
;
return
0
;
}
index
-=
ret
;
continue
;
}
while
(
engine
->
func
->
sclass
[
c
].
oclass
)
{
if
(
c
++
==
index
)
{
oclass
->
base
=
engine
->
func
->
sclass
[
index
];
if
(
!
oclass
->
base
.
ctor
)
oclass
->
base
.
ctor
=
nvkm_object_new
;
oclass
->
ctor
=
nvkm_fifo_chan_child_new
;
return
0
;
}
}
index
-=
c
;
}
return
-
EINVAL
;
}
int
_nvkm_fifo_channel_map
(
struct
nvkm_object
*
object
,
u64
*
addr
,
u32
*
size
)
static
int
nvkm_fifo_chan_ntfy
(
struct
nvkm_object
*
object
,
u32
type
,
struct
nvkm_event
**
pevent
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
);
if
(
chan
->
func
->
ntfy
)
return
chan
->
func
->
ntfy
(
chan
,
type
,
pevent
);
return
-
ENODEV
;
}
static
int
nvkm_fifo_chan_map
(
struct
nvkm_object
*
object
,
u64
*
addr
,
u32
*
size
)
{
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
);
*
addr
=
chan
->
addr
;
*
size
=
chan
->
size
;
return
0
;
}
u32
_nvkm_fifo_channel_rd32
(
struct
nvkm_object
*
object
,
u64
addr
)
static
int
nvkm_fifo_chan_rd32
(
struct
nvkm_object
*
object
,
u64
addr
,
u32
*
data
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
)
;
if
(
unlikely
(
!
chan
->
user
))
{
chan
->
user
=
ioremap
(
chan
->
addr
,
chan
->
size
);
if
(
WARN_ON_ONCE
(
chan
->
user
==
NULL
)
)
return
0
;
if
(
!
chan
->
user
)
return
-
ENOMEM
;
}
return
ioread32_native
(
chan
->
user
+
addr
);
if
(
unlikely
(
addr
+
4
>
chan
->
size
))
return
-
EINVAL
;
*
data
=
ioread32_native
(
chan
->
user
+
addr
);
return
0
;
}
void
_nvkm_fifo_channel
_wr32
(
struct
nvkm_object
*
object
,
u64
addr
,
u32
data
)
static
int
nvkm_fifo_chan
_wr32
(
struct
nvkm_object
*
object
,
u64
addr
,
u32
data
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
)
;
if
(
unlikely
(
!
chan
->
user
))
{
chan
->
user
=
ioremap
(
chan
->
addr
,
chan
->
size
);
if
(
WARN_ON_ONCE
(
chan
->
user
==
NULL
)
)
return
;
if
(
!
chan
->
user
)
return
-
ENOMEM
;
}
if
(
unlikely
(
addr
+
4
>
chan
->
size
))
return
-
EINVAL
;
iowrite32_native
(
data
,
chan
->
user
+
addr
);
return
0
;
}
static
int
nvkm_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
);
chan
->
func
->
fini
(
chan
);
return
0
;
}
void
nvkm_fifo_chan
nel_destroy
(
struct
nvkm_fifo_chan
*
chan
)
static
int
nvkm_fifo_chan
_init
(
struct
nvkm_object
*
object
)
{
struct
nvkm_fifo
*
fifo
=
(
void
*
)
nv_object
(
chan
)
->
engine
;
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
);
chan
->
func
->
init
(
chan
);
return
0
;
}
static
void
*
nvkm_fifo_chan_dtor
(
struct
nvkm_object
*
object
)
{
struct
nvkm_fifo_chan
*
chan
=
nvkm_fifo_chan
(
object
);
struct
nvkm_fifo
*
fifo
=
chan
->
fifo
;
void
*
data
=
chan
->
func
->
dtor
(
chan
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
if
(
!
list_empty
(
&
chan
->
head
))
{
__clear_bit
(
chan
->
chid
,
fifo
->
mask
);
list_del
(
&
chan
->
head
);
}
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
if
(
chan
->
user
)
iounmap
(
chan
->
user
);
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
fifo
->
channel
[
chan
->
chid
]
=
NULL
;
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
nvkm_vm_ref
(
NULL
,
&
chan
->
vm
,
NULL
);
nvkm_gpuobj_del
(
&
chan
->
pushgpu
);
nvkm_namedb_destroy
(
&
chan
->
namedb
);
nvkm_gpuobj_del
(
&
chan
->
push
);
nvkm_gpuobj_del
(
&
chan
->
inst
);
return
data
;
}
void
_nvkm_fifo_channel_dtor
(
struct
nvkm_object
*
object
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
nvkm_fifo_channel_destroy
(
chan
);
}
const
struct
nvkm_object_func
nvkm_fifo_chan_func
=
{
.
dtor
=
nvkm_fifo_chan_dtor
,
.
init
=
nvkm_fifo_chan_init
,
.
fini
=
nvkm_fifo_chan_fini
,
.
ntfy
=
nvkm_fifo_chan_ntfy
,
.
map
=
nvkm_fifo_chan_map
,
.
rd32
=
nvkm_fifo_chan_rd32
,
.
wr32
=
nvkm_fifo_chan_wr32
,
.
sclass
=
nvkm_fifo_chan_child_get
,
};
int
nvkm_fifo_chan
nel_create_
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
int
bar
,
u32
addr
,
u32
size
,
u64
pushbuf
,
u64
engmask
,
int
len
,
void
**
ptr
)
nvkm_fifo_chan
_ctor
(
const
struct
nvkm_fifo_chan_func
*
func
,
struct
nvkm_fifo
*
fifo
,
u32
size
,
u32
align
,
bool
zero
,
u64
vm
,
u64
push
,
u64
engines
,
int
bar
,
u32
base
,
u32
user
,
const
struct
nvkm_oclass
*
oclass
,
struct
nvkm_fifo_chan
*
chan
)
{
struct
nvkm_client
*
client
=
nvkm_client
(
parent
);
struct
nvkm_fifo
*
fifo
=
(
void
*
)
engine
;
struct
nvkm_fifo_base
*
base
=
(
void
*
)
parent
;
struct
nvkm_fifo_chan
*
chan
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
struct
nvkm_client
*
client
=
oclass
->
client
;
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
struct
nvkm_mmu
*
mmu
=
device
->
mmu
;
struct
nvkm_dmaobj
*
dmaobj
;
unsigned
long
flags
;
int
ret
;
/* create base object class */
ret
=
nvkm_namedb_create_
(
parent
,
engine
,
oclass
,
0
,
NULL
,
engmask
,
len
,
ptr
);
chan
=
*
ptr
;
nvkm_object_ctor
(
&
nvkm_fifo_chan_func
,
oclass
,
&
chan
->
object
);
chan
->
func
=
func
;
chan
->
fifo
=
fifo
;
chan
->
engines
=
engines
;
INIT_LIST_HEAD
(
&
chan
->
head
);
/* instance memory */
ret
=
nvkm_gpuobj_new
(
device
,
size
,
align
,
zero
,
NULL
,
&
chan
->
inst
);
if
(
ret
)
return
ret
;
/*
validate dma object representing push buffer
*/
if
(
push
buf
)
{
dmaobj
=
nvkm_dma_search
(
device
->
dma
,
client
,
pushbuf
);
/*
allocate push buffer ctxdma instance
*/
if
(
push
)
{
dmaobj
=
nvkm_dma_search
(
device
->
dma
,
oclass
->
client
,
push
);
if
(
!
dmaobj
)
return
-
ENOENT
;
ret
=
nvkm_object_bind
(
&
dmaobj
->
object
,
&
base
->
gpuobj
,
16
,
&
chan
->
push
gpu
);
ret
=
nvkm_object_bind
(
&
dmaobj
->
object
,
chan
->
inst
,
-
16
,
&
chan
->
push
);
if
(
ret
)
return
ret
;
}
/* find a free fifo channel */
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
for
(
chan
->
chid
=
fifo
->
min
;
chan
->
chid
<
fifo
->
max
;
chan
->
chid
++
)
{
if
(
!
fifo
->
channel
[
chan
->
chid
])
{
fifo
->
channel
[
chan
->
chid
]
=
nv_object
(
chan
);
break
;
/* channel address space */
if
(
!
vm
&&
mmu
)
{
if
(
!
client
->
vm
||
client
->
vm
->
mmu
==
mmu
)
{
ret
=
nvkm_vm_ref
(
client
->
vm
,
&
chan
->
vm
,
NULL
);
if
(
ret
)
return
ret
;
}
else
{
return
-
EINVAL
;
}
}
else
{
return
-
ENOENT
;
}
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
if
(
chan
->
chid
==
fifo
->
max
)
{
nvkm_error
(
subdev
,
"no free channels
\n
"
);
/* allocate channel id */
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
chan
->
chid
=
find_first_zero_bit
(
fifo
->
mask
,
NVKM_FIFO_CHID_NR
);
if
(
chan
->
chid
>=
NVKM_FIFO_CHID_NR
)
{
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
return
-
ENOSPC
;
}
list_add
(
&
chan
->
head
,
&
fifo
->
chan
);
__set_bit
(
chan
->
chid
,
fifo
->
mask
);
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
/* determine address of this channel's user registers */
chan
->
addr
=
nv_device_resource_start
(
device
,
bar
)
+
addr
+
size
*
chan
->
chid
;
chan
->
size
=
size
;
base
+
user
*
chan
->
chid
;
chan
->
size
=
user
;
nvkm_event_send
(
&
fifo
->
cevent
,
1
,
0
,
NULL
,
0
);
return
0
;
}
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
View file @
8f0649b5
...
...
@@ -2,27 +2,31 @@
#define __NVKM_FIFO_CHAN_H__
#include "priv.h"
#define nvkm_fifo_channel_create(p,e,c,b,a,s,n,m,d) \
nvkm_fifo_channel_create_((p), (e), (c), (b), (a), (s), (n), \
(m), sizeof(**d), (void **)d)
#define nvkm_fifo_channel_init(p) \
nvkm_namedb_init(&(p)->namedb)
#define nvkm_fifo_channel_fini(p,s) \
nvkm_namedb_fini(&(p)->namedb, (s))
struct
nvkm_fifo_chan_func
{
void
*
(
*
dtor
)(
struct
nvkm_fifo_chan
*
);
void
(
*
init
)(
struct
nvkm_fifo_chan
*
);
void
(
*
fini
)(
struct
nvkm_fifo_chan
*
);
int
(
*
ntfy
)(
struct
nvkm_fifo_chan
*
,
u32
type
,
struct
nvkm_event
**
);
int
(
*
engine_ctor
)(
struct
nvkm_fifo_chan
*
,
struct
nvkm_engine
*
,
struct
nvkm_object
*
);
void
(
*
engine_dtor
)(
struct
nvkm_fifo_chan
*
,
struct
nvkm_engine
*
);
int
(
*
engine_init
)(
struct
nvkm_fifo_chan
*
,
struct
nvkm_engine
*
);
int
(
*
engine_fini
)(
struct
nvkm_fifo_chan
*
,
struct
nvkm_engine
*
,
bool
suspend
);
int
(
*
object_ctor
)(
struct
nvkm_fifo_chan
*
,
struct
nvkm_object
*
);
void
(
*
object_dtor
)(
struct
nvkm_fifo_chan
*
,
int
);
};
int
nvkm_fifo_channel_create_
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
struct
nvkm_oclass
*
,
int
bar
,
u32
addr
,
u32
size
,
u64
push
,
u64
engmask
,
int
len
,
void
**
);
void
nvkm_fifo_channel_destroy
(
struct
nvkm_fifo_chan
*
);
int
nvkm_fifo_chan_ctor
(
const
struct
nvkm_fifo_chan_func
*
,
struct
nvkm_fifo
*
,
u32
size
,
u32
align
,
bool
zero
,
u64
vm
,
u64
push
,
u64
engines
,
int
bar
,
u32
base
,
u32
user
,
const
struct
nvkm_oclass
*
,
struct
nvkm_fifo_chan
*
);
#define _nvkm_fifo_channel_init _nvkm_namedb_init
#define _nvkm_fifo_channel_fini _nvkm_namedb_fini
struct
nvkm_fifo_chan_oclass
{
int
(
*
ctor
)(
struct
nvkm_fifo
*
,
const
struct
nvkm_oclass
*
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
);
struct
nvkm_sclass
base
;
};
void
_nvkm_fifo_channel_dtor
(
struct
nvkm_object
*
);
int
_nvkm_fifo_channel_map
(
struct
nvkm_object
*
,
u64
*
,
u32
*
);
u32
_nvkm_fifo_channel_rd32
(
struct
nvkm_object
*
,
u64
);
void
_nvkm_fifo_channel_wr32
(
struct
nvkm_object
*
,
u64
,
u32
);
int
_nvkm_fifo_channel_ntfy
(
struct
nvkm_object
*
,
u32
,
struct
nvkm_event
**
);
int
g84_fifo_chan_ntfy
(
struct
nvkm_fifo_chan
*
,
u32
,
struct
nvkm_event
**
);
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
View file @
8f0649b5
...
...
@@ -25,38 +25,86 @@
#include <core/client.h>
#include <core/ramht.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
#include <nvif/class.h>
int
g84_fifo_c
ontext_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
objec
t
)
g84_fifo_c
han_ntfy
(
struct
nvkm_fifo_chan
*
chan
,
u32
type
,
struct
nvkm_event
**
peven
t
)
{
struct
nv50_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
u32
addr
,
save
,
engn
;
bool
done
;
switch
(
type
)
{
case
G82_CHANNEL_DMA_V0_NTFY_UEVENT
:
*
pevent
=
&
chan
->
fifo
->
uevent
;
return
0
;
default:
break
;
}
return
-
EINVAL
;
}
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
engn
=
0
;
addr
=
0x0020
;
break
;
static
int
g84_fifo_chan_engine
(
struct
nvkm_engine
*
engine
)
{
switch
(
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_GR
:
return
0
;
case
NVDEV_ENGINE_MPEG
:
case
NVDEV_ENGINE_MSPPP
:
return
1
;
case
NVDEV_ENGINE_CE0
:
return
2
;
case
NVDEV_ENGINE_VP
:
case
NVDEV_ENGINE_MSPDEC
:
engn
=
3
;
addr
=
0x0040
;
break
;
case
NVDEV_ENGINE_
MSPPP
:
case
NVDEV_ENGINE_
MPEG
:
engn
=
1
;
addr
=
0x0060
;
break
;
case
NVDEV_ENGINE_MSPDEC
:
return
3
;
case
NVDEV_ENGINE_
CIPHER
:
case
NVDEV_ENGINE_
SEC
:
return
4
;
case
NVDEV_ENGINE_BSP
:
case
NVDEV_ENGINE_MSVLD
:
engn
=
5
;
addr
=
0x0080
;
break
;
case
NVDEV_ENGINE_MSVLD
:
return
5
;
default:
WARN_ON
(
1
);
return
0
;
}
}
static
int
g84_fifo_chan_engine_addr
(
struct
nvkm_engine
*
engine
)
{
switch
(
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
return
-
1
;
case
NVDEV_ENGINE_GR
:
return
0x0020
;
case
NVDEV_ENGINE_VP
:
case
NVDEV_ENGINE_MSPDEC
:
return
0x0040
;
case
NVDEV_ENGINE_MPEG
:
case
NVDEV_ENGINE_MSPPP
:
return
0x0060
;
case
NVDEV_ENGINE_BSP
:
case
NVDEV_ENGINE_MSVLD
:
return
0x0080
;
case
NVDEV_ENGINE_CIPHER
:
case
NVDEV_ENGINE_SEC
:
engn
=
4
;
addr
=
0x00a0
;
break
;
case
NVDEV_ENGINE_CE0
:
engn
=
2
;
addr
=
0x00c0
;
break
;
case
NVDEV_ENGINE_SEC
:
return
0x00a0
;
case
NVDEV_ENGINE_CE0
:
return
0x00c0
;
default:
return
-
EINVAL
;
WARN_ON
(
1
);
return
-
1
;
}
}
static
int
g84_fifo_chan_engine_fini
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
bool
suspend
)
{
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
struct
nv50_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
u32
engn
,
save
;
int
offset
;
bool
done
;
offset
=
g84_fifo_chan_engine_addr
(
engine
);
if
(
offset
<
0
)
return
0
;
engn
=
g84_fifo_chan_engine
(
engine
);
save
=
nvkm_mask
(
device
,
0x002520
,
0x0000003f
,
1
<<
engn
);
nvkm_wr32
(
device
,
0x0032fc
,
nv_gpuobj
(
base
)
->
addr
>>
12
);
nvkm_wr32
(
device
,
0x0032fc
,
chan
->
base
.
inst
->
addr
>>
12
);
done
=
nvkm_msec
(
device
,
2000
,
if
(
nvkm_rd32
(
device
,
0x0032fc
)
!=
0xffffffff
)
break
;
...
...
@@ -64,168 +112,179 @@ g84_fifo_context_detach(struct nvkm_object *parent, bool suspend,
nvkm_wr32
(
device
,
0x002520
,
save
);
if
(
!
done
)
{
nvkm_error
(
subdev
,
"channel %d [%s] unload timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
)
);
chan
->
base
.
chid
,
chan
->
base
.
object
.
client
->
name
);
if
(
suspend
)
return
-
EBUSY
;
}
nvkm_kmap
(
base
->
eng
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x00
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x04
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x08
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x0c
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x10
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x14
,
0x00000000
);
nvkm_done
(
base
->
eng
);
nvkm_kmap
(
chan
->
eng
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x00
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x04
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x08
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x0c
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x10
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x14
,
0x00000000
);
nvkm_done
(
chan
->
eng
);
return
0
;
}
int
g84_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
g84_fifo_chan_engine_init
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
nvkm_gpuobj
*
ectx
=
(
void
*
)
object
;
u64
limit
=
ectx
->
addr
+
ectx
->
size
-
1
;
u64
start
=
ectx
->
addr
;
u32
addr
;
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
addr
=
0x0020
;
break
;
case
NVDEV_ENGINE_VP
:
case
NVDEV_ENGINE_MSPDEC
:
addr
=
0x0040
;
break
;
case
NVDEV_ENGINE_MSPPP
:
case
NVDEV_ENGINE_MPEG
:
addr
=
0x0060
;
break
;
case
NVDEV_ENGINE_BSP
:
case
NVDEV_ENGINE_MSVLD
:
addr
=
0x0080
;
break
;
case
NVDEV_ENGINE_CIPHER
:
case
NVDEV_ENGINE_SEC
:
addr
=
0x00a0
;
break
;
case
NVDEV_ENGINE_CE0
:
addr
=
0x00c0
;
break
;
default:
return
-
EINVAL
;
}
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
struct
nvkm_gpuobj
*
engn
=
chan
->
engn
[
engine
->
subdev
.
index
];
u64
limit
,
start
;
int
offset
;
nv_engctx
(
ectx
)
->
addr
=
nv_gpuobj
(
base
)
->
addr
>>
12
;
nvkm_kmap
(
base
->
eng
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x00
,
0x00190000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x04
,
lower_32_bits
(
limit
));
nvkm_wo32
(
base
->
eng
,
addr
+
0x08
,
lower_32_bits
(
start
));
nvkm_wo32
(
base
->
eng
,
addr
+
0x0c
,
upper_32_bits
(
limit
)
<<
24
|
upper_32_bits
(
start
));
nvkm_wo32
(
base
->
eng
,
addr
+
0x10
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x14
,
0x00000000
);
nvkm_done
(
base
->
eng
);
offset
=
g84_fifo_chan_engine_addr
(
engine
);
if
(
offset
<
0
)
return
0
;
limit
=
engn
->
addr
+
engn
->
size
-
1
;
start
=
engn
->
addr
;
nvkm_kmap
(
chan
->
eng
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x00
,
0x00190000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x04
,
lower_32_bits
(
limit
));
nvkm_wo32
(
chan
->
eng
,
offset
+
0x08
,
lower_32_bits
(
start
));
nvkm_wo32
(
chan
->
eng
,
offset
+
0x0c
,
upper_32_bits
(
limit
)
<<
24
|
upper_32_bits
(
start
));
nvkm_wo32
(
chan
->
eng
,
offset
+
0x10
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x14
,
0x00000000
);
nvkm_done
(
chan
->
eng
);
return
0
;
}
static
int
g84_fifo_chan_engine_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
struct
nvkm_object
*
object
)
{
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
int
engn
=
engine
->
subdev
.
index
;
if
(
g84_fifo_chan_engine_addr
(
engine
)
<
0
)
return
0
;
if
(
nv_iclass
(
object
,
NV_GPUOBJ_CLASS
))
{
chan
->
engn
[
engn
]
=
nv_gpuobj
(
object
);
return
0
;
}
return
nvkm_object_bind
(
object
,
NULL
,
0
,
&
chan
->
engn
[
engn
]);
}
int
g84_fifo_
object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
g84_fifo_
chan_object_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_object
*
object
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
u32
handle
=
object
->
handle
;
u32
context
;
if
(
nv_iclass
(
object
,
NV_GPUOBJ_CLASS
))
context
=
nv_gpuobj
(
object
)
->
node
->
offset
>>
4
;
else
context
=
0x00000004
;
/* just non-zero */
if
(
object
->
engine
)
{
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
|=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
|=
0x00100000
;
break
;
case
NVDEV_ENGINE_MPEG
:
case
NVDEV_ENGINE_MSPPP
:
context
|=
0x00200000
;
break
;
case
NVDEV_ENGINE_ME
:
case
NVDEV_ENGINE_CE0
:
context
|=
0x00300000
;
break
;
case
NVDEV_ENGINE_VP
:
case
NVDEV_ENGINE_MSPDEC
:
context
|=
0x00400000
;
break
;
case
NVDEV_ENGINE_CIPHER
:
case
NVDEV_ENGINE_SEC
:
case
NVDEV_ENGINE_VIC
:
context
|=
0x00500000
;
break
;
case
NVDEV_ENGINE_BSP
:
case
NVDEV_ENGINE_MSVLD
:
context
|=
0x00600000
;
break
;
default:
return
-
EINVAL
;
}
switch
(
object
->
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
=
0x00100000
;
break
;
case
NVDEV_ENGINE_MPEG
:
case
NVDEV_ENGINE_MSPPP
:
context
=
0x00200000
;
break
;
case
NVDEV_ENGINE_ME
:
case
NVDEV_ENGINE_CE0
:
context
=
0x00300000
;
break
;
case
NVDEV_ENGINE_VP
:
case
NVDEV_ENGINE_MSPDEC
:
context
=
0x00400000
;
break
;
case
NVDEV_ENGINE_CIPHER
:
case
NVDEV_ENGINE_SEC
:
case
NVDEV_ENGINE_VIC
:
context
=
0x00500000
;
break
;
case
NVDEV_ENGINE_BSP
:
case
NVDEV_ENGINE_MSVLD
:
context
=
0x00600000
;
break
;
default:
WARN_ON
(
1
);
return
-
EINVAL
;
}
return
nvkm_ramht_insert
(
chan
->
ramht
,
NULL
,
0
,
0
,
handle
,
context
);
return
nvkm_ramht_insert
(
chan
->
ramht
,
object
,
0
,
4
,
handle
,
context
);
}
int
g84_fifo_chan_init
(
struct
nvkm_
object
*
object
)
static
void
g84_fifo_chan_init
(
struct
nvkm_
fifo_chan
*
base
)
{
struct
nv50_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
object
->
parent
;
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_gpuobj
*
ramfc
=
base
->
ramfc
;
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
struct
nv50_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u64
addr
=
chan
->
ramfc
->
addr
>>
8
;
u32
chid
=
chan
->
base
.
chid
;
int
ret
;
ret
=
nvkm_fifo_channel_init
(
&
chan
->
base
);
if
(
ret
)
return
ret
;
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
|
ramfc
->
addr
>>
8
);
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
|
addr
);
nv50_fifo_runlist_update
(
fifo
);
return
0
;
}
static
int
g84_fifo_context_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
static
const
struct
nvkm_fifo_chan_func
g84_fifo_chan_func
=
{
.
dtor
=
nv50_fifo_chan_dtor
,
.
init
=
g84_fifo_chan_init
,
.
fini
=
nv50_fifo_chan_fini
,
.
ntfy
=
g84_fifo_chan_ntfy
,
.
engine_ctor
=
g84_fifo_chan_engine_ctor
,
.
engine_dtor
=
nv50_fifo_chan_engine_dtor
,
.
engine_init
=
g84_fifo_chan_engine_init
,
.
engine_fini
=
g84_fifo_chan_engine_fini
,
.
object_ctor
=
g84_fifo_chan_object_ctor
,
.
object_dtor
=
nv50_fifo_chan_object_dtor
,
};
int
g84_fifo_chan_ctor
(
struct
nv50_fifo
*
fifo
,
u64
vm
,
u64
push
,
const
struct
nvkm_oclass
*
oclass
,
struct
nv50_fifo_chan
*
chan
)
{
struct
nvkm_device
*
device
=
nv_engine
(
engine
)
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x10000
,
0x1000
,
NVOBJ_FLAG_HEAP
,
&
base
);
*
pobject
=
nv_object
(
base
);
ret
=
nvkm_fifo_chan_ctor
(
&
g84_fifo_chan_func
,
&
fifo
->
base
,
0x10000
,
0x1000
,
false
,
vm
,
push
,
(
1ULL
<<
NVDEV_ENGINE_BSP
)
|
(
1ULL
<<
NVDEV_ENGINE_CE0
)
|
(
1ULL
<<
NVDEV_ENGINE_CIPHER
)
|
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_ME
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPDEC
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPPP
)
|
(
1ULL
<<
NVDEV_ENGINE_MSVLD
)
|
(
1ULL
<<
NVDEV_ENGINE_SEC
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_VIC
)
|
(
1ULL
<<
NVDEV_ENGINE_VP
),
0
,
0xc00000
,
0x2000
,
oclass
,
&
chan
->
base
);
chan
->
fifo
=
fifo
;
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x0200
,
0
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
eng
);
ret
=
nvkm_gpuobj_new
(
device
,
0x0200
,
0
,
true
,
chan
->
base
.
inst
,
&
chan
->
eng
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x4000
,
0
,
false
,
&
base
->
base
.
gpuobj
,
&
base
->
pgd
);
ret
=
nvkm_gpuobj_new
(
device
,
0x4000
,
0
,
false
,
chan
->
base
.
inst
,
&
chan
->
pgd
);
if
(
ret
)
return
ret
;
ret
=
nvkm_vm_ref
(
nvkm_client
(
parent
)
->
vm
,
&
base
->
vm
,
base
->
pgd
);
ret
=
nvkm_gpuobj_new
(
device
,
0x1000
,
0x400
,
true
,
chan
->
base
.
inst
,
&
chan
->
cache
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x100
0
,
0x400
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
cache
);
ret
=
nvkm_gpuobj_new
(
device
,
0x100
,
0x100
,
true
,
chan
->
base
.
inst
,
&
chan
->
ramfc
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x100
,
0x100
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
ramfc
);
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
chan
->
base
.
inst
,
&
chan
->
ramht
);
if
(
ret
)
return
ret
;
return
0
;
return
nvkm_vm_ref
(
chan
->
base
.
vm
,
&
chan
->
vm
,
chan
->
pgd
)
;
}
struct
nvkm_oclass
g84_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0x84
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
g84_fifo_context_ctor
,
.
dtor
=
nv50_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
},
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h
View file @
8f0649b5
#ifndef __GF100_FIFO_CHAN_H__
#define __GF100_FIFO_CHAN_H__
#define gf100_fifo_chan(p) container_of((p), struct gf100_fifo_chan, base)
#include "chan.h"
#include "gf100.h"
struct
gf100_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
gf100_fifo_chan
{
struct
nvkm_fifo_chan
base
;
struct
gf100_fifo
*
fifo
;
struct
list_head
head
;
bool
killed
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_vm
*
vm
;
};
struct
gf100_fifo_chan
{
struct
nvkm_fifo_chan
base
;
enum
{
STOPPED
,
RUNNING
,
KILLED
}
state
;
struct
{
struct
nvkm_gpuobj
*
inst
;
struct
nvkm_vma
vma
;
}
engn
[
NVDEV_SUBDEV_NR
];
};
extern
struct
nvkm_oclass
gf100_fifo_cclass
;
extern
struct
nvkm_oclass
gf100_fifo_sclass
[];
extern
const
struct
nvkm_fifo_chan_oclass
gf100_fifo_gpfifo_oclass
;
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h
View file @
8f0649b5
#ifndef __GK104_FIFO_CHAN_H__
#define __GK104_FIFO_CHAN_H__
#define gk104_fifo_chan(p) container_of((p), struct gk104_fifo_chan, base)
#include "chan.h"
#include "gk104.h"
struct
gk104_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
gk104_fifo_chan
{
struct
nvkm_fifo_chan
base
;
struct
gk104_fifo
*
fifo
;
int
engine
;
struct
list_head
head
;
bool
killed
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_vm
*
vm
;
};
struct
gk104_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
engine
;
enum
{
STOPPED
,
RUNNING
,
KILLED
}
state
;
struct
{
struct
nvkm_gpuobj
*
inst
;
struct
nvkm_vma
vma
;
}
engn
[
NVDEV_SUBDEV_NR
];
};
extern
struct
nvkm_oclass
gk104_fifo_cclass
;
extern
struct
nvkm_oclass
gk104_fifo_sclass
[];
extern
struct
nvkm_ofuncs
gk104_fifo_chan_ofuncs
;
int
gk104_fifo_gpfifo_new
(
struct
nvkm_fifo
*
,
const
struct
nvkm_oclass
*
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
);
extern
struct
nvkm_oclass
gm204_fifo_sclass
[];
extern
const
struct
nvkm_fifo_chan_oclass
gk104_fifo_gpfifo_oclass
;
extern
const
struct
nvkm_fifo_chan_oclass
gm204_fifo_gpfifo_oclass
;
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv04.h
View file @
8f0649b5
#ifndef __NV04_FIFO_CHAN_H__
#define __NV04_FIFO_CHAN_H__
#define nv04_fifo_chan(p) container_of((p), struct nv04_fifo_chan, base)
#include "chan.h"
#include "nv04.h"
struct
nv04_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
subc
[
8
]
;
struct
nv04_fifo
*
fifo
;
u32
ramfc
;
struct
nvkm_gpuobj
*
engn
[
NVDEV_SUBDEV_NR
];
};
int
nv04_fifo_object_attach
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
u32
);
void
nv04_fifo_object_detach
(
struct
nvkm_object
*
,
int
);
extern
const
struct
nvkm_fifo_chan_func
nv04_fifo_dma_func
;
void
*
nv04_fifo_dma_dtor
(
struct
nvkm_fifo_chan
*
);
void
nv04_fifo_dma_init
(
struct
nvkm_fifo_chan
*
);
void
nv04_fifo_dma_fini
(
struct
nvkm_fifo_chan
*
);
void
nv04_fifo_dma_object_dtor
(
struct
nvkm_fifo_chan
*
,
int
);
void
nv04_fifo_chan_dtor
(
struct
nvkm_object
*
);
int
nv04_fifo_chan_init
(
struct
nvkm_object
*
);
int
nv04_fifo_chan_fini
(
struct
nvkm_object
*
,
bool
suspend
);
extern
struct
nvkm_oclass
nv04_fifo_cclass
;
extern
struct
nvkm_oclass
nv04_fifo_sclass
[];
extern
struct
nvkm_oclass
nv10_fifo_sclass
[];
extern
struct
nvkm_oclass
nv17_fifo_sclass
[];
extern
struct
nvkm_oclass
nv40_fifo_sclass
[];
extern
const
struct
nvkm_fifo_chan_oclass
nv04_fifo_dma_oclass
;
extern
const
struct
nvkm_fifo_chan_oclass
nv10_fifo_dma_oclass
;
extern
const
struct
nvkm_fifo_chan_oclass
nv17_fifo_dma_oclass
;
extern
const
struct
nvkm_fifo_chan_oclass
nv40_fifo_dma_oclass
;
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c
View file @
8f0649b5
...
...
@@ -25,27 +25,37 @@
#include <core/client.h>
#include <core/ramht.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
int
nv50_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
static
int
nv50_fifo_chan_engine_addr
(
struct
nvkm_engine
*
engine
)
{
struct
nv50_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
switch
(
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
return
-
1
;
case
NVDEV_ENGINE_GR
:
return
0x0000
;
case
NVDEV_ENGINE_MPEG
:
return
0x0060
;
default:
WARN_ON
(
1
);
return
-
1
;
}
}
static
int
nv50_fifo_chan_engine_fini
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
bool
suspend
)
{
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
struct
nv50_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
u32
addr
,
me
;
int
ret
=
0
;
int
offset
,
ret
=
0
;
u32
me
;
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
addr
=
0x0000
;
break
;
case
NVDEV_ENGINE_MPEG
:
addr
=
0x0060
;
break
;
default:
return
-
EINVAL
;
}
offset
=
nv50_fifo_chan_engine_addr
(
engine
);
if
(
offset
<
0
)
return
0
;
/* HW bug workaround:
*
...
...
@@ -62,101 +72,124 @@ nv50_fifo_context_detach(struct nvkm_object *parent, bool suspend,
me
=
nvkm_mask
(
device
,
0x00b860
,
0x00000001
,
0x00000001
);
/* do the kickoff... */
nvkm_wr32
(
device
,
0x0032fc
,
nv_gpuobj
(
base
)
->
addr
>>
12
);
nvkm_wr32
(
device
,
0x0032fc
,
chan
->
base
.
inst
->
addr
>>
12
);
if
(
nvkm_msec
(
device
,
2000
,
if
(
nvkm_rd32
(
device
,
0x0032fc
)
!=
0xffffffff
)
break
;
)
<
0
)
{
nvkm_error
(
subdev
,
"channel %d [%s] unload timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
)
);
chan
->
base
.
chid
,
chan
->
base
.
object
.
client
->
name
);
if
(
suspend
)
ret
=
-
EBUSY
;
}
nvkm_wr32
(
device
,
0x00b860
,
me
);
if
(
ret
==
0
)
{
nvkm_kmap
(
base
->
eng
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x00
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x04
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x08
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x0c
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x10
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x14
,
0x00000000
);
nvkm_done
(
base
->
eng
);
nvkm_kmap
(
chan
->
eng
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x00
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x04
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x08
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x0c
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x10
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x14
,
0x00000000
);
nvkm_done
(
chan
->
eng
);
}
return
ret
;
}
int
nv50_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
static
int
nv50_fifo_chan_engine_init
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
nvkm_gpuobj
*
ectx
=
(
void
*
)
object
;
u64
limit
=
ectx
->
addr
+
ectx
->
size
-
1
;
u64
start
=
ectx
->
addr
;
u32
addr
;
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
addr
=
0x0000
;
break
;
case
NVDEV_ENGINE_MPEG
:
addr
=
0x0060
;
break
;
default:
return
-
EINVAL
;
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
struct
nvkm_gpuobj
*
engn
=
chan
->
engn
[
engine
->
subdev
.
index
];
u64
limit
,
start
;
int
offset
;
offset
=
nv50_fifo_chan_engine_addr
(
engine
);
if
(
offset
<
0
)
return
0
;
limit
=
engn
->
addr
+
engn
->
size
-
1
;
start
=
engn
->
addr
;
nvkm_kmap
(
chan
->
eng
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x00
,
0x00190000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x04
,
lower_32_bits
(
limit
));
nvkm_wo32
(
chan
->
eng
,
offset
+
0x08
,
lower_32_bits
(
start
));
nvkm_wo32
(
chan
->
eng
,
offset
+
0x0c
,
upper_32_bits
(
limit
)
<<
24
|
upper_32_bits
(
start
));
nvkm_wo32
(
chan
->
eng
,
offset
+
0x10
,
0x00000000
);
nvkm_wo32
(
chan
->
eng
,
offset
+
0x14
,
0x00000000
);
nvkm_done
(
chan
->
eng
);
return
0
;
}
void
nv50_fifo_chan_engine_dtor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
if
(
!
chan
->
engn
[
engine
->
subdev
.
index
]
||
chan
->
engn
[
engine
->
subdev
.
index
]
->
object
.
oclass
)
{
chan
->
engn
[
engine
->
subdev
.
index
]
=
NULL
;
return
;
}
nvkm_gpuobj_del
(
&
chan
->
engn
[
engine
->
subdev
.
index
]);
}
nv_engctx
(
ectx
)
->
addr
=
nv_gpuobj
(
base
)
->
addr
>>
12
;
nvkm_kmap
(
base
->
eng
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x00
,
0x00190000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x04
,
lower_32_bits
(
limit
));
nvkm_wo32
(
base
->
eng
,
addr
+
0x08
,
lower_32_bits
(
start
));
nvkm_wo32
(
base
->
eng
,
addr
+
0x0c
,
upper_32_bits
(
limit
)
<<
24
|
upper_32_bits
(
start
));
nvkm_wo32
(
base
->
eng
,
addr
+
0x10
,
0x00000000
);
nvkm_wo32
(
base
->
eng
,
addr
+
0x14
,
0x00000000
);
nvkm_done
(
base
->
eng
);
return
0
;
static
int
nv50_fifo_chan_engine_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
struct
nvkm_object
*
object
)
{
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
int
engn
=
engine
->
subdev
.
index
;
if
(
nv50_fifo_chan_engine_addr
(
engine
)
<
0
)
return
0
;
if
(
nv_iclass
(
object
,
NV_GPUOBJ_CLASS
))
{
chan
->
engn
[
engn
]
=
nv_gpuobj
(
object
);
return
0
;
}
return
nvkm_object_bind
(
object
,
NULL
,
0
,
&
chan
->
engn
[
engn
]);
}
void
nv50_fifo_
object_detach
(
struct
nvkm_object
*
parent
,
int
cookie
)
nv50_fifo_
chan_object_dtor
(
struct
nvkm_fifo_chan
*
base
,
int
cookie
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
)
;
nvkm_ramht_remove
(
chan
->
ramht
,
cookie
);
}
int
nv50_fifo_
object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
static
int
nv50_fifo_
chan_object_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_object
*
object
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
u32
handle
=
object
->
handle
;
u32
context
;
if
(
nv_iclass
(
object
,
NV_GPUOBJ_CLASS
))
context
=
nv_gpuobj
(
object
)
->
node
->
offset
>>
4
;
else
context
=
0x00000004
;
/* just non-zero */
if
(
object
->
engine
)
{
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
|=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
|=
0x00100000
;
break
;
case
NVDEV_ENGINE_MPEG
:
context
|=
0x00200000
;
break
;
default:
return
-
EINVAL
;
}
switch
(
object
->
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
=
0x00100000
;
break
;
case
NVDEV_ENGINE_MPEG
:
context
=
0x00200000
;
break
;
default:
WARN_ON
(
1
);
return
-
EINVAL
;
}
return
nvkm_ramht_insert
(
chan
->
ramht
,
NULL
,
0
,
0
,
handle
,
context
);
return
nvkm_ramht_insert
(
chan
->
ramht
,
object
,
0
,
4
,
handle
,
context
);
}
int
nv50_fifo_chan_fini
(
struct
nvkm_
object
*
object
,
bool
suspend
)
void
nv50_fifo_chan_fini
(
struct
nvkm_
fifo_chan
*
base
)
{
struct
nv50_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv50_fifo
_chan
*
chan
=
(
void
*
)
object
;
struct
nv50_fifo
_chan
*
chan
=
nv50_fifo_chan
(
base
)
;
struct
nv50_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
...
...
@@ -164,96 +197,84 @@ nv50_fifo_chan_fini(struct nvkm_object *object, bool suspend)
nvkm_mask
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
,
0x00000000
);
nv50_fifo_runlist_update
(
fifo
);
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x00000000
);
return
nvkm_fifo_channel_fini
(
&
chan
->
base
,
suspend
);
}
int
nv50_fifo_chan_init
(
struct
nvkm_
object
*
object
)
static
void
nv50_fifo_chan_init
(
struct
nvkm_
fifo_chan
*
base
)
{
struct
nv50_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
object
->
parent
;
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_gpuobj
*
ramfc
=
base
->
ramfc
;
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
struct
nv50_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u64
addr
=
chan
->
ramfc
->
addr
>>
12
;
u32
chid
=
chan
->
base
.
chid
;
int
ret
;
ret
=
nvkm_fifo_channel_init
(
&
chan
->
base
);
if
(
ret
)
return
ret
;
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
|
ramfc
->
addr
>>
12
);
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
|
addr
);
nv50_fifo_runlist_update
(
fifo
);
return
0
;
}
void
nv50_fifo_chan_dtor
(
struct
nvkm_
object
*
object
)
void
*
nv50_fifo_chan_dtor
(
struct
nvkm_
fifo_chan
*
base
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nv50_fifo_chan
*
chan
=
nv50_fifo_chan
(
base
);
nvkm_vm_ref
(
NULL
,
&
chan
->
vm
,
chan
->
pgd
);
nvkm_ramht_del
(
&
chan
->
ramht
);
nvkm_fifo_channel_destroy
(
&
chan
->
base
);
nvkm_gpuobj_del
(
&
chan
->
pgd
);
nvkm_gpuobj_del
(
&
chan
->
eng
);
nvkm_gpuobj_del
(
&
chan
->
cache
);
nvkm_gpuobj_del
(
&
chan
->
ramfc
);
return
chan
;
}
void
nv50_fifo_context_dtor
(
struct
nvkm_object
*
object
)
{
struct
nv50_fifo_base
*
base
=
(
void
*
)
object
;
nvkm_vm_ref
(
NULL
,
&
base
->
vm
,
base
->
pgd
);
nvkm_gpuobj_del
(
&
base
->
pgd
);
nvkm_gpuobj_del
(
&
base
->
eng
);
nvkm_gpuobj_del
(
&
base
->
ramfc
);
nvkm_gpuobj_del
(
&
base
->
cache
);
nvkm_fifo_context_destroy
(
&
base
->
base
);
}
static
const
struct
nvkm_fifo_chan_func
nv50_fifo_chan_func
=
{
.
dtor
=
nv50_fifo_chan_dtor
,
.
init
=
nv50_fifo_chan_init
,
.
fini
=
nv50_fifo_chan_fini
,
.
engine_ctor
=
nv50_fifo_chan_engine_ctor
,
.
engine_dtor
=
nv50_fifo_chan_engine_dtor
,
.
engine_init
=
nv50_fifo_chan_engine_init
,
.
engine_fini
=
nv50_fifo_chan_engine_fini
,
.
object_ctor
=
nv50_fifo_chan_object_ctor
,
.
object_dtor
=
nv50_fifo_chan_object_dtor
,
};
static
int
nv50_fifo_c
ontext_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
int
nv50_fifo_c
han_ctor
(
struct
nv50_fifo
*
fifo
,
u64
vm
,
u64
push
,
const
struct
nvkm_oclass
*
oclass
,
struct
nv50_fifo_chan
*
chan
)
{
struct
nvkm_device
*
device
=
nv_engine
(
engine
)
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x10000
,
0x1000
,
NVOBJ_FLAG_HEAP
,
&
base
);
*
pobject
=
nv_object
(
base
);
ret
=
nvkm_fifo_chan_ctor
(
&
nv50_fifo_chan_func
,
&
fifo
->
base
,
0x10000
,
0x1000
,
false
,
vm
,
push
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
),
0
,
0xc00000
,
0x2000
,
oclass
,
&
chan
->
base
);
chan
->
fifo
=
fifo
;
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x0200
,
0x1000
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
ramfc
);
ret
=
nvkm_gpuobj_new
(
device
,
0x0200
,
0x1000
,
true
,
chan
->
base
.
inst
,
&
chan
->
ramfc
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x1200
,
0
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
eng
);
ret
=
nvkm_gpuobj_new
(
device
,
0x1200
,
0
,
true
,
chan
->
base
.
inst
,
&
chan
->
eng
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x4000
,
0
,
false
,
&
base
->
base
.
gpuobj
,
&
base
->
pgd
);
ret
=
nvkm_gpuobj_new
(
device
,
0x4000
,
0
,
false
,
chan
->
base
.
inst
,
&
chan
->
pgd
);
if
(
ret
)
return
ret
;
ret
=
nvkm_
vm_ref
(
nvkm_client
(
parent
)
->
vm
,
&
base
->
vm
,
base
->
pgd
);
ret
=
nvkm_
ramht_new
(
device
,
0x8000
,
16
,
chan
->
base
.
inst
,
&
chan
->
ramht
);
if
(
ret
)
return
ret
;
return
0
;
return
nvkm_vm_ref
(
chan
->
base
.
vm
,
&
chan
->
vm
,
chan
->
pgd
)
;
}
struct
nvkm_oclass
nv50_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0x50
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
nv50_fifo_context_ctor
,
.
dtor
=
nv50_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
},
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h
View file @
8f0649b5
#ifndef __NV50_FIFO_CHAN_H__
#define __NV50_FIFO_CHAN_H__
#define nv50_fifo_chan(p) container_of((p), struct nv50_fifo_chan, base)
#include "chan.h"
#include "nv50.h"
struct
nv50_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
nv50_fifo_chan
{
struct
nv50_fifo
*
fifo
;
struct
nvkm_fifo_chan
base
;
struct
nvkm_gpuobj
*
ramfc
;
struct
nvkm_gpuobj
*
cache
;
struct
nvkm_gpuobj
*
eng
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_ramht
*
ramht
;
struct
nvkm_vm
*
vm
;
};
struct
nv50_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
subc
[
8
];
struct
nvkm_ramht
*
ramht
;
struct
nvkm_gpuobj
*
engn
[
NVDEV_SUBDEV_NR
];
};
extern
struct
nvkm_oclass
nv50_fifo_cclass
;
extern
struct
nvkm_oclass
nv50_fifo_sclass
[];
void
nv50_fifo_context_dtor
(
struct
nvkm_object
*
);
void
nv50_fifo_chan_dtor
(
struct
nvkm_object
*
);
int
nv50_fifo_chan_init
(
struct
nvkm_object
*
);
int
nv50_fifo_chan_fini
(
struct
nvkm_object
*
,
bool
);
int
nv50_fifo_context_attach
(
struct
nvkm_object
*
,
struct
nvkm_object
*
);
int
nv50_fifo_context_detach
(
struct
nvkm_object
*
,
bool
,
struct
nvkm_object
*
);
int
nv50_fifo_object_attach
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
u32
);
void
nv50_fifo_object_detach
(
struct
nvkm_object
*
,
int
);
extern
struct
nvkm_ofuncs
nv50_fifo_ofuncs_ind
;
int
nv50_fifo_chan_ctor
(
struct
nv50_fifo
*
,
u64
vm
,
u64
push
,
const
struct
nvkm_oclass
*
,
struct
nv50_fifo_chan
*
);
void
*
nv50_fifo_chan_dtor
(
struct
nvkm_fifo_chan
*
);
void
nv50_fifo_chan_fini
(
struct
nvkm_fifo_chan
*
);
void
nv50_fifo_chan_engine_dtor
(
struct
nvkm_fifo_chan
*
,
struct
nvkm_engine
*
);
void
nv50_fifo_chan_object_dtor
(
struct
nvkm_fifo_chan
*
,
int
);
int
g84_fifo_chan_ctor
(
struct
nv50_fifo
*
,
u64
vm
,
u64
push
,
const
struct
nvkm_oclass
*
,
struct
nv50_fifo_chan
*
);
extern
struct
nvkm_oclass
g84_fifo_cclass
;
extern
struct
nvkm_oclass
g84_fifo_sclass
[];
int
g84_fifo_chan_init
(
struct
nvkm_object
*
);
int
g84_fifo_context_attach
(
struct
nvkm_object
*
,
struct
nvkm_object
*
);
int
g84_fifo_context_detach
(
struct
nvkm_object
*
,
bool
,
struct
nvkm_object
*
);
int
g84_fifo_object_attach
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
u32
);
extern
struct
nvkm_ofuncs
g84_fifo_ofuncs_ind
;
extern
const
struct
nvkm_fifo_chan_oclass
nv50_fifo_dma_oclass
;
extern
const
struct
nvkm_fifo_chan_oclass
nv50_fifo_gpfifo_oclass
;
extern
const
struct
nvkm_fifo_chan_oclass
g84_fifo_dma_oclass
;
extern
const
struct
nvkm_fifo_chan_oclass
g84_fifo_gpfifo_oclass
;
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c
View file @
8f0649b5
...
...
@@ -30,15 +30,14 @@
#include <nvif/unpack.h>
static
int
g84_fifo_chan_ctor_dma
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
g84_fifo_dma_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
nv50_channel_dma_v0
v0
;
}
*
args
=
data
;
struct
nvkm_device
*
device
=
parent
->
engine
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
;
struct
nv50_fifo
*
fifo
=
nv50_fifo
(
base
);
struct
nv50_fifo_chan
*
chan
;
int
ret
;
...
...
@@ -48,80 +47,47 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
"pushbuf %llx offset %016llx
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
args
->
v0
.
vm
)
return
-
E
NOENT
;
if
(
!
args
->
v0
.
pushbuf
)
return
-
E
INVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0xc00000
,
0x2000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
)
|
(
1ULL
<<
NVDEV_ENGINE_ME
)
|
(
1ULL
<<
NVDEV_ENGINE_VP
)
|
(
1ULL
<<
NVDEV_ENGINE_CIPHER
)
|
(
1ULL
<<
NVDEV_ENGINE_SEC
)
|
(
1ULL
<<
NVDEV_ENGINE_BSP
)
|
(
1ULL
<<
NVDEV_ENGINE_MSVLD
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPDEC
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPPP
)
|
(
1ULL
<<
NVDEV_ENGINE_CE0
)
|
(
1ULL
<<
NVDEV_ENGINE_VIC
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
ret
)
return
ret
;
chan
->
base
.
inst
=
base
->
base
.
gpuobj
.
addr
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
ret
=
g84_fifo_chan_ctor
(
fifo
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
oclass
,
chan
);
if
(
ret
)
return
ret
;
nv_parent
(
chan
)
->
context_attach
=
g84_fifo_context_attach
;
nv_parent
(
chan
)
->
context_detach
=
g84_fifo_context_detach
;
nv_parent
(
chan
)
->
object_attach
=
g84_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv50_fifo_object_detach
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nvkm_kmap
(
base
->
ramfc
);
nvkm_wo32
(
base
->
ramfc
,
0x08
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x0c
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x10
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x14
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x3c
,
0x003f6078
);
nvkm_wo32
(
base
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
base
->
ramfc
,
0x48
,
chan
->
base
.
pushgpu
->
node
->
offset
>>
4
);
nvkm_wo32
(
base
->
ramfc
,
0x4c
,
0xffffffff
);
nvkm_wo32
(
base
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
base
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
base
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
base
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
nvkm_kmap
(
chan
->
ramfc
);
nvkm_wo32
(
chan
->
ramfc
,
0x08
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x0c
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x10
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x14
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x3c
,
0x003f6078
);
nvkm_wo32
(
chan
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
chan
->
ramfc
,
0x48
,
chan
->
base
.
push
->
node
->
offset
>>
4
);
nvkm_wo32
(
chan
->
ramfc
,
0x4c
,
0xffffffff
);
nvkm_wo32
(
chan
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
chan
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
chan
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
chan
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
(
4
<<
24
)
/* SEARCH_FULL */
|
(
chan
->
ramht
->
gpuobj
->
node
->
offset
>>
4
));
nvkm_wo32
(
base
->
ramfc
,
0x88
,
base
->
cache
->
addr
>>
10
);
nvkm_wo32
(
base
->
ramfc
,
0x98
,
nv_gpuobj
(
base
)
->
addr
>>
12
);
nvkm_done
(
base
->
ramfc
);
nvkm_wo32
(
chan
->
ramfc
,
0x88
,
chan
->
cache
->
addr
>>
10
);
nvkm_wo32
(
chan
->
ramfc
,
0x98
,
chan
->
base
.
inst
->
addr
>>
12
);
nvkm_done
(
chan
->
ramfc
);
return
0
;
}
static
struct
nvkm_ofuncs
g84_fifo_ofuncs_dma
=
{
.
ctor
=
g84_fifo_chan_ctor_dma
,
.
dtor
=
nv50_fifo_chan_dtor
,
.
init
=
g84_fifo_chan_init
,
.
fini
=
nv50_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
g84_fifo_sclass
[]
=
{
{
G82_CHANNEL_DMA
,
&
g84_fifo_ofuncs_dma
},
{
G82_CHANNEL_GPFIFO
,
&
g84_fifo_ofuncs_ind
},
{}
const
struct
nvkm_fifo_chan_oclass
g84_fifo_dma_oclass
=
{
.
base
.
oclass
=
G82_CHANNEL_DMA
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
g84_fifo_dma_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
View file @
8f0649b5
...
...
@@ -31,74 +31,51 @@
#include <nvif/class.h>
#include <nvif/unpack.h>
int
nv04_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
{
nv_engctx
(
object
)
->
addr
=
nvkm_fifo_chan
(
parent
)
->
chid
;
return
0
;
}
void
nv04_fifo_
object_detach
(
struct
nvkm_object
*
parent
,
int
cookie
)
nv04_fifo_
dma_object_dtor
(
struct
nvkm_fifo_chan
*
base
,
int
cookie
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
mutex_lock
(
&
nv_subdev
(
fifo
)
->
mutex
);
struct
nv04_fifo_chan
*
chan
=
nv04_fifo_chan
(
base
);
struct
nvkm_instmem
*
imem
=
chan
->
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
nvkm_ramht_remove
(
imem
->
ramht
,
cookie
);
mutex_unlock
(
&
nv_subdev
(
fifo
)
->
mutex
);
}
int
nv04_fifo_
object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
static
int
nv04_fifo_
dma_object_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_object
*
object
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
u32
context
,
chid
=
chan
->
base
.
chid
;
int
ret
;
if
(
nv_iclass
(
object
,
NV_GPUOBJ_CLASS
))
context
=
nv_gpuobj
(
object
)
->
addr
>>
4
;
else
context
=
0x00000004
;
/* just non-zero */
if
(
object
->
engine
)
{
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
|=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
|=
0x00010000
;
break
;
case
NVDEV_ENGINE_MPEG
:
context
|=
0x00020000
;
break
;
default:
return
-
EINVAL
;
}
struct
nv04_fifo_chan
*
chan
=
nv04_fifo_chan
(
base
);
struct
nvkm_instmem
*
imem
=
chan
->
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
u32
context
=
0x80000000
|
chan
->
base
.
chid
<<
24
;
u32
handle
=
object
->
handle
;
int
hash
;
switch
(
object
->
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
|=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
|=
0x00010000
;
break
;
case
NVDEV_ENGINE_MPEG
:
context
|=
0x00020000
;
break
;
default:
WARN_ON
(
1
);
return
-
EINVAL
;
}
context
|=
0x80000000
;
/* valid */
context
|=
chid
<<
24
;
mutex_lock
(
&
nv_subdev
(
fifo
)
->
mutex
);
ret
=
nvkm_ramht_insert
(
imem
->
ramht
,
NULL
,
chid
,
0
,
handle
,
context
);
mutex_unlock
(
&
nv_subdev
(
fifo
)
->
mutex
);
return
ret
;
mutex_lock
(
&
chan
->
fifo
->
base
.
engine
.
subdev
.
mutex
);
hash
=
nvkm_ramht_insert
(
imem
->
ramht
,
object
,
chan
->
base
.
chid
,
4
,
handle
,
context
);
mutex_unlock
(
&
chan
->
fifo
->
base
.
engine
.
subdev
.
mutex
);
return
hash
;
}
int
nv04_fifo_
chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
void
nv04_fifo_
dma_fini
(
struct
nvkm_fifo_chan
*
base
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo
_chan
*
chan
=
(
void
*
)
object
;
struct
nv04_fifo
_chan
*
chan
=
nv04_fifo_chan
(
base
)
;
struct
nv04_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_memory
*
fctx
=
device
->
imem
->
ramfc
;
struct
ramfc_desc
*
c
;
unsigned
long
flags
;
u32
mask
=
fifo
->
base
.
nr
-
1
;
u32
data
=
chan
->
ramfc
;
u32
chid
;
...
...
@@ -107,7 +84,7 @@ nv04_fifo_chan_fini(struct nvkm_object *object, bool suspend)
nvkm_wr32
(
device
,
NV03_PFIFO_CACHES
,
0
);
/* if this channel is active, replace it with a null context */
chid
=
nvkm_rd32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
)
&
fifo
->
base
.
max
;
chid
=
nvkm_rd32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
)
&
mask
;
if
(
chid
==
chan
->
base
.
chid
)
{
nvkm_mask
(
device
,
NV04_PFIFO_CACHE1_DMA_PUSH
,
0x00000001
,
0
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH0
,
0
);
...
...
@@ -129,7 +106,7 @@ nv04_fifo_chan_fini(struct nvkm_object *object, bool suspend)
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_GET
,
0
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUT
,
0
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
fifo
->
base
.
max
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
mask
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH0
,
1
);
nvkm_wr32
(
device
,
NV04_PFIFO_CACHE1_PULL0
,
1
);
}
...
...
@@ -138,35 +115,26 @@ nv04_fifo_chan_fini(struct nvkm_object *object, bool suspend)
nvkm_mask
(
device
,
NV04_PFIFO_MODE
,
1
<<
chan
->
base
.
chid
,
0
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHES
,
1
);
spin_unlock_irqrestore
(
&
fifo
->
base
.
lock
,
flags
);
return
nvkm_fifo_channel_fini
(
&
chan
->
base
,
suspend
);
}
int
nv04_fifo_
chan_init
(
struct
nvkm_object
*
object
)
void
nv04_fifo_
dma_init
(
struct
nvkm_fifo_chan
*
base
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo
_chan
*
chan
=
(
void
*
)
object
;
struct
nv04_fifo
_chan
*
chan
=
nv04_fifo_chan
(
base
)
;
struct
nv04_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
mask
=
1
<<
chan
->
base
.
chid
;
unsigned
long
flags
;
int
ret
;
ret
=
nvkm_fifo_channel_init
(
&
chan
->
base
);
if
(
ret
)
return
ret
;
spin_lock_irqsave
(
&
fifo
->
base
.
lock
,
flags
);
nvkm_mask
(
device
,
NV04_PFIFO_MODE
,
mask
,
mask
);
spin_unlock_irqrestore
(
&
fifo
->
base
.
lock
,
flags
);
return
0
;
}
void
nv04_fifo_
chan_dtor
(
struct
nvkm_object
*
object
)
void
*
nv04_fifo_
dma_dtor
(
struct
nvkm_fifo_chan
*
base
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo
_chan
*
chan
=
(
void
*
)
object
;
struct
nv04_fifo
_chan
*
chan
=
nv04_fifo_chan
(
base
)
;
struct
nv04_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
struct
ramfc_desc
*
c
=
fifo
->
ramfc_desc
;
...
...
@@ -175,22 +143,30 @@ nv04_fifo_chan_dtor(struct nvkm_object *object)
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
c
->
ctxp
,
0x00000000
);
}
while
((
++
c
)
->
bits
);
nvkm_done
(
imem
->
ramfc
);
nvkm_fifo_channel_destroy
(
&
chan
->
base
);
return
chan
;
}
const
struct
nvkm_fifo_chan_func
nv04_fifo_dma_func
=
{
.
dtor
=
nv04_fifo_dma_dtor
,
.
init
=
nv04_fifo_dma_init
,
.
fini
=
nv04_fifo_dma_fini
,
.
object_ctor
=
nv04_fifo_dma_object_ctor
,
.
object_dtor
=
nv04_fifo_dma_object_dtor
,
};
static
int
nv04_fifo_chan_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
nv04_fifo_dma_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
nv03_channel_dma_v0
v0
;
}
*
args
=
data
;
struct
nv04_fifo
*
fifo
=
(
void
*
)
engine
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
struct
nv04_fifo_chan
*
chan
;
struct
nv04_fifo
*
fifo
=
nv04_fifo
(
base
);
struct
nv04_fifo_chan
*
chan
=
NULL
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
...
...
@@ -198,29 +174,32 @@ nv04_fifo_chan_ctor(struct nvkm_object *parent,
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
!
args
->
v0
.
pushbuf
)
return
-
EINVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0x800000
,
0x10000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nvkm_fifo_chan_ctor
(
&
nv04_fifo_dma_func
,
&
fifo
->
base
,
0x1000
,
0x1000
,
false
,
0
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
),
0
,
0x800000
,
0x10000
,
oclass
,
&
chan
->
base
);
chan
->
fifo
=
fifo
;
if
(
ret
)
return
ret
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
object_attach
=
nv04_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv04_fifo_object_detach
;
nv_parent
(
chan
)
->
context_attach
=
nv04_fifo_context_attach
;
chan
->
ramfc
=
chan
->
base
.
chid
*
32
;
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x00
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x04
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x08
,
chan
->
base
.
push
gpu
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x08
,
chan
->
base
.
push
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x10
,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES
|
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES
|
...
...
@@ -232,51 +211,10 @@ nv04_fifo_chan_ctor(struct nvkm_object *parent,
return
0
;
}
static
struct
nvkm_ofuncs
nv04_fifo_ofuncs
=
{
.
ctor
=
nv04_fifo_chan_ctor
,
.
dtor
=
nv04_fifo_chan_dtor
,
.
init
=
nv04_fifo_chan_init
,
.
fini
=
nv04_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
nv04_fifo_sclass
[]
=
{
{
NV03_CHANNEL_DMA
,
&
nv04_fifo_ofuncs
},
{}
};
int
nv04_fifo_context_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nv04_fifo_base
*
base
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x1000
,
0x1000
,
NVOBJ_FLAG_HEAP
,
&
base
);
*
pobject
=
nv_object
(
base
);
if
(
ret
)
return
ret
;
return
0
;
}
struct
nvkm_oclass
nv04_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0x04
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
nv04_fifo_context_ctor
,
.
dtor
=
_nvkm_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
},
const
struct
nvkm_fifo_chan_oclass
nv04_fifo_dma_oclass
=
{
.
base
.
oclass
=
NV03_CHANNEL_DMA
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
nv04_fifo_dma_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.c
View file @
8f0649b5
...
...
@@ -31,17 +31,17 @@
#include <nvif/unpack.h>
static
int
nv10_fifo_chan_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
nv10_fifo_dma_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
nv03_channel_dma_v0
v0
;
}
*
args
=
data
;
struct
nv04_fifo
*
fifo
=
(
void
*
)
engine
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
struct
nv04_fifo_chan
*
chan
;
struct
nv04_fifo
*
fifo
=
nv04_fifo
(
base
);
struct
nv04_fifo_chan
*
chan
=
NULL
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
...
...
@@ -49,29 +49,32 @@ nv10_fifo_chan_ctor(struct nvkm_object *parent,
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
!
args
->
v0
.
pushbuf
)
return
-
EINVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0x800000
,
0x10000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nvkm_fifo_chan_ctor
(
&
nv04_fifo_dma_func
,
&
fifo
->
base
,
0x1000
,
0x1000
,
false
,
0
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
),
0
,
0x800000
,
0x10000
,
oclass
,
&
chan
->
base
);
chan
->
fifo
=
fifo
;
if
(
ret
)
return
ret
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
object_attach
=
nv04_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv04_fifo_object_detach
;
nv_parent
(
chan
)
->
context_attach
=
nv04_fifo_context_attach
;
chan
->
ramfc
=
chan
->
base
.
chid
*
32
;
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x00
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x04
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x0c
,
chan
->
base
.
push
gpu
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x0c
,
chan
->
base
.
push
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x14
,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES
|
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES
|
...
...
@@ -83,20 +86,10 @@ nv10_fifo_chan_ctor(struct nvkm_object *parent,
return
0
;
}
static
struct
nvkm_ofuncs
nv10_fifo_ofuncs
=
{
.
ctor
=
nv10_fifo_chan_ctor
,
.
dtor
=
nv04_fifo_chan_dtor
,
.
init
=
nv04_fifo_chan_init
,
.
fini
=
nv04_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
nv10_fifo_sclass
[]
=
{
{
NV10_CHANNEL_DMA
,
&
nv10_fifo_ofuncs
},
{}
const
struct
nvkm_fifo_chan_oclass
nv10_fifo_dma_oclass
=
{
.
base
.
oclass
=
NV10_CHANNEL_DMA
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
nv10_fifo_dma_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.c
View file @
8f0649b5
...
...
@@ -31,17 +31,17 @@
#include <nvif/unpack.h>
static
int
nv17_fifo_chan_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
nv17_fifo_dma_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
nv03_channel_dma_v0
v0
;
}
*
args
=
data
;
struct
nv04_fifo
*
fifo
=
(
void
*
)
engine
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
struct
nv04_fifo_chan
*
chan
;
struct
nv04_fifo
*
fifo
=
nv04_fifo
(
base
);
struct
nv04_fifo_chan
*
chan
=
NULL
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
...
...
@@ -49,31 +49,33 @@ nv17_fifo_chan_ctor(struct nvkm_object *parent,
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
!
args
->
v0
.
pushbuf
)
return
-
EINVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0x800000
,
0x10000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
),
/* NV31- */
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nvkm_fifo_chan_ctor
(
&
nv04_fifo_dma_func
,
&
fifo
->
base
,
0x1000
,
0x1000
,
false
,
0
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
)
|
/* NV31- */
(
1ULL
<<
NVDEV_ENGINE_SW
),
0
,
0x800000
,
0x10000
,
oclass
,
&
chan
->
base
);
chan
->
fifo
=
fifo
;
if
(
ret
)
return
ret
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
object_attach
=
nv04_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv04_fifo_object_detach
;
nv_parent
(
chan
)
->
context_attach
=
nv04_fifo_context_attach
;
chan
->
ramfc
=
chan
->
base
.
chid
*
64
;
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x00
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x04
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x0c
,
chan
->
base
.
push
gpu
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x0c
,
chan
->
base
.
push
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x14
,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES
|
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES
|
...
...
@@ -85,20 +87,10 @@ nv17_fifo_chan_ctor(struct nvkm_object *parent,
return
0
;
}
static
struct
nvkm_ofuncs
nv17_fifo_ofuncs
=
{
.
ctor
=
nv17_fifo_chan_ctor
,
.
dtor
=
nv04_fifo_chan_dtor
,
.
init
=
nv04_fifo_chan_init
,
.
fini
=
nv04_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
nv17_fifo_sclass
[]
=
{
{
NV17_CHANNEL_DMA
,
&
nv17_fifo_ofuncs
},
{}
const
struct
nvkm_fifo_chan_oclass
nv17_fifo_dma_oclass
=
{
.
base
.
oclass
=
NV17_CHANNEL_DMA
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
nv17_fifo_dma_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.c
View file @
8f0649b5
...
...
@@ -31,36 +31,47 @@
#include <nvif/class.h>
#include <nvif/unpack.h>
static
bool
nv40_fifo_dma_engine
(
struct
nvkm_engine
*
engine
,
u32
*
reg
,
u32
*
ctx
)
{
switch
(
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
return
false
;
case
NVDEV_ENGINE_GR
:
*
reg
=
0x0032e0
;
*
ctx
=
0x38
;
return
true
;
case
NVDEV_ENGINE_MPEG
:
*
reg
=
0x00330c
;
*
ctx
=
0x54
;
return
true
;
default:
WARN_ON
(
1
);
return
false
;
}
}
static
int
nv40_fifo_
context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
engctx
)
nv40_fifo_
dma_engine_fini
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
bool
suspend
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv04_fifo
_chan
*
chan
=
(
void
*
)
parent
;
struct
nv04_fifo
_chan
*
chan
=
nv04_fifo_chan
(
base
)
;
struct
nv04_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
unsigned
long
flags
;
u32
reg
,
ctx
;
int
chid
;
switch
(
nv_engidx
(
engctx
->
engine
))
{
case
NVDEV_ENGINE_SW
:
if
(
!
nv40_fifo_dma_engine
(
engine
,
&
reg
,
&
ctx
))
return
0
;
case
NVDEV_ENGINE_GR
:
reg
=
0x32e0
;
ctx
=
0x38
;
break
;
case
NVDEV_ENGINE_MPEG
:
reg
=
0x330c
;
ctx
=
0x54
;
break
;
default:
return
-
EINVAL
;
}
spin_lock_irqsave
(
&
fifo
->
base
.
lock
,
flags
);
nvkm_mask
(
device
,
0x002500
,
0x00000001
,
0x00000000
);
if
((
nvkm_rd32
(
device
,
0x003204
)
&
fifo
->
base
.
max
)
==
chan
->
base
.
chid
)
chid
=
nvkm_rd32
(
device
,
0x003204
)
&
(
fifo
->
base
.
nr
-
1
);
if
(
chid
==
chan
->
base
.
chid
)
nvkm_wr32
(
device
,
reg
,
0x00000000
);
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
ctx
,
0x00000000
);
...
...
@@ -72,38 +83,29 @@ nv40_fifo_context_detach(struct nvkm_object *parent, bool suspend,
}
static
int
nv40_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engctx
)
nv40_fifo_dma_engine_init
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv04_fifo
_chan
*
chan
=
(
void
*
)
parent
;
struct
nv04_fifo
_chan
*
chan
=
nv04_fifo_chan
(
base
)
;
struct
nv04_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
unsigned
long
flags
;
u32
reg
,
ctx
;
u32
inst
,
reg
,
ctx
;
int
chid
;
switch
(
nv_engidx
(
engctx
->
engine
))
{
case
NVDEV_ENGINE_SW
:
if
(
!
nv40_fifo_dma_engine
(
engine
,
&
reg
,
&
ctx
))
return
0
;
case
NVDEV_ENGINE_GR
:
reg
=
0x32e0
;
ctx
=
0x38
;
break
;
case
NVDEV_ENGINE_MPEG
:
reg
=
0x330c
;
ctx
=
0x54
;
break
;
default:
return
-
EINVAL
;
}
inst
=
chan
->
engn
[
engine
->
subdev
.
index
]
->
addr
>>
4
;
spin_lock_irqsave
(
&
fifo
->
base
.
lock
,
flags
);
nv_engctx
(
engctx
)
->
addr
=
nv_gpuobj
(
engctx
)
->
addr
>>
4
;
nvkm_mask
(
device
,
0x002500
,
0x00000001
,
0x00000000
);
if
((
nvkm_rd32
(
device
,
0x003204
)
&
fifo
->
base
.
max
)
==
chan
->
base
.
chid
)
nvkm_wr32
(
device
,
reg
,
nv_engctx
(
engctx
)
->
addr
);
chid
=
nvkm_rd32
(
device
,
0x003204
)
&
(
fifo
->
base
.
nr
-
1
);
if
(
chid
==
chan
->
base
.
chid
)
nvkm_wr32
(
device
,
reg
,
inst
);
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
ctx
,
nv_engctx
(
engctx
)
->
addr
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
ctx
,
inst
);
nvkm_done
(
imem
->
ramfc
);
nvkm_mask
(
device
,
0x002500
,
0x00000001
,
0x00000001
);
...
...
@@ -111,57 +113,91 @@ nv40_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *engctx)
return
0
;
}
static
void
nv40_fifo_dma_engine_dtor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
struct
nv04_fifo_chan
*
chan
=
nv04_fifo_chan
(
base
);
if
(
!
chan
->
engn
[
engine
->
subdev
.
index
]
||
chan
->
engn
[
engine
->
subdev
.
index
]
->
object
.
oclass
)
{
chan
->
engn
[
engine
->
subdev
.
index
]
=
NULL
;
return
;
}
nvkm_gpuobj_del
(
&
chan
->
engn
[
engine
->
subdev
.
index
]);
}
static
int
nv40_fifo_object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
nv40_fifo_dma_engine_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
struct
nvkm_object
*
object
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
u32
context
,
chid
=
chan
->
base
.
chid
;
int
ret
;
struct
nv04_fifo_chan
*
chan
=
nv04_fifo_chan
(
base
);
const
int
engn
=
engine
->
subdev
.
index
;
u32
reg
,
ctx
;
if
(
nv_iclass
(
object
,
NV_GPUOBJ_CLASS
))
context
=
nv_gpuobj
(
object
)
->
addr
>>
4
;
else
context
=
0x00000004
;
/* just non-zero */
if
(
object
->
engine
)
{
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
|=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
|=
0x00100000
;
break
;
case
NVDEV_ENGINE_MPEG
:
context
|=
0x00200000
;
break
;
default:
return
-
EINVAL
;
}
if
(
!
nv40_fifo_dma_engine
(
engine
,
&
reg
,
&
ctx
))
return
0
;
if
(
nv_iclass
(
object
,
NV_GPUOBJ_CLASS
))
{
chan
->
engn
[
engn
]
=
nv_gpuobj
(
object
);
return
0
;
}
context
|=
chid
<<
23
;
return
nvkm_object_bind
(
object
,
NULL
,
0
,
&
chan
->
engn
[
engn
]);
}
mutex_lock
(
&
nv_subdev
(
fifo
)
->
mutex
);
ret
=
nvkm_ramht_insert
(
imem
->
ramht
,
NULL
,
chid
,
0
,
handle
,
context
);
mutex_unlock
(
&
nv_subdev
(
fifo
)
->
mutex
);
return
ret
;
static
int
nv40_fifo_dma_object_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_object
*
object
)
{
struct
nv04_fifo_chan
*
chan
=
nv04_fifo_chan
(
base
);
struct
nvkm_instmem
*
imem
=
chan
->
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
u32
context
=
chan
->
base
.
chid
<<
23
;
u32
handle
=
object
->
handle
;
int
hash
;
switch
(
object
->
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_DMAOBJ
:
case
NVDEV_ENGINE_SW
:
context
|=
0x00000000
;
break
;
case
NVDEV_ENGINE_GR
:
context
|=
0x00100000
;
break
;
case
NVDEV_ENGINE_MPEG
:
context
|=
0x00200000
;
break
;
default:
WARN_ON
(
1
);
return
-
EINVAL
;
}
mutex_lock
(
&
chan
->
fifo
->
base
.
engine
.
subdev
.
mutex
);
hash
=
nvkm_ramht_insert
(
imem
->
ramht
,
object
,
chan
->
base
.
chid
,
4
,
handle
,
context
);
mutex_unlock
(
&
chan
->
fifo
->
base
.
engine
.
subdev
.
mutex
);
return
hash
;
}
static
const
struct
nvkm_fifo_chan_func
nv40_fifo_dma_func
=
{
.
dtor
=
nv04_fifo_dma_dtor
,
.
init
=
nv04_fifo_dma_init
,
.
fini
=
nv04_fifo_dma_fini
,
.
engine_ctor
=
nv40_fifo_dma_engine_ctor
,
.
engine_dtor
=
nv40_fifo_dma_engine_dtor
,
.
engine_init
=
nv40_fifo_dma_engine_init
,
.
engine_fini
=
nv40_fifo_dma_engine_fini
,
.
object_ctor
=
nv40_fifo_dma_object_ctor
,
.
object_dtor
=
nv04_fifo_dma_object_dtor
,
};
static
int
nv40_fifo_chan_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
nv40_fifo_dma_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
nv03_channel_dma_v0
v0
;
}
*
args
=
data
;
struct
nv04_fifo
*
fifo
=
(
void
*
)
engine
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
struct
nv04_fifo_chan
*
chan
;
struct
nv04_fifo
*
fifo
=
nv04_fifo
(
base
);
struct
nv04_fifo_chan
*
chan
=
NULL
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
...
...
@@ -169,31 +205,33 @@ nv40_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
!
args
->
v0
.
pushbuf
)
return
-
EINVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0xc00000
,
0x1000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nvkm_fifo_chan_ctor
(
&
nv40_fifo_dma_func
,
&
fifo
->
base
,
0x1000
,
0x1000
,
false
,
0
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
),
0
,
0xc00000
,
0x1000
,
oclass
,
&
chan
->
base
);
chan
->
fifo
=
fifo
;
if
(
ret
)
return
ret
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
context_attach
=
nv40_fifo_context_attach
;
nv_parent
(
chan
)
->
context_detach
=
nv40_fifo_context_detach
;
nv_parent
(
chan
)
->
object_attach
=
nv40_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv04_fifo_object_detach
;
chan
->
ramfc
=
chan
->
base
.
chid
*
128
;
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x00
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x04
,
args
->
v0
.
offset
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x0c
,
chan
->
base
.
push
gpu
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x0c
,
chan
->
base
.
push
->
addr
>>
4
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x18
,
0x30000000
|
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES
|
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES
|
...
...
@@ -206,20 +244,10 @@ nv40_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
return
0
;
}
static
struct
nvkm_ofuncs
nv40_fifo_ofuncs
=
{
.
ctor
=
nv40_fifo_chan_ctor
,
.
dtor
=
nv04_fifo_chan_dtor
,
.
init
=
nv04_fifo_chan_init
,
.
fini
=
nv04_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
nv40_fifo_sclass
[]
=
{
{
NV40_CHANNEL_DMA
,
&
nv40_fifo_ofuncs
},
{}
const
struct
nvkm_fifo_chan_oclass
nv40_fifo_dma_oclass
=
{
.
base
.
oclass
=
NV40_CHANNEL_DMA
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
nv40_fifo_dma_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c
View file @
8f0649b5
...
...
@@ -30,15 +30,14 @@
#include <nvif/unpack.h>
static
int
nv50_fifo_chan_ctor_dma
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
nv50_fifo_dma_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
nv50_channel_dma_v0
v0
;
}
*
args
=
data
;
struct
nvkm_device
*
device
=
parent
->
engine
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
;
struct
nv50_fifo
*
fifo
=
nv50_fifo
(
base
);
struct
nv50_fifo_chan
*
chan
;
int
ret
;
...
...
@@ -48,68 +47,45 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
"pushbuf %llx offset %016llx
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
args
->
v0
.
vm
)
return
-
E
NOENT
;
if
(
!
args
->
v0
.
pushbuf
)
return
-
E
INVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0xc00000
,
0x2000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nv50_fifo_chan_ctor
(
fifo
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
oclass
,
chan
);
if
(
ret
)
return
ret
;
chan
->
base
.
inst
=
base
->
base
.
gpuobj
.
addr
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
context_attach
=
nv50_fifo_context_attach
;
nv_parent
(
chan
)
->
context_detach
=
nv50_fifo_context_detach
;
nv_parent
(
chan
)
->
object_attach
=
nv50_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv50_fifo_object_detach
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
if
(
ret
)
return
ret
;
nvkm_kmap
(
base
->
ramfc
);
nvkm_wo32
(
base
->
ramfc
,
0x08
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x0c
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x10
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x14
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
base
->
ramfc
,
0x3c
,
0x003f6078
);
nvkm_wo32
(
base
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
base
->
ramfc
,
0x48
,
chan
->
base
.
pushgpu
->
node
->
offset
>>
4
);
nvkm_wo32
(
base
->
ramfc
,
0x4c
,
0xffffffff
);
nvkm_wo32
(
base
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
base
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
base
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
base
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
nvkm_kmap
(
chan
->
ramfc
);
nvkm_wo32
(
chan
->
ramfc
,
0x08
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x0c
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x10
,
lower_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x14
,
upper_32_bits
(
args
->
v0
.
offset
));
nvkm_wo32
(
chan
->
ramfc
,
0x3c
,
0x003f6078
);
nvkm_wo32
(
chan
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
chan
->
ramfc
,
0x48
,
chan
->
base
.
push
->
node
->
offset
>>
4
);
nvkm_wo32
(
chan
->
ramfc
,
0x4c
,
0xffffffff
);
nvkm_wo32
(
chan
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
chan
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
chan
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
chan
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
(
4
<<
24
)
/* SEARCH_FULL */
|
(
chan
->
ramht
->
gpuobj
->
node
->
offset
>>
4
));
nvkm_done
(
base
->
ramfc
);
nvkm_done
(
chan
->
ramfc
);
return
0
;
}
static
struct
nvkm_ofuncs
nv50_fifo_ofuncs_dma
=
{
.
ctor
=
nv50_fifo_chan_ctor_dma
,
.
dtor
=
nv50_fifo_chan_dtor
,
.
init
=
nv50_fifo_chan_init
,
.
fini
=
nv50_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
nv50_fifo_sclass
[]
=
{
{
NV50_CHANNEL_DMA
,
&
nv50_fifo_ofuncs_dma
},
{
NV50_CHANNEL_GPFIFO
,
&
nv50_fifo_ofuncs_ind
},
{}
const
struct
nvkm_fifo_chan_oclass
nv50_fifo_dma_oclass
=
{
.
base
.
oclass
=
NV50_CHANNEL_DMA
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
nv50_fifo_dma_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
View file @
8f0649b5
...
...
@@ -47,6 +47,15 @@ g84_fifo_uevent_func = {
.
fini
=
g84_fifo_uevent_fini
,
};
static
const
struct
nvkm_fifo_func
g84_fifo_func
=
{
.
chan
=
{
&
g84_fifo_dma_oclass
,
&
g84_fifo_gpfifo_oclass
,
NULL
},
};
static
int
g84_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -61,6 +70,8 @@ g84_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
g84_fifo_func
;
ret
=
nvkm_memory_new
(
device
,
NVKM_MEM_TARGET_INST
,
128
*
4
,
0x1000
,
false
,
&
fifo
->
runlist
[
0
]);
if
(
ret
)
...
...
@@ -77,8 +88,6 @@ g84_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
nv04_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
g84_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
g84_fifo_sclass
;
fifo
->
base
.
pause
=
nv04_fifo_pause
;
fifo
->
base
.
start
=
nv04_fifo_start
;
return
0
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
View file @
8f0649b5
...
...
@@ -58,28 +58,26 @@ gf100_fifo_uevent_func = {
void
gf100_fifo_runlist_update
(
struct
gf100_fifo
*
fifo
)
{
struct
gf100_fifo_chan
*
chan
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
struct
nvkm_memory
*
cur
;
int
i
,
p
;
int
nr
=
0
;
mutex_lock
(
&
nv_subdev
(
fifo
)
->
mutex
);
cur
=
fifo
->
runlist
.
mem
[
fifo
->
runlist
.
active
];
fifo
->
runlist
.
active
=
!
fifo
->
runlist
.
active
;
nvkm_kmap
(
cur
);
for
(
i
=
0
,
p
=
0
;
i
<
128
;
i
++
)
{
struct
gf100_fifo_chan
*
chan
=
(
void
*
)
fifo
->
base
.
channel
[
i
];
if
(
chan
&&
chan
->
state
==
RUNNING
)
{
nvkm_wo32
(
cur
,
p
+
0
,
i
);
nvkm_wo32
(
cur
,
p
+
4
,
0x00000004
);
p
+=
8
;
}
list_for_each_entry
(
chan
,
&
fifo
->
chan
,
head
)
{
nvkm_wo32
(
cur
,
(
nr
*
8
)
+
0
,
chan
->
base
.
chid
);
nvkm_wo32
(
cur
,
(
nr
*
8
)
+
4
,
0x00000004
);
nr
++
;
}
nvkm_done
(
cur
);
nvkm_wr32
(
device
,
0x002270
,
nvkm_memory_addr
(
cur
)
>>
12
);
nvkm_wr32
(
device
,
0x002274
,
0x01f00000
|
(
p
>>
3
)
);
nvkm_wr32
(
device
,
0x002274
,
0x01f00000
|
nr
);
if
(
wait_event_timeout
(
fifo
->
runlist
.
wait
,
!
(
nvkm_rd32
(
device
,
0x00227c
)
&
0x00100000
),
...
...
@@ -166,7 +164,8 @@ gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine,
assert_spin_locked
(
&
fifo
->
base
.
lock
);
nvkm_mask
(
device
,
0x003004
+
(
chid
*
0x08
),
0x00000001
,
0x00000000
);
chan
->
state
=
KILLED
;
list_del_init
(
&
chan
->
head
);
chan
->
killed
=
true
;
fifo
->
mask
|=
1ULL
<<
nv_engidx
(
engine
);
schedule_work
(
&
fifo
->
fault
);
...
...
@@ -198,11 +197,15 @@ gf100_fifo_intr_sched_ctxsw(struct gf100_fifo *fifo)
(
void
)
save
;
if
(
busy
&&
unk0
&&
unk1
)
{
if
(
!
(
chan
=
(
void
*
)
fifo
->
base
.
channel
[
chid
]))
continue
;
if
(
!
(
engine
=
gf100_fifo_engine
(
fifo
,
engn
)))
continue
;
gf100_fifo_recover
(
fifo
,
engine
,
chan
);
list_for_each_entry
(
chan
,
&
fifo
->
chan
,
head
)
{
if
(
chan
->
base
.
chid
==
chid
)
{
engine
=
gf100_fifo_engine
(
fifo
,
engn
);
if
(
!
engine
)
break
;
gf100_fifo_recover
(
fifo
,
engine
,
chan
);
break
;
}
}
}
}
spin_unlock_irqrestore
(
&
fifo
->
base
.
lock
,
flags
);
...
...
@@ -343,7 +346,8 @@ gf100_fifo_intr_fault(struct gf100_fifo *fifo, int unit)
write
?
"write"
:
"read"
,
(
u64
)
vahi
<<
32
|
valo
,
unit
,
eu
?
eu
->
name
:
""
,
client
,
gpcid
,
ec
?
ec
->
name
:
""
,
reason
,
er
?
er
->
name
:
""
,
chan
?
chan
->
chid
:
-
1
,
(
u64
)
inst
<<
12
,
nvkm_client_name
(
chan
));
(
u64
)
inst
<<
12
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
);
if
(
engine
&&
chan
)
gf100_fifo_recover
(
fifo
,
engine
,
(
void
*
)
chan
);
...
...
@@ -369,6 +373,8 @@ gf100_fifo_intr_pbdma(struct gf100_fifo *fifo, int unit)
u32
chid
=
nvkm_rd32
(
device
,
0x040120
+
(
unit
*
0x2000
))
&
0x7f
;
u32
subc
=
(
addr
&
0x00070000
)
>>
16
;
u32
mthd
=
(
addr
&
0x00003ffc
);
struct
nvkm_fifo_chan
*
chan
;
unsigned
long
flags
;
u32
show
=
stat
;
char
msg
[
128
];
...
...
@@ -381,11 +387,13 @@ gf100_fifo_intr_pbdma(struct gf100_fifo *fifo, int unit)
if
(
show
)
{
nvkm_snprintbf
(
msg
,
sizeof
(
msg
),
gf100_fifo_pbdma_intr
,
show
);
nvkm_error
(
subdev
,
"PBDMA%d: %08x [%s] ch %d [%s] subc %d "
"mthd %04x data %08x
\n
"
,
unit
,
show
,
msg
,
chid
,
nvkm_client_name_for_fifo_chid
(
&
fifo
->
base
,
chid
),
chan
=
nvkm_fifo_chan_chid
(
&
fifo
->
base
,
chid
,
&
flags
);
nvkm_error
(
subdev
,
"PBDMA%d: %08x [%s] ch %d [%010llx %s] "
"subc %d mthd %04x data %08x
\n
"
,
unit
,
show
,
msg
,
chid
,
chan
?
chan
->
inst
->
addr
:
0
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
subc
,
mthd
,
data
);
nvkm_fifo_chan_put
(
&
fifo
->
base
,
flags
,
&
chan
);
}
nvkm_wr32
(
device
,
0x0400c0
+
(
unit
*
0x2000
),
0x80600008
);
...
...
@@ -579,6 +587,14 @@ gf100_fifo_dtor(struct nvkm_object *object)
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
static
const
struct
nvkm_fifo_func
gf100_fifo_func
=
{
.
chan
=
{
&
gf100_fifo_gpfifo_oclass
,
NULL
},
};
static
int
gf100_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -594,6 +610,9 @@ gf100_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
gf100_fifo_func
;
INIT_LIST_HEAD
(
&
fifo
->
chan
);
INIT_WORK
(
&
fifo
->
fault
,
gf100_fifo_recover_work
);
ret
=
nvkm_memory_new
(
device
,
NVKM_MEM_TARGET_INST
,
0x1000
,
0x1000
,
...
...
@@ -625,8 +644,6 @@ gf100_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
gf100_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
gf100_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
gf100_fifo_sclass
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h
View file @
8f0649b5
#ifndef __GF100_FIFO_H__
#define __GF100_FIFO_H__
#define gf100_fifo(p) container_of((p), struct gf100_fifo, base)
#include "priv.h"
#include <subdev/mmu.h>
struct
gf100_fifo
{
struct
nvkm_fifo
base
;
struct
list_head
chan
;
struct
work_struct
fault
;
u64
mask
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
View file @
8f0649b5
...
...
@@ -32,23 +32,6 @@
#include <nvif/class.h>
#define _(a,b) { (a), ((1ULL << (a)) | (b)) }
static
const
struct
{
u64
subdev
;
u64
mask
;
}
fifo_engine
[]
=
{
_
(
NVDEV_ENGINE_GR
,
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_CE2
)),
_
(
NVDEV_ENGINE_MSPDEC
,
0
),
_
(
NVDEV_ENGINE_MSPPP
,
0
),
_
(
NVDEV_ENGINE_MSVLD
,
0
),
_
(
NVDEV_ENGINE_CE0
,
0
),
_
(
NVDEV_ENGINE_CE1
,
0
),
_
(
NVDEV_ENGINE_MSENC
,
0
),
};
#undef _
#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
static
void
gk104_fifo_uevent_fini
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
...
...
@@ -76,28 +59,26 @@ void
gk104_fifo_runlist_update
(
struct
gk104_fifo
*
fifo
,
u32
engine
)
{
struct
gk104_fifo_engn
*
engn
=
&
fifo
->
engine
[
engine
];
struct
gk104_fifo_chan
*
chan
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
struct
nvkm_memory
*
cur
;
int
i
,
p
;
int
nr
=
0
;
mutex_lock
(
&
nv_subdev
(
fifo
)
->
mutex
);
cur
=
engn
->
runlist
[
engn
->
cur_runlist
];
engn
->
cur_runlist
=
!
engn
->
cur_runlist
;
nvkm_kmap
(
cur
);
for
(
i
=
0
,
p
=
0
;
i
<
fifo
->
base
.
max
;
i
++
)
{
struct
gk104_fifo_chan
*
chan
=
(
void
*
)
fifo
->
base
.
channel
[
i
];
if
(
chan
&&
chan
->
state
==
RUNNING
&&
chan
->
engine
==
engine
)
{
nvkm_wo32
(
cur
,
p
+
0
,
i
);
nvkm_wo32
(
cur
,
p
+
4
,
0x00000000
);
p
+=
8
;
}
list_for_each_entry
(
chan
,
&
engn
->
chan
,
head
)
{
nvkm_wo32
(
cur
,
(
nr
*
8
)
+
0
,
chan
->
base
.
chid
);
nvkm_wo32
(
cur
,
(
nr
*
8
)
+
4
,
0x00000000
);
nr
++
;
}
nvkm_done
(
cur
);
nvkm_wr32
(
device
,
0x002270
,
nvkm_memory_addr
(
cur
)
>>
12
);
nvkm_wr32
(
device
,
0x002274
,
(
engine
<<
20
)
|
(
p
>>
3
)
);
nvkm_wr32
(
device
,
0x002274
,
(
engine
<<
20
)
|
nr
);
if
(
wait_event_timeout
(
engn
->
wait
,
!
(
nvkm_rd32
(
device
,
0x002284
+
(
engine
*
0x08
))
&
0x00100000
),
...
...
@@ -106,31 +87,13 @@ gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
mutex_unlock
(
&
nv_subdev
(
fifo
)
->
mutex
);
}
static
inline
int
gk104_fifo_engidx
(
struct
gk104_fifo
*
fifo
,
u32
engn
)
{
switch
(
engn
)
{
case
NVDEV_ENGINE_GR
:
case
NVDEV_ENGINE_CE2
:
engn
=
0
;
break
;
case
NVDEV_ENGINE_MSVLD
:
engn
=
1
;
break
;
case
NVDEV_ENGINE_MSPPP
:
engn
=
2
;
break
;
case
NVDEV_ENGINE_MSPDEC
:
engn
=
3
;
break
;
case
NVDEV_ENGINE_CE0
:
engn
=
4
;
break
;
case
NVDEV_ENGINE_CE1
:
engn
=
5
;
break
;
case
NVDEV_ENGINE_MSENC
:
engn
=
6
;
break
;
default:
return
-
1
;
}
return
engn
;
}
static
inline
struct
nvkm_engine
*
gk104_fifo_engine
(
struct
gk104_fifo
*
fifo
,
u32
engn
)
{
if
(
engn
>=
ARRAY_SIZE
(
fifo_engine
))
return
NULL
;
return
nvkm_engine
(
fifo
,
fifo_engine
[
engn
].
subdev
);
u64
subdevs
=
gk104_fifo_engine_subdev
(
engn
);
if
(
subdevs
)
return
nvkm_engine
(
fifo
,
__ffs
(
subdevs
));
return
NULL
;
}
static
void
...
...
@@ -149,7 +112,7 @@ gk104_fifo_recover_work(struct work_struct *work)
spin_unlock_irqrestore
(
&
fifo
->
base
.
lock
,
flags
);
for
(
todo
=
mask
;
engn
=
__ffs64
(
todo
),
todo
;
todo
&=
~
(
1
<<
engn
))
engm
|=
1
<<
gk104_fifo_
engidx
(
fifo
,
engn
);
engm
|=
1
<<
gk104_fifo_
subdev_engine
(
engn
);
nvkm_mask
(
device
,
0x002630
,
engm
,
engm
);
for
(
todo
=
mask
;
engn
=
__ffs64
(
todo
),
todo
;
todo
&=
~
(
1
<<
engn
))
{
...
...
@@ -157,7 +120,7 @@ gk104_fifo_recover_work(struct work_struct *work)
nvkm_subdev_fini
(
&
engine
->
subdev
,
false
);
WARN_ON
(
nvkm_subdev_init
(
&
engine
->
subdev
));
}
gk104_fifo_runlist_update
(
fifo
,
gk104_fifo_
engidx
(
fifo
,
engn
));
gk104_fifo_runlist_update
(
fifo
,
gk104_fifo_
subdev_engine
(
engn
));
}
nvkm_wr32
(
device
,
0x00262c
,
engm
);
...
...
@@ -177,7 +140,8 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
assert_spin_locked
(
&
fifo
->
base
.
lock
);
nvkm_mask
(
device
,
0x800004
+
(
chid
*
0x08
),
0x00000800
,
0x00000800
);
chan
->
state
=
KILLED
;
list_del_init
(
&
chan
->
head
);
chan
->
killed
=
true
;
fifo
->
mask
|=
1ULL
<<
nv_engidx
(
engine
);
schedule_work
(
&
fifo
->
fault
);
...
...
@@ -223,7 +187,7 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
u32
engn
;
spin_lock_irqsave
(
&
fifo
->
base
.
lock
,
flags
);
for
(
engn
=
0
;
engn
<
ARRAY_SIZE
(
fifo
_
engine
);
engn
++
)
{
for
(
engn
=
0
;
engn
<
ARRAY_SIZE
(
fifo
->
engine
);
engn
++
)
{
u32
stat
=
nvkm_rd32
(
device
,
0x002640
+
(
engn
*
0x04
));
u32
busy
=
(
stat
&
0x80000000
);
u32
next
=
(
stat
&
0x07ff0000
)
>>
16
;
...
...
@@ -235,11 +199,15 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
(
void
)
save
;
if
(
busy
&&
chsw
)
{
if
(
!
(
chan
=
(
void
*
)
fifo
->
base
.
channel
[
chid
]))
continue
;
if
(
!
(
engine
=
gk104_fifo_engine
(
fifo
,
engn
)))
continue
;
gk104_fifo_recover
(
fifo
,
engine
,
chan
);
list_for_each_entry
(
chan
,
&
fifo
->
engine
[
engn
].
chan
,
head
)
{
if
(
chan
->
base
.
chid
==
chid
)
{
engine
=
gk104_fifo_engine
(
fifo
,
engn
);
if
(
!
engine
)
break
;
gk104_fifo_recover
(
fifo
,
engine
,
chan
);
break
;
}
}
}
}
spin_unlock_irqrestore
(
&
fifo
->
base
.
lock
,
flags
);
...
...
@@ -444,7 +412,8 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
write
?
"write"
:
"read"
,
(
u64
)
vahi
<<
32
|
valo
,
unit
,
eu
?
eu
->
name
:
""
,
client
,
gpcid
,
ec
?
ec
->
name
:
""
,
reason
,
er
?
er
->
name
:
""
,
chan
?
chan
->
chid
:
-
1
,
(
u64
)
inst
<<
12
,
nvkm_client_name
(
chan
));
(
u64
)
inst
<<
12
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
);
if
(
engine
&&
chan
)
gk104_fifo_recover
(
fifo
,
engine
,
(
void
*
)
chan
);
...
...
@@ -498,6 +467,8 @@ gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit)
u32
subc
=
(
addr
&
0x00070000
)
>>
16
;
u32
mthd
=
(
addr
&
0x00003ffc
);
u32
show
=
stat
;
struct
nvkm_fifo_chan
*
chan
;
unsigned
long
flags
;
char
msg
[
128
];
if
(
stat
&
0x00800000
)
{
...
...
@@ -510,11 +481,13 @@ gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit)
if
(
show
)
{
nvkm_snprintbf
(
msg
,
sizeof
(
msg
),
gk104_fifo_pbdma_intr_0
,
show
);
nvkm_error
(
subdev
,
"PBDMA%d: %08x [%s] ch %d [%s] subc %d "
"mthd %04x data %08x
\n
"
,
unit
,
show
,
msg
,
chid
,
nvkm_client_name_for_fifo_chid
(
&
fifo
->
base
,
chid
),
chan
=
nvkm_fifo_chan_chid
(
&
fifo
->
base
,
chid
,
&
flags
);
nvkm_error
(
subdev
,
"PBDMA%d: %08x [%s] ch %d [%010llx %s] "
"subc %d mthd %04x data %08x
\n
"
,
unit
,
show
,
msg
,
chid
,
chan
?
chan
->
inst
->
addr
:
0
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
subc
,
mthd
,
data
);
nvkm_fifo_chan_put
(
&
fifo
->
base
,
flags
,
&
chan
);
}
nvkm_wr32
(
device
,
0x040108
+
(
unit
*
0x2000
),
stat
);
...
...
@@ -722,7 +695,7 @@ gk104_fifo_dtor(struct nvkm_object *object)
nvkm_vm_put
(
&
fifo
->
user
.
bar
);
nvkm_memory_del
(
&
fifo
->
user
.
mem
);
for
(
i
=
0
;
i
<
FIFO_ENGINE_NR
;
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
fifo
->
engine
)
;
i
++
)
{
nvkm_memory_del
(
&
fifo
->
engine
[
i
].
runlist
[
1
]);
nvkm_memory_del
(
&
fifo
->
engine
[
i
].
runlist
[
0
]);
}
...
...
@@ -730,6 +703,14 @@ gk104_fifo_dtor(struct nvkm_object *object)
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
static
const
struct
nvkm_fifo_func
gk104_fifo_func
=
{
.
chan
=
{
&
gk104_fifo_gpfifo_oclass
,
NULL
},
};
int
gk104_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -747,9 +728,11 @@ gk104_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
gk104_fifo_func
;
INIT_WORK
(
&
fifo
->
fault
,
gk104_fifo_recover_work
);
for
(
i
=
0
;
i
<
FIFO_ENGINE_NR
;
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
fifo
->
engine
)
;
i
++
)
{
ret
=
nvkm_memory_new
(
device
,
NVKM_MEM_TARGET_INST
,
0x8000
,
0x1000
,
false
,
&
fifo
->
engine
[
i
].
runlist
[
0
]);
...
...
@@ -763,6 +746,7 @@ gk104_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
return
ret
;
init_waitqueue_head
(
&
fifo
->
engine
[
i
].
wait
);
INIT_LIST_HEAD
(
&
fifo
->
engine
[
i
].
chan
);
}
ret
=
nvkm_memory_new
(
device
,
NVKM_MEM_TARGET_INST
,
...
...
@@ -783,8 +767,6 @@ gk104_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
gk104_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
gk104_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
gk104_fifo_sclass
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
View file @
8f0649b5
#ifndef __GK104_FIFO_H__
#define __GK104_FIFO_H__
#define gk104_fifo(p) container_of((p), struct gk104_fifo, base)
#include "priv.h"
#include <subdev/mmu.h>
struct
gk104_fifo_engn
{
struct
nvkm_memory
*
runlist
[
2
];
int
cur_runlist
;
wait_queue_head_t
wait
;
struct
list_head
chan
;
};
struct
gk104_fifo
{
...
...
@@ -38,4 +42,42 @@ void gk104_fifo_runlist_update(struct gk104_fifo *, u32 engine);
int
gm204_fifo_ctor
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
struct
nvkm_oclass
*
,
void
*
,
u32
,
struct
nvkm_object
**
);
static
inline
u64
gk104_fifo_engine_subdev
(
int
engine
)
{
switch
(
engine
)
{
case
0
:
return
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_CE2
);
case
1
:
return
(
1ULL
<<
NVDEV_ENGINE_MSPDEC
);
case
2
:
return
(
1ULL
<<
NVDEV_ENGINE_MSPPP
);
case
3
:
return
(
1ULL
<<
NVDEV_ENGINE_MSVLD
);
case
4
:
return
(
1ULL
<<
NVDEV_ENGINE_CE0
);
case
5
:
return
(
1ULL
<<
NVDEV_ENGINE_CE1
);
case
6
:
return
(
1ULL
<<
NVDEV_ENGINE_MSENC
);
default:
WARN_ON
(
1
);
return
0
;
}
}
static
inline
int
gk104_fifo_subdev_engine
(
int
subdev
)
{
switch
(
subdev
)
{
case
NVDEV_ENGINE_GR
:
case
NVDEV_ENGINE_SW
:
case
NVDEV_ENGINE_CE2
:
return
0
;
case
NVDEV_ENGINE_MSPDEC
:
return
1
;
case
NVDEV_ENGINE_MSPPP
:
return
2
;
case
NVDEV_ENGINE_MSVLD
:
return
3
;
case
NVDEV_ENGINE_CE0
:
return
4
;
case
NVDEV_ENGINE_CE1
:
return
5
;
case
NVDEV_ENGINE_MSENC
:
return
6
;
default:
WARN_ON
(
1
);
return
0
;
}
}
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm204.c
View file @
8f0649b5
...
...
@@ -24,6 +24,14 @@
#include "gk104.h"
#include "changk104.h"
static
const
struct
nvkm_fifo_func
gm204_fifo_func
=
{
.
chan
=
{
&
gm204_fifo_gpfifo_oclass
,
NULL
},
};
int
gm204_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -32,7 +40,7 @@ gm204_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
int
ret
=
gk104_fifo_ctor
(
parent
,
engine
,
oclass
,
data
,
size
,
pobject
);
if
(
ret
==
0
)
{
struct
gk104_fifo
*
fifo
=
(
void
*
)
*
pobject
;
nv_engine
(
fifo
)
->
sclass
=
gm204_fifo_sclass
;
fifo
->
base
.
func
=
&
gm204_fifo_func
;
}
return
ret
;
}
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c
View file @
8f0649b5
...
...
@@ -30,15 +30,14 @@
#include <nvif/unpack.h>
static
int
g84_fifo_chan_ctor_ind
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
g84_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
nv50_channel_gpfifo_v0
v0
;
}
*
args
=
data
;
struct
nvkm_device
*
device
=
parent
->
engine
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
;
struct
nv50_fifo
*
fifo
=
nv50_fifo
(
base
);
struct
nv50_fifo_chan
*
chan
;
u64
ioffset
,
ilength
;
int
ret
;
...
...
@@ -50,73 +49,46 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
"ilength %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
);
if
(
args
->
v0
.
vm
)
return
-
E
NOENT
;
if
(
!
args
->
v0
.
pushbuf
)
return
-
E
INVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0xc00000
,
0x2000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
)
|
(
1ULL
<<
NVDEV_ENGINE_ME
)
|
(
1ULL
<<
NVDEV_ENGINE_VP
)
|
(
1ULL
<<
NVDEV_ENGINE_CIPHER
)
|
(
1ULL
<<
NVDEV_ENGINE_SEC
)
|
(
1ULL
<<
NVDEV_ENGINE_BSP
)
|
(
1ULL
<<
NVDEV_ENGINE_MSVLD
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPDEC
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPPP
)
|
(
1ULL
<<
NVDEV_ENGINE_CE0
)
|
(
1ULL
<<
NVDEV_ENGINE_VIC
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
ret
)
return
ret
;
chan
->
base
.
inst
=
base
->
base
.
gpuobj
.
addr
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
ret
=
g84_fifo_chan_ctor
(
fifo
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
oclass
,
chan
);
if
(
ret
)
return
ret
;
nv_parent
(
chan
)
->
context_attach
=
g84_fifo_context_attach
;
nv_parent
(
chan
)
->
context_detach
=
g84_fifo_context_detach
;
nv_parent
(
chan
)
->
object_attach
=
g84_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv50_fifo_object_detach
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
nvkm_kmap
(
base
->
ramfc
);
nvkm_wo32
(
base
->
ramfc
,
0x3c
,
0x403f6078
);
nvkm_wo32
(
base
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
base
->
ramfc
,
0x48
,
chan
->
base
.
pushgpu
->
node
->
offset
>>
4
);
nvkm_wo32
(
base
->
ramfc
,
0x50
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
base
->
ramfc
,
0x54
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
base
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
base
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
base
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
base
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
nvkm_kmap
(
chan
->
ramfc
);
nvkm_wo32
(
chan
->
ramfc
,
0x3c
,
0x403f6078
);
nvkm_wo32
(
chan
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
chan
->
ramfc
,
0x48
,
chan
->
base
.
push
->
node
->
offset
>>
4
);
nvkm_wo32
(
chan
->
ramfc
,
0x50
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
chan
->
ramfc
,
0x54
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
chan
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
chan
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
chan
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
chan
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
(
4
<<
24
)
/* SEARCH_FULL */
|
(
chan
->
ramht
->
gpuobj
->
node
->
offset
>>
4
));
nvkm_wo32
(
base
->
ramfc
,
0x88
,
base
->
cache
->
addr
>>
10
);
nvkm_wo32
(
base
->
ramfc
,
0x98
,
nv_gpuobj
(
base
)
->
addr
>>
12
);
nvkm_done
(
base
->
ramfc
);
nvkm_wo32
(
chan
->
ramfc
,
0x88
,
chan
->
cache
->
addr
>>
10
);
nvkm_wo32
(
chan
->
ramfc
,
0x98
,
chan
->
base
.
inst
->
addr
>>
12
);
nvkm_done
(
chan
->
ramfc
);
return
0
;
}
struct
nvkm_ofuncs
g84_fifo_ofuncs_ind
=
{
.
ctor
=
g84_fifo_chan_ctor_ind
,
.
dtor
=
nv50_fifo_chan_dtor
,
.
init
=
g84_fifo_chan_init
,
.
fini
=
nv50_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
const
struct
nvkm_fifo_chan_oclass
g84_fifo_gpfifo_oclass
=
{
.
base
.
oclass
=
G82_CHANNEL_GPFIFO
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
g84_fifo_gpfifo_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
View file @
8f0649b5
...
...
@@ -30,29 +30,33 @@
#include <nvif/class.h>
#include <nvif/unpack.h>
static
int
gf100_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
static
u32
gf100_fifo_gpfifo_engine_addr
(
struct
nvkm_engine
*
engine
)
{
struct
gf100_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
gf100_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
gf100_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nvkm_gpuobj
*
engn
=
&
base
->
base
.
gpuobj
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
u32
addr
;
switch
(
nv_engidx
(
object
->
engine
))
{
switch
(
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
addr
=
0x0210
;
break
;
case
NVDEV_ENGINE_CE0
:
addr
=
0x0230
;
break
;
case
NVDEV_ENGINE_CE1
:
addr
=
0x0240
;
break
;
case
NVDEV_ENGINE_MS
VLD
:
addr
=
0x0270
;
break
;
case
NVDEV_ENGINE_MSP
DEC
:
addr
=
0x0250
;
break
;
case
NVDEV_ENGINE_MS
PPP
:
addr
=
0x0260
;
break
;
case
NVDEV_ENGINE_GR
:
return
0x0210
;
case
NVDEV_ENGINE_CE0
:
return
0x0230
;
case
NVDEV_ENGINE_CE1
:
return
0x0240
;
case
NVDEV_ENGINE_MS
PDEC
:
return
0x0250
;
case
NVDEV_ENGINE_MSP
PP
:
return
0x0260
;
case
NVDEV_ENGINE_MS
VLD
:
return
0x0270
;
default:
return
-
EINVAL
;
WARN_ON
(
1
);
return
0
;
}
}
static
int
gf100_fifo_gpfifo_engine_fini
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
bool
suspend
)
{
const
u32
offset
=
gf100_fifo_gpfifo_engine_addr
(
engine
);
struct
gf100_fifo_chan
*
chan
=
gf100_fifo_chan
(
base
);
struct
nvkm_subdev
*
subdev
=
&
chan
->
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
struct
nvkm_gpuobj
*
inst
=
chan
->
base
.
inst
;
int
ret
=
0
;
nvkm_wr32
(
device
,
0x002634
,
chan
->
base
.
chid
);
if
(
nvkm_msec
(
device
,
2000
,
...
...
@@ -60,143 +64,197 @@ gf100_fifo_context_detach(struct nvkm_object *parent, bool suspend,
break
;
)
<
0
)
{
nvkm_error
(
subdev
,
"channel %d [%s] kick timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
));
chan
->
base
.
chid
,
chan
->
base
.
object
.
client
->
name
);
ret
=
-
EBUSY
;
if
(
suspend
)
return
-
EBUSY
;
return
ret
;
}
if
(
offset
)
{
nvkm_kmap
(
inst
);
nvkm_wo32
(
inst
,
offset
+
0x00
,
0x00000000
);
nvkm_wo32
(
inst
,
offset
+
0x04
,
0x00000000
);
nvkm_done
(
inst
);
}
return
ret
;
}
static
int
gf100_fifo_gpfifo_engine_init
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
const
u32
offset
=
gf100_fifo_gpfifo_engine_addr
(
engine
);
struct
gf100_fifo_chan
*
chan
=
gf100_fifo_chan
(
base
);
struct
nvkm_gpuobj
*
inst
=
chan
->
base
.
inst
;
if
(
offset
)
{
u64
addr
=
chan
->
engn
[
engine
->
subdev
.
index
].
vma
.
offset
;
nvkm_kmap
(
inst
);
nvkm_wo32
(
inst
,
offset
+
0x00
,
lower_32_bits
(
addr
)
|
4
);
nvkm_wo32
(
inst
,
offset
+
0x04
,
upper_32_bits
(
addr
));
nvkm_done
(
inst
);
}
nvkm_kmap
(
engn
);
nvkm_wo32
(
engn
,
addr
+
0x00
,
0x00000000
);
nvkm_wo32
(
engn
,
addr
+
0x04
,
0x00000000
);
nvkm_done
(
engn
);
return
0
;
}
static
void
gf100_fifo_gpfifo_engine_dtor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
struct
gf100_fifo_chan
*
chan
=
gf100_fifo_chan
(
base
);
nvkm_gpuobj_unmap
(
&
chan
->
engn
[
engine
->
subdev
.
index
].
vma
);
nvkm_gpuobj_del
(
&
chan
->
engn
[
engine
->
subdev
.
index
].
inst
);
}
static
int
gf100_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
gf100_fifo_gpfifo_engine_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
struct
nvkm_object
*
object
)
{
struct
gf100_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
nvkm_gpuobj
*
engn
=
&
base
->
base
.
gpuobj
;
struct
nvkm_engctx
*
ectx
=
(
void
*
)
object
;
u32
addr
;
struct
gf100_fifo_chan
*
chan
=
gf100_fifo_chan
(
base
);
int
engn
=
engine
->
subdev
.
index
;
int
ret
;
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
addr
=
0x0210
;
break
;
case
NVDEV_ENGINE_CE0
:
addr
=
0x0230
;
break
;
case
NVDEV_ENGINE_CE1
:
addr
=
0x0240
;
break
;
case
NVDEV_ENGINE_MSVLD
:
addr
=
0x0270
;
break
;
case
NVDEV_ENGINE_MSPDEC
:
addr
=
0x0250
;
break
;
case
NVDEV_ENGINE_MSPPP
:
addr
=
0x0260
;
break
;
default:
return
-
EINVAL
;
}
if
(
!
ectx
->
vma
.
node
)
{
ret
=
nvkm_gpuobj_map
(
nv_gpuobj
(
ectx
),
base
->
vm
,
NV_MEM_ACCESS_RW
,
&
ectx
->
vma
);
if
(
ret
)
return
ret
;
if
(
!
gf100_fifo_gpfifo_engine_addr
(
engine
))
return
0
;
nv_engctx
(
ectx
)
->
addr
=
nv_gpuobj
(
base
)
->
addr
>>
12
;
if
(
object
->
oclass
)
{
return
nvkm_gpuobj_map
(
nv_gpuobj
(
object
),
chan
->
vm
,
NV_MEM_ACCESS_RW
,
&
chan
->
engn
[
engn
].
vma
);
}
nvkm_kmap
(
engn
);
nvkm_wo32
(
engn
,
addr
+
0x00
,
lower_32_bits
(
ectx
->
vma
.
offset
)
|
4
);
nvkm_wo32
(
engn
,
addr
+
0x04
,
upper_32_bits
(
ectx
->
vma
.
offset
));
nvkm_done
(
engn
);
return
0
;
ret
=
nvkm_object_bind
(
object
,
NULL
,
0
,
&
chan
->
engn
[
engn
].
inst
);
if
(
ret
)
return
ret
;
return
nvkm_gpuobj_map
(
chan
->
engn
[
engn
].
inst
,
chan
->
vm
,
NV_MEM_ACCESS_RW
,
&
chan
->
engn
[
engn
].
vma
);
}
static
int
gf100_fifo_
chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
static
void
gf100_fifo_
gpfifo_fini
(
struct
nvkm_fifo_chan
*
base
)
{
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gf100_fifo
_chan
*
chan
=
(
void
*
)
object
;
struct
gf100_fifo
_chan
*
chan
=
gf100_fifo_chan
(
base
)
;
struct
gf100_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
c
hid
=
chan
->
base
.
chid
;
u32
c
off
=
chan
->
base
.
chid
*
8
;
if
(
chan
->
state
==
RUNNING
&&
(
chan
->
state
=
STOPPED
)
==
STOPPED
)
{
nvkm_mask
(
device
,
0x003004
+
(
chid
*
8
),
0x00000001
,
0x00000000
);
if
(
!
list_empty
(
&
chan
->
head
)
&&
!
chan
->
killed
)
{
list_del_init
(
&
chan
->
head
);
nvkm_mask
(
device
,
0x003004
+
coff
,
0x00000001
,
0x00000000
);
gf100_fifo_runlist_update
(
fifo
);
}
gf100_fifo_intr_engine
(
fifo
);
nvkm_wr32
(
device
,
0x003000
+
(
chid
*
8
),
0x00000000
);
return
nvkm_fifo_channel_fini
(
&
chan
->
base
,
suspend
);
nvkm_wr32
(
device
,
0x003000
+
coff
,
0x00000000
);
}
static
int
gf100_fifo_
chan_init
(
struct
nvkm_object
*
object
)
static
void
gf100_fifo_
gpfifo_init
(
struct
nvkm_fifo_chan
*
base
)
{
struct
nvkm_gpuobj
*
base
=
nv_gpuobj
(
object
->
parent
);
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gf100_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
gf100_fifo_chan
*
chan
=
gf100_fifo_chan
(
base
);
struct
gf100_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
int
ret
;
ret
=
nvkm_fifo_channel_init
(
&
chan
->
base
);
if
(
ret
)
return
ret
;
u32
addr
=
chan
->
base
.
inst
->
addr
>>
12
;
u32
coff
=
chan
->
base
.
chid
*
8
;
nvkm_wr32
(
device
,
0x003000
+
(
chid
*
8
),
0xc0000000
|
base
->
addr
>>
12
);
nvkm_wr32
(
device
,
0x003000
+
coff
,
0xc0000000
|
addr
);
if
(
chan
->
state
==
STOPPED
&&
(
chan
->
state
=
RUNNING
)
==
RUNNING
)
{
nvkm_wr32
(
device
,
0x003004
+
(
chid
*
8
),
0x001f0001
);
if
(
list_empty
(
&
chan
->
head
)
&&
!
chan
->
killed
)
{
list_add_tail
(
&
chan
->
head
,
&
fifo
->
chan
);
nvkm_wr32
(
device
,
0x003004
+
coff
,
0x001f0001
);
gf100_fifo_runlist_update
(
fifo
);
}
}
return
0
;
static
void
*
gf100_fifo_gpfifo_dtor
(
struct
nvkm_fifo_chan
*
base
)
{
struct
gf100_fifo_chan
*
chan
=
gf100_fifo_chan
(
base
);
nvkm_vm_ref
(
NULL
,
&
chan
->
vm
,
chan
->
pgd
);
nvkm_gpuobj_del
(
&
chan
->
pgd
);
return
chan
;
}
static
const
struct
nvkm_fifo_chan_func
gf100_fifo_gpfifo_func
=
{
.
dtor
=
gf100_fifo_gpfifo_dtor
,
.
init
=
gf100_fifo_gpfifo_init
,
.
fini
=
gf100_fifo_gpfifo_fini
,
.
ntfy
=
g84_fifo_chan_ntfy
,
.
engine_ctor
=
gf100_fifo_gpfifo_engine_ctor
,
.
engine_dtor
=
gf100_fifo_gpfifo_engine_dtor
,
.
engine_init
=
gf100_fifo_gpfifo_engine_init
,
.
engine_fini
=
gf100_fifo_gpfifo_engine_fini
,
};
static
int
gf100_fifo_chan_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
gf100_fifo_gpfifo_new
(
struct
nvkm_fifo
*
base
,
const
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
union
{
struct
fermi_channel_gpfifo_v0
v0
;
}
*
args
=
data
;
struct
gf100_fifo
*
fifo
=
(
void
*
)
engine
;
struct
gf100_fifo_base
*
base
=
(
void
*
)
parent
;
struct
gf100_fifo
*
fifo
=
gf100_fifo
(
base
);
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_object
*
parent
=
oclass
->
parent
;
struct
gf100_fifo_chan
*
chan
;
struct
nvkm_gpuobj
*
ramfc
=
&
base
->
base
.
gpuobj
;
u64
usermem
,
ioffset
,
ilength
;
int
ret
,
i
;
nvif_ioctl
(
parent
,
"create channel gpfifo size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel gpfifo vers %d vm %llx"
nvif_ioctl
(
parent
,
"create channel gpfifo vers %d vm %llx
"
"ioffset %016llx ilength %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
1
,
fifo
->
user
.
bar
.
offset
,
0x1000
,
0
,
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_CE0
)
|
(
1ULL
<<
NVDEV_ENGINE_CE1
)
|
(
1ULL
<<
NVDEV_ENGINE_MSVLD
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPDEC
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPPP
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
/* allocate channel */
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
chan
->
fifo
=
fifo
;
INIT_LIST_HEAD
(
&
chan
->
head
);
ret
=
nvkm_fifo_chan_ctor
(
&
gf100_fifo_gpfifo_func
,
&
fifo
->
base
,
0x1000
,
0x1000
,
true
,
args
->
v0
.
vm
,
0
,
(
1ULL
<<
NVDEV_ENGINE_CE0
)
|
(
1ULL
<<
NVDEV_ENGINE_CE1
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPDEC
)
|
(
1ULL
<<
NVDEV_ENGINE_MSPPP
)
|
(
1ULL
<<
NVDEV_ENGINE_MSVLD
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
),
1
,
fifo
->
user
.
bar
.
offset
,
0x1000
,
oclass
,
&
chan
->
base
);
if
(
ret
)
return
ret
;
chan
->
base
.
inst
=
base
->
base
.
gpuobj
.
addr
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
context_attach
=
gf100_fifo_context_attach
;
nv_parent
(
chan
)
->
context_detach
=
gf100_fifo_context_detach
;
/* page directory */
ret
=
nvkm_gpuobj_new
(
device
,
0x10000
,
0x1000
,
false
,
NULL
,
&
chan
->
pgd
);
if
(
ret
)
return
ret
;
nvkm_kmap
(
chan
->
base
.
inst
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x0200
,
lower_32_bits
(
chan
->
pgd
->
addr
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x0204
,
upper_32_bits
(
chan
->
pgd
->
addr
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x0208
,
0xffffffff
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x020c
,
0x000000ff
);
nvkm_done
(
chan
->
base
.
inst
);
ret
=
nvkm_vm_ref
(
chan
->
base
.
vm
,
&
chan
->
vm
,
chan
->
pgd
);
if
(
ret
)
return
ret
;
/* clear channel control registers */
usermem
=
chan
->
base
.
chid
*
0x1000
;
ioffset
=
args
->
v0
.
ioffset
;
...
...
@@ -208,97 +266,33 @@ gf100_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nvkm_done
(
fifo
->
user
.
mem
);
usermem
=
nvkm_memory_addr
(
fifo
->
user
.
mem
)
+
usermem
;
nvkm_kmap
(
ramfc
);
nvkm_wo32
(
ramfc
,
0x08
,
lower_32_bits
(
usermem
));
nvkm_wo32
(
ramfc
,
0x0c
,
upper_32_bits
(
usermem
));
nvkm_wo32
(
ramfc
,
0x10
,
0x0000face
);
nvkm_wo32
(
ramfc
,
0x30
,
0xfffff902
);
nvkm_wo32
(
ramfc
,
0x48
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
ramfc
,
0x4c
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
ramfc
,
0x54
,
0x00000002
);
nvkm_wo32
(
ramfc
,
0x84
,
0x20400000
);
nvkm_wo32
(
ramfc
,
0x94
,
0x30000001
);
nvkm_wo32
(
ramfc
,
0x9c
,
0x00000100
);
nvkm_wo32
(
ramfc
,
0xa4
,
0x1f1f1f1f
);
nvkm_wo32
(
ramfc
,
0xa8
,
0x1f1f1f1f
);
nvkm_wo32
(
ramfc
,
0xac
,
0x0000001f
);
nvkm_wo32
(
ramfc
,
0xb8
,
0xf8000000
);
nvkm_wo32
(
ramfc
,
0xf8
,
0x10003080
);
/* 0x002310 */
nvkm_wo32
(
ramfc
,
0xfc
,
0x10000010
);
/* 0x002350 */
nvkm_done
(
ramfc
);
return
0
;
}
static
struct
nvkm_ofuncs
gf100_fifo_ofuncs
=
{
.
ctor
=
gf100_fifo_chan_ctor
,
.
dtor
=
_nvkm_fifo_channel_dtor
,
.
init
=
gf100_fifo_chan_init
,
.
fini
=
gf100_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
gf100_fifo_sclass
[]
=
{
{
FERMI_CHANNEL_GPFIFO
,
&
gf100_fifo_ofuncs
},
{}
};
static
int
gf100_fifo_context_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nvkm_device
*
device
=
nv_engine
(
engine
)
->
subdev
.
device
;
struct
gf100_fifo_base
*
base
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x1000
,
0x1000
,
NVOBJ_FLAG_ZERO_ALLOC
|
NVOBJ_FLAG_HEAP
,
&
base
);
*
pobject
=
nv_object
(
base
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x10000
,
0x1000
,
false
,
NULL
,
&
base
->
pgd
);
if
(
ret
)
return
ret
;
nvkm_kmap
(
&
base
->
base
.
gpuobj
);
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x0200
,
lower_32_bits
(
base
->
pgd
->
addr
));
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x0204
,
upper_32_bits
(
base
->
pgd
->
addr
));
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x0208
,
0xffffffff
);
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x020c
,
0x000000ff
);
nvkm_done
(
&
base
->
base
.
gpuobj
);
ret
=
nvkm_vm_ref
(
nvkm_client
(
parent
)
->
vm
,
&
base
->
vm
,
base
->
pgd
);
if
(
ret
)
return
ret
;
/* RAMFC */
nvkm_kmap
(
chan
->
base
.
inst
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x08
,
lower_32_bits
(
usermem
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x0c
,
upper_32_bits
(
usermem
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x10
,
0x0000face
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x30
,
0xfffff902
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x48
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x4c
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x54
,
0x00000002
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x84
,
0x20400000
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x94
,
0x30000001
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x9c
,
0x00000100
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xa4
,
0x1f1f1f1f
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xa8
,
0x1f1f1f1f
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xac
,
0x0000001f
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xb8
,
0xf8000000
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xf8
,
0x10003080
);
/* 0x002310 */
nvkm_wo32
(
chan
->
base
.
inst
,
0xfc
,
0x10000010
);
/* 0x002350 */
nvkm_done
(
chan
->
base
.
inst
);
return
0
;
}
static
void
gf100_fifo_context_dtor
(
struct
nvkm_object
*
object
)
{
struct
gf100_fifo_base
*
base
=
(
void
*
)
object
;
nvkm_vm_ref
(
NULL
,
&
base
->
vm
,
base
->
pgd
);
nvkm_gpuobj_del
(
&
base
->
pgd
);
nvkm_fifo_context_destroy
(
&
base
->
base
);
}
struct
nvkm_oclass
gf100_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0xc0
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
gf100_fifo_context_ctor
,
.
dtor
=
gf100_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
},
const
struct
nvkm_fifo_chan_oclass
gf100_fifo_gpfifo_oclass
=
{
.
base
.
oclass
=
FERMI_CHANNEL_GPFIFO
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
gf100_fifo_gpfifo_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
View file @
8f0649b5
...
...
@@ -31,30 +31,13 @@
#include <nvif/class.h>
#include <nvif/unpack.h>
#define _(a,b) { (a), ((1ULL << (a)) | (b)) }
static
const
struct
{
u64
subdev
;
u64
mask
;
}
fifo_engine
[]
=
{
_
(
NVDEV_ENGINE_GR
,
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_CE2
)),
_
(
NVDEV_ENGINE_MSPDEC
,
0
),
_
(
NVDEV_ENGINE_MSPPP
,
0
),
_
(
NVDEV_ENGINE_MSVLD
,
0
),
_
(
NVDEV_ENGINE_CE0
,
0
),
_
(
NVDEV_ENGINE_CE1
,
0
),
_
(
NVDEV_ENGINE_MSENC
,
0
),
};
#undef _
#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
static
int
gk104_fifo_
chan
_kick
(
struct
gk104_fifo_chan
*
chan
)
gk104_fifo_
gpfifo
_kick
(
struct
gk104_fifo_chan
*
chan
)
{
struct
nvkm_object
*
obj
=
(
void
*
)
chan
;
struct
gk104_fifo
*
fifo
=
(
void
*
)
obj
->
engine
;
struct
gk104_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
struct
nvkm_client
*
client
=
chan
->
base
.
object
.
client
;
nvkm_wr32
(
device
,
0x002634
,
chan
->
base
.
chid
);
if
(
nvkm_msec
(
device
,
2000
,
...
...
@@ -62,198 +45,249 @@ gk104_fifo_chan_kick(struct gk104_fifo_chan *chan)
break
;
)
<
0
)
{
nvkm_error
(
subdev
,
"channel %d [%s] kick timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
)
);
chan
->
base
.
chid
,
client
->
name
);
return
-
EBUSY
;
}
return
0
;
}
static
int
gk104_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
static
u32
gk104_fifo_gpfifo_engine_addr
(
struct
nvkm_engine
*
engine
)
{
struct
gk104_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
gk104_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nvkm_gpuobj
*
engn
=
&
base
->
base
.
gpuobj
;
u32
addr
;
int
ret
;
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
switch
(
engine
->
subdev
.
index
)
{
case
NVDEV_ENGINE_SW
:
case
NVDEV_ENGINE_CE0
:
case
NVDEV_ENGINE_CE1
:
case
NVDEV_ENGINE_CE2
:
addr
=
0x0000
;
break
;
case
NVDEV_ENGINE_GR
:
addr
=
0x0210
;
break
;
case
NVDEV_ENGINE_MS
VLD
:
addr
=
0x0270
;
break
;
case
NVDEV_ENGINE_MSP
DEC
:
addr
=
0x0250
;
break
;
case
NVDEV_ENGINE_MS
PPP
:
addr
=
0x0260
;
break
;
case
NVDEV_ENGINE_CE2
:
return
0x0000
;
case
NVDEV_ENGINE_GR
:
return
0x0210
;
case
NVDEV_ENGINE_MS
PDEC
:
return
0x0250
;
case
NVDEV_ENGINE_MSP
PP
:
return
0x0260
;
case
NVDEV_ENGINE_MS
VLD
:
return
0x0270
;
default:
return
-
EINVAL
;
WARN_ON
(
1
);
return
0
;
}
}
ret
=
gk104_fifo_chan_kick
(
chan
);
static
int
gk104_fifo_gpfifo_engine_fini
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
bool
suspend
)
{
const
u32
offset
=
gk104_fifo_gpfifo_engine_addr
(
engine
);
struct
gk104_fifo_chan
*
chan
=
gk104_fifo_chan
(
base
);
struct
nvkm_gpuobj
*
inst
=
chan
->
base
.
inst
;
int
ret
;
ret
=
gk104_fifo_gpfifo_kick
(
chan
);
if
(
ret
&&
suspend
)
return
ret
;
if
(
addr
)
{
nvkm_kmap
(
engn
);
nvkm_wo32
(
engn
,
addr
+
0x00
,
0x00000000
);
nvkm_wo32
(
engn
,
addr
+
0x04
,
0x00000000
);
nvkm_done
(
engn
);
if
(
offset
)
{
nvkm_kmap
(
inst
);
nvkm_wo32
(
inst
,
offset
+
0x00
,
0x00000000
);
nvkm_wo32
(
inst
,
offset
+
0x04
,
0x00000000
);
nvkm_done
(
inst
);
}
return
ret
;
}
static
int
gk104_fifo_gpfifo_engine_init
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
const
u32
offset
=
gk104_fifo_gpfifo_engine_addr
(
engine
);
struct
gk104_fifo_chan
*
chan
=
gk104_fifo_chan
(
base
);
struct
nvkm_gpuobj
*
inst
=
chan
->
base
.
inst
;
if
(
offset
)
{
u64
addr
=
chan
->
engn
[
engine
->
subdev
.
index
].
vma
.
offset
;
nvkm_kmap
(
inst
);
nvkm_wo32
(
inst
,
offset
+
0x00
,
lower_32_bits
(
addr
)
|
4
);
nvkm_wo32
(
inst
,
offset
+
0x04
,
upper_32_bits
(
addr
));
nvkm_done
(
inst
);
}
return
0
;
}
static
void
gk104_fifo_gpfifo_engine_dtor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
)
{
struct
gk104_fifo_chan
*
chan
=
gk104_fifo_chan
(
base
);
nvkm_gpuobj_unmap
(
&
chan
->
engn
[
engine
->
subdev
.
index
].
vma
);
nvkm_gpuobj_del
(
&
chan
->
engn
[
engine
->
subdev
.
index
].
inst
);
}
static
int
gk104_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
gk104_fifo_gpfifo_engine_ctor
(
struct
nvkm_fifo_chan
*
base
,
struct
nvkm_engine
*
engine
,
struct
nvkm_object
*
object
)
{
struct
gk104_fifo_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
nvkm_gpuobj
*
engn
=
&
base
->
base
.
gpuobj
;
struct
nvkm_engctx
*
ectx
=
(
void
*
)
object
;
u32
addr
;
struct
gk104_fifo_chan
*
chan
=
gk104_fifo_chan
(
base
);
int
engn
=
engine
->
subdev
.
index
;
int
ret
;
switch
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_CE0
:
case
NVDEV_ENGINE_CE1
:
case
NVDEV_ENGINE_CE2
:
nv_engctx
(
ectx
)
->
addr
=
nv_gpuobj
(
base
)
->
addr
>>
12
;
if
(
!
gk104_fifo_gpfifo_engine_addr
(
engine
))
return
0
;
case
NVDEV_ENGINE_GR
:
addr
=
0x0210
;
break
;
case
NVDEV_ENGINE_MSVLD
:
addr
=
0x0270
;
break
;
case
NVDEV_ENGINE_MSPDEC
:
addr
=
0x0250
;
break
;
case
NVDEV_ENGINE_MSPPP
:
addr
=
0x0260
;
break
;
default:
return
-
EINVAL
;
}
if
(
!
ectx
->
vma
.
node
)
{
ret
=
nvkm_gpuobj_map
(
nv_gpuobj
(
ectx
),
base
->
vm
,
NV_MEM_ACCESS_RW
,
&
ectx
->
vma
);
if
(
ret
)
return
ret
;
nv_engctx
(
ectx
)
->
addr
=
nv_gpuobj
(
base
)
->
addr
>>
12
;
if
(
object
->
oclass
)
{
return
nvkm_gpuobj_map
(
nv_gpuobj
(
object
),
chan
->
vm
,
NV_MEM_ACCESS_RW
,
&
chan
->
engn
[
engn
].
vma
);
}
nvkm_kmap
(
engn
);
nvkm_wo32
(
engn
,
addr
+
0x00
,
lower_32_bits
(
ectx
->
vma
.
offset
)
|
4
);
nvkm_wo32
(
engn
,
addr
+
0x04
,
upper_32_bits
(
ectx
->
vma
.
offset
));
nvkm_done
(
engn
);
return
0
;
ret
=
nvkm_object_bind
(
object
,
NULL
,
0
,
&
chan
->
engn
[
engn
].
inst
);
if
(
ret
)
return
ret
;
return
nvkm_gpuobj_map
(
chan
->
engn
[
engn
].
inst
,
chan
->
vm
,
NV_MEM_ACCESS_RW
,
&
chan
->
engn
[
engn
].
vma
);
}
static
int
gk104_fifo_
chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
static
void
gk104_fifo_
gpfifo_fini
(
struct
nvkm_fifo_chan
*
base
)
{
struct
gk104_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gk104_fifo
_chan
*
chan
=
(
void
*
)
object
;
struct
gk104_fifo
_chan
*
chan
=
gk104_fifo_chan
(
base
)
;
struct
gk104_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
c
hid
=
chan
->
base
.
chid
;
u32
c
off
=
chan
->
base
.
chid
*
8
;
if
(
chan
->
state
==
RUNNING
&&
(
chan
->
state
=
STOPPED
)
==
STOPPED
)
{
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
),
0x00000800
,
0x00000800
);
if
(
!
list_empty
(
&
chan
->
head
))
{
list_del_init
(
&
chan
->
head
);
nvkm_mask
(
device
,
0x800004
+
coff
,
0x00000800
,
0x00000800
);
gk104_fifo_runlist_update
(
fifo
,
chan
->
engine
);
}
nvkm_wr32
(
device
,
0x800000
+
(
chid
*
8
),
0x00000000
);
return
nvkm_fifo_channel_fini
(
&
chan
->
base
,
suspend
);
nvkm_wr32
(
device
,
0x800000
+
coff
,
0x00000000
);
}
static
int
gk104_fifo_
chan_init
(
struct
nvkm_object
*
object
)
static
void
gk104_fifo_
gpfifo_init
(
struct
nvkm_fifo_chan
*
base
)
{
struct
nvkm_gpuobj
*
base
=
nv_gpuobj
(
object
->
parent
);
struct
gk104_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gk104_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
gk104_fifo_chan
*
chan
=
gk104_fifo_chan
(
base
);
struct
gk104_fifo
*
fifo
=
chan
->
fifo
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
int
ret
;
u32
addr
=
chan
->
base
.
inst
->
addr
>>
12
;
u32
coff
=
chan
->
base
.
chid
*
8
;
ret
=
nvkm_fifo_channel_init
(
&
chan
->
base
);
if
(
ret
)
return
ret
;
nvkm_mask
(
device
,
0x800004
+
coff
,
0x000f0000
,
chan
->
engine
<<
16
);
nvkm_wr32
(
device
,
0x800000
+
coff
,
0x80000000
|
addr
);
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
),
0x000f0000
,
chan
->
engine
<<
16
);
nvkm_wr32
(
device
,
0x800000
+
(
chid
*
8
),
0x80000000
|
base
->
addr
>>
12
);
if
(
chan
->
state
==
STOPPED
&&
(
chan
->
state
=
RUNNING
)
==
RUNNING
)
{
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
),
0x00000400
,
0x00000400
);
if
(
list_empty
(
&
chan
->
head
)
&&
!
chan
->
killed
)
{
list_add_tail
(
&
chan
->
head
,
&
fifo
->
engine
[
chan
->
engine
].
chan
);
nvkm_mask
(
device
,
0x800004
+
coff
,
0x00000400
,
0x00000400
);
gk104_fifo_runlist_update
(
fifo
,
chan
->
engine
);
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
)
,
0x00000400
,
0x00000400
);
nvkm_mask
(
device
,
0x800004
+
coff
,
0x00000400
,
0x00000400
);
}
}
return
0
;
static
void
*
gk104_fifo_gpfifo_dtor
(
struct
nvkm_fifo_chan
*
base
)
{
struct
gk104_fifo_chan
*
chan
=
gk104_fifo_chan
(
base
);
nvkm_vm_ref
(
NULL
,
&
chan
->
vm
,
chan
->
pgd
);
nvkm_gpuobj_del
(
&
chan
->
pgd
);
return
chan
;
}
static
int
gk104_fifo_chan_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
static
const
struct
nvkm_fifo_chan_func
gk104_fifo_gpfifo_func
=
{
.
dtor
=
gk104_fifo_gpfifo_dtor
,
.
init
=
gk104_fifo_gpfifo_init
,
.
fini
=
gk104_fifo_gpfifo_fini
,
.
ntfy
=
g84_fifo_chan_ntfy
,
.
engine_ctor
=
gk104_fifo_gpfifo_engine_ctor
,
.
engine_dtor
=
gk104_fifo_gpfifo_engine_dtor
,
.
engine_init
=
gk104_fifo_gpfifo_engine_init
,
.
engine_fini
=
gk104_fifo_gpfifo_engine_fini
,
};
int
gk104_fifo_gpfifo_new
(
struct
nvkm_fifo
*
base
,
const
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
union
{
struct
kepler_channel_gpfifo_a_v0
v0
;
}
*
args
=
data
;
struct
gk104_fifo
*
fifo
=
(
void
*
)
engine
;
struct
gk104_fifo_base
*
base
=
(
void
*
)
parent
;
struct
gk104_fifo
*
fifo
=
gk104_fifo
(
base
);
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_object
*
parent
=
oclass
->
parent
;
struct
gk104_fifo_chan
*
chan
;
struct
nvkm_gpuobj
*
ramfc
=
&
base
->
base
.
gpuobj
;
u64
usermem
,
ioffset
,
ilength
;
u32
engines
;
int
ret
,
i
;
nvif_ioctl
(
parent
,
"create channel gpfifo size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel gpfifo vers %d vm %llx"
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
.
engine
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
else
return
ret
;
for
(
i
=
0
,
engines
=
0
;
i
<
FIFO_ENGINE_NR
;
i
++
)
{
if
(
!
nvkm_engine
(
parent
,
fifo_engine
[
i
].
subdev
))
/* determine which downstream engines are present */
for
(
i
=
0
,
engines
=
0
;
i
<
ARRAY_SIZE
(
fifo
->
engine
);
i
++
)
{
u64
subdevs
=
gk104_fifo_engine_subdev
(
i
);
if
(
!
nvkm_device_engine
(
device
,
__ffs64
(
subdevs
)))
continue
;
engines
|=
(
1
<<
i
);
}
/* if this is an engine mask query, we're done */
if
(
!
args
->
v0
.
engine
)
{
static
struct
nvkm_oclass
oclass
=
{
.
ofuncs
=
&
nvkm_object_ofuncs
,
};
args
->
v0
.
engine
=
engines
;
return
nvkm_object_
old
(
parent
,
engine
,
&
oclass
,
NULL
,
0
,
pobject
);
return
nvkm_object_
new
(
oclass
,
NULL
,
0
,
pobject
);
}
engines
&=
args
->
v0
.
engine
;
if
(
!
engines
)
{
nvif_ioctl
(
parent
,
"unsupported engines %08x
\n
"
,
args
->
v0
.
engine
);
/* check that we support a requested engine - note that the user
* argument is a mask in order to allow the user to request (for
* example) *any* copy engine, but doesn't matter which.
*/
args
->
v0
.
engine
&=
engines
;
if
(
!
args
->
v0
.
engine
)
{
nvif_ioctl
(
parent
,
"no supported engine
\n
"
);
return
-
ENODEV
;
}
i
=
__ffs
(
engines
);
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
1
,
fifo
->
user
.
bar
.
offset
,
0x200
,
0
,
fifo_engine
[
i
].
mask
,
&
chan
);
*
pobject
=
nv_object
(
chan
);
/* allocate the channel */
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
chan
->
fifo
=
fifo
;
chan
->
engine
=
__ffs
(
args
->
v0
.
engine
);
INIT_LIST_HEAD
(
&
chan
->
head
);
ret
=
nvkm_fifo_chan_ctor
(
&
gk104_fifo_gpfifo_func
,
&
fifo
->
base
,
0x1000
,
0x1000
,
true
,
args
->
v0
.
vm
,
0
,
gk104_fifo_engine_subdev
(
chan
->
engine
),
1
,
fifo
->
user
.
bar
.
offset
,
0x200
,
oclass
,
&
chan
->
base
);
if
(
ret
)
return
ret
;
chan
->
base
.
inst
=
base
->
base
.
gpuobj
.
addr
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
context_attach
=
gk104_fifo_context_attach
;
nv_parent
(
chan
)
->
context_detach
=
gk104_fifo_context_detach
;
chan
->
engine
=
i
;
/* page directory */
ret
=
nvkm_gpuobj_new
(
device
,
0x10000
,
0x1000
,
false
,
NULL
,
&
chan
->
pgd
);
if
(
ret
)
return
ret
;
nvkm_kmap
(
chan
->
base
.
inst
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x0200
,
lower_32_bits
(
chan
->
pgd
->
addr
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x0204
,
upper_32_bits
(
chan
->
pgd
->
addr
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x0208
,
0xffffffff
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x020c
,
0x000000ff
);
nvkm_done
(
chan
->
base
.
inst
);
ret
=
nvkm_vm_ref
(
chan
->
base
.
vm
,
&
chan
->
vm
,
chan
->
pgd
);
if
(
ret
)
return
ret
;
/* clear channel control registers */
usermem
=
chan
->
base
.
chid
*
0x200
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
...
...
@@ -264,94 +298,31 @@ gk104_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nvkm_done
(
fifo
->
user
.
mem
);
usermem
=
nvkm_memory_addr
(
fifo
->
user
.
mem
)
+
usermem
;
nvkm_kmap
(
ramfc
);
nvkm_wo32
(
ramfc
,
0x08
,
lower_32_bits
(
usermem
));
nvkm_wo32
(
ramfc
,
0x0c
,
upper_32_bits
(
usermem
));
nvkm_wo32
(
ramfc
,
0x10
,
0x0000face
);
nvkm_wo32
(
ramfc
,
0x30
,
0xfffff902
);
nvkm_wo32
(
ramfc
,
0x48
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
ramfc
,
0x4c
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
ramfc
,
0x84
,
0x20400000
);
nvkm_wo32
(
ramfc
,
0x94
,
0x30000001
);
nvkm_wo32
(
ramfc
,
0x9c
,
0x00000100
);
nvkm_wo32
(
ramfc
,
0xac
,
0x0000001f
);
nvkm_wo32
(
ramfc
,
0xe8
,
chan
->
base
.
chid
);
nvkm_wo32
(
ramfc
,
0xb8
,
0xf8000000
);
nvkm_wo32
(
ramfc
,
0xf8
,
0x10003080
);
/* 0x002310 */
nvkm_wo32
(
ramfc
,
0xfc
,
0x10000010
);
/* 0x002350 */
nvkm_done
(
ramfc
);
return
0
;
}
struct
nvkm_ofuncs
gk104_fifo_chan_ofuncs
=
{
.
ctor
=
gk104_fifo_chan_ctor
,
.
dtor
=
_nvkm_fifo_channel_dtor
,
.
init
=
gk104_fifo_chan_init
,
.
fini
=
gk104_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
};
struct
nvkm_oclass
gk104_fifo_sclass
[]
=
{
{
KEPLER_CHANNEL_GPFIFO_A
,
&
gk104_fifo_chan_ofuncs
},
{}
};
static
int
gk104_fifo_context_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nvkm_device
*
device
=
nv_engine
(
engine
)
->
subdev
.
device
;
struct
gk104_fifo_base
*
base
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x1000
,
0x1000
,
NVOBJ_FLAG_ZERO_ALLOC
,
&
base
);
*
pobject
=
nv_object
(
base
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x10000
,
0x1000
,
false
,
NULL
,
&
base
->
pgd
);
if
(
ret
)
return
ret
;
nvkm_kmap
(
&
base
->
base
.
gpuobj
);
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x0200
,
lower_32_bits
(
base
->
pgd
->
addr
));
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x0204
,
upper_32_bits
(
base
->
pgd
->
addr
));
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x0208
,
0xffffffff
);
nvkm_wo32
(
&
base
->
base
.
gpuobj
,
0x020c
,
0x000000ff
);
nvkm_done
(
&
base
->
base
.
gpuobj
);
ret
=
nvkm_vm_ref
(
nvkm_client
(
parent
)
->
vm
,
&
base
->
vm
,
base
->
pgd
);
if
(
ret
)
return
ret
;
/* RAMFC */
nvkm_kmap
(
chan
->
base
.
inst
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x08
,
lower_32_bits
(
usermem
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x0c
,
upper_32_bits
(
usermem
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x10
,
0x0000face
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x30
,
0xfffff902
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x48
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x4c
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
chan
->
base
.
inst
,
0x84
,
0x20400000
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x94
,
0x30000001
);
nvkm_wo32
(
chan
->
base
.
inst
,
0x9c
,
0x00000100
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xac
,
0x0000001f
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xe8
,
chan
->
base
.
chid
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xb8
,
0xf8000000
);
nvkm_wo32
(
chan
->
base
.
inst
,
0xf8
,
0x10003080
);
/* 0x002310 */
nvkm_wo32
(
chan
->
base
.
inst
,
0xfc
,
0x10000010
);
/* 0x002350 */
nvkm_done
(
chan
->
base
.
inst
);
return
0
;
}
static
void
gk104_fifo_context_dtor
(
struct
nvkm_object
*
object
)
{
struct
gk104_fifo_base
*
base
=
(
void
*
)
object
;
nvkm_vm_ref
(
NULL
,
&
base
->
vm
,
base
->
pgd
);
nvkm_gpuobj_del
(
&
base
->
pgd
);
nvkm_fifo_context_destroy
(
&
base
->
base
);
}
struct
nvkm_oclass
gk104_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0xe0
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
gk104_fifo_context_ctor
,
.
dtor
=
gk104_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
},
const
struct
nvkm_fifo_chan_oclass
gk104_fifo_gpfifo_oclass
=
{
.
base
.
oclass
=
KEPLER_CHANNEL_GPFIFO_A
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
gk104_fifo_gpfifo_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm204.c
View file @
8f0649b5
...
...
@@ -25,8 +25,10 @@
#include <nvif/class.h>
struct
nvkm_oclass
gm204_fifo_sclass
[]
=
{
{
MAXWELL_CHANNEL_GPFIFO_A
,
&
gk104_fifo_chan_ofuncs
},
{}
const
struct
nvkm_fifo_chan_oclass
gm204_fifo_gpfifo_oclass
=
{
.
base
.
oclass
=
MAXWELL_CHANNEL_GPFIFO_A
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
gk104_fifo_gpfifo_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c
View file @
8f0649b5
...
...
@@ -30,15 +30,14 @@
#include <nvif/unpack.h>
static
int
nv50_fifo_chan_ctor_ind
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
nv50_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
nv50_channel_gpfifo_v0
v0
;
}
*
args
=
data
;
struct
nvkm_device
*
device
=
parent
->
engine
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
=
(
void
*
)
parent
;
struct
nv50_fifo
*
fifo
=
nv50_fifo
(
base
);
struct
nv50_fifo_chan
*
chan
;
u64
ioffset
,
ilength
;
int
ret
;
...
...
@@ -50,61 +49,44 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
"ilength %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
);
if
(
args
->
v0
.
vm
)
return
-
E
NOENT
;
if
(
!
args
->
v0
.
pushbuf
)
return
-
E
INVAL
;
}
else
return
ret
;
ret
=
nvkm_fifo_channel_create
(
parent
,
engine
,
oclass
,
0
,
0xc00000
,
0x2000
,
args
->
v0
.
pushbuf
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
)
|
(
1ULL
<<
NVDEV_ENGINE_SW
)
|
(
1ULL
<<
NVDEV_ENGINE_GR
)
|
(
1ULL
<<
NVDEV_ENGINE_MPEG
),
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
ret
)
return
ret
;
chan
->
base
.
inst
=
base
->
base
.
gpuobj
.
addr
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
nv_parent
(
chan
)
->
context_attach
=
nv50_fifo_context_attach
;
nv_parent
(
chan
)
->
context_detach
=
nv50_fifo_context_detach
;
nv_parent
(
chan
)
->
object_attach
=
nv50_fifo_object_attach
;
nv_parent
(
chan
)
->
object_detach
=
nv50_fifo_object_detach
;
if
(
!
(
chan
=
kzalloc
(
sizeof
(
*
chan
),
GFP_KERNEL
)))
return
-
ENOMEM
;
*
pobject
=
&
chan
->
base
.
object
;
ret
=
nv
km_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
ret
=
nv
50_fifo_chan_ctor
(
fifo
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
oclass
,
chan
);
if
(
ret
)
return
ret
;
args
->
v0
.
chid
=
chan
->
base
.
chid
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
nvkm_kmap
(
base
->
ramfc
);
nvkm_wo32
(
base
->
ramfc
,
0x3c
,
0x403f6078
);
nvkm_wo32
(
base
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
base
->
ramfc
,
0x48
,
chan
->
base
.
pushgpu
->
node
->
offset
>>
4
);
nvkm_wo32
(
base
->
ramfc
,
0x50
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
base
->
ramfc
,
0x54
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
base
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
base
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
base
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
base
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
nvkm_kmap
(
chan
->
ramfc
);
nvkm_wo32
(
chan
->
ramfc
,
0x3c
,
0x403f6078
);
nvkm_wo32
(
chan
->
ramfc
,
0x44
,
0x01003fff
);
nvkm_wo32
(
chan
->
ramfc
,
0x48
,
chan
->
base
.
push
->
node
->
offset
>>
4
);
nvkm_wo32
(
chan
->
ramfc
,
0x50
,
lower_32_bits
(
ioffset
));
nvkm_wo32
(
chan
->
ramfc
,
0x54
,
upper_32_bits
(
ioffset
)
|
(
ilength
<<
16
));
nvkm_wo32
(
chan
->
ramfc
,
0x60
,
0x7fffffff
);
nvkm_wo32
(
chan
->
ramfc
,
0x78
,
0x00000000
);
nvkm_wo32
(
chan
->
ramfc
,
0x7c
,
0x30000001
);
nvkm_wo32
(
chan
->
ramfc
,
0x80
,
((
chan
->
ramht
->
bits
-
9
)
<<
27
)
|
(
4
<<
24
)
/* SEARCH_FULL */
|
(
chan
->
ramht
->
gpuobj
->
node
->
offset
>>
4
));
nvkm_done
(
base
->
ramfc
);
nvkm_done
(
chan
->
ramfc
);
return
0
;
}
struct
nvkm_ofuncs
nv50_fifo_ofuncs_ind
=
{
.
ctor
=
nv50_fifo_chan_ctor_ind
,
.
dtor
=
nv50_fifo_chan_dtor
,
.
init
=
nv50_fifo_chan_init
,
.
fini
=
nv50_fifo_chan_fini
,
.
map
=
_nvkm_fifo_channel_map
,
.
rd32
=
_nvkm_fifo_channel_rd32
,
.
wr32
=
_nvkm_fifo_channel_wr32
,
.
ntfy
=
_nvkm_fifo_channel_ntfy
const
struct
nvkm_fifo_chan_oclass
nv50_fifo_gpfifo_oclass
=
{
.
base
.
oclass
=
NV50_CHANNEL_GPFIFO
,
.
base
.
minver
=
0
,
.
base
.
maxver
=
0
,
.
ctor
=
nv50_fifo_gpfifo_new
,
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
View file @
8f0649b5
...
...
@@ -25,6 +25,7 @@
#include "channv04.h"
#include "regsnv04.h"
#include <core/client.h>
#include <core/handle.h>
#include <core/ramht.h>
#include <subdev/instmem.h>
...
...
@@ -136,6 +137,8 @@ nv04_fifo_cache_error(struct nv04_fifo *fifo, u32 chid, u32 get)
{
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
struct
nvkm_fifo_chan
*
chan
;
unsigned
long
flags
;
u32
pull0
=
nvkm_rd32
(
device
,
0x003250
);
u32
mthd
,
data
;
int
ptr
;
...
...
@@ -157,12 +160,12 @@ nv04_fifo_cache_error(struct nv04_fifo *fifo, u32 chid, u32 get)
if
(
!
(
pull0
&
0x00000100
)
||
!
nv04_fifo_swmthd
(
device
,
chid
,
mthd
,
data
))
{
const
char
*
client_name
=
nvkm_client_name_for_fifo_chid
(
&
fifo
->
base
,
chid
);
chan
=
nvkm_fifo_chan_chid
(
&
fifo
->
base
,
chid
,
&
flags
);
nvkm_error
(
subdev
,
"CACHE_ERROR - "
"ch %d [%s] subc %d mthd %04x data %08x
\n
"
,
chid
,
client_name
,
(
mthd
>>
13
)
&
7
,
mthd
&
0x1ffc
,
data
);
chid
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
(
mthd
>>
13
)
&
7
,
mthd
&
0x1ffc
,
data
);
nvkm_fifo_chan_put
(
&
fifo
->
base
,
flags
,
&
chan
);
}
nvkm_wr32
(
device
,
NV04_PFIFO_CACHE1_DMA_PUSH
,
0
);
...
...
@@ -189,10 +192,12 @@ nv04_fifo_dma_pusher(struct nv04_fifo *fifo, u32 chid)
u32
dma_put
=
nvkm_rd32
(
device
,
0x003240
);
u32
push
=
nvkm_rd32
(
device
,
0x003220
);
u32
state
=
nvkm_rd32
(
device
,
0x003228
);
const
char
*
client_name
;
c
lient_name
=
nvkm_client_name_for_fifo_chid
(
&
fifo
->
base
,
chid
)
;
struct
nvkm_fifo_chan
*
chan
;
unsigned
long
flags
;
c
onst
char
*
name
;
chan
=
nvkm_fifo_chan_chid
(
&
fifo
->
base
,
chid
,
&
flags
);
name
=
chan
?
chan
->
object
.
client
->
name
:
"unknown"
;
if
(
device
->
card_type
==
NV_50
)
{
u32
ho_get
=
nvkm_rd32
(
device
,
0x003328
);
u32
ho_put
=
nvkm_rd32
(
device
,
0x003320
);
...
...
@@ -202,7 +207,7 @@ nv04_fifo_dma_pusher(struct nv04_fifo *fifo, u32 chid)
nvkm_error
(
subdev
,
"DMA_PUSHER - "
"ch %d [%s] get %02x%08x put %02x%08x ib_get %08x "
"ib_put %08x state %08x (err: %s) push %08x
\n
"
,
chid
,
client_
name
,
ho_get
,
dma_get
,
ho_put
,
dma_put
,
chid
,
name
,
ho_get
,
dma_get
,
ho_put
,
dma_put
,
ib_get
,
ib_put
,
state
,
nv_dma_state_err
(
state
),
push
);
...
...
@@ -217,12 +222,13 @@ nv04_fifo_dma_pusher(struct nv04_fifo *fifo, u32 chid)
}
else
{
nvkm_error
(
subdev
,
"DMA_PUSHER - ch %d [%s] get %08x put %08x "
"state %08x (err: %s) push %08x
\n
"
,
chid
,
client_
name
,
dma_get
,
dma_put
,
state
,
chid
,
name
,
dma_get
,
dma_put
,
state
,
nv_dma_state_err
(
state
),
push
);
if
(
dma_get
!=
dma_put
)
nvkm_wr32
(
device
,
0x003244
,
dma_put
);
}
nvkm_fifo_chan_put
(
&
fifo
->
base
,
flags
,
&
chan
);
nvkm_wr32
(
device
,
0x003228
,
0x00000000
);
nvkm_wr32
(
device
,
0x003220
,
0x00000001
);
...
...
@@ -241,7 +247,7 @@ nv04_fifo_intr(struct nvkm_subdev *subdev)
reassign
=
nvkm_rd32
(
device
,
NV03_PFIFO_CACHES
)
&
1
;
nvkm_wr32
(
device
,
NV03_PFIFO_CACHES
,
0
);
chid
=
nvkm_rd32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
)
&
fifo
->
base
.
max
;
chid
=
nvkm_rd32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
)
&
(
fifo
->
base
.
nr
-
1
)
;
get
=
nvkm_rd32
(
device
,
NV03_PFIFO_CACHE1_GET
);
if
(
stat
&
NV_PFIFO_INTR_CACHE_ERROR
)
{
...
...
@@ -311,7 +317,7 @@ nv04_fifo_init(struct nvkm_object *object)
nvkm_wr32
(
device
,
NV03_PFIFO_RAMRO
,
nvkm_memory_addr
(
ramro
)
>>
8
);
nvkm_wr32
(
device
,
NV03_PFIFO_RAMFC
,
nvkm_memory_addr
(
ramfc
)
>>
8
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
fifo
->
base
.
max
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
fifo
->
base
.
nr
-
1
);
nvkm_wr32
(
device
,
NV03_PFIFO_INTR_0
,
0xffffffff
);
nvkm_wr32
(
device
,
NV03_PFIFO_INTR_EN_0
,
0xffffffff
);
...
...
@@ -329,6 +335,14 @@ nv04_fifo_dtor(struct nvkm_object *object)
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
static
const
struct
nvkm_fifo_func
nv04_fifo_func
=
{
.
chan
=
{
&
nv04_fifo_dma_oclass
,
NULL
},
};
static
int
nv04_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -342,10 +356,10 @@ nv04_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
nv04_fifo_func
;
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
nv04_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
nv04_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
nv04_fifo_sclass
;
fifo
->
base
.
pause
=
nv04_fifo_pause
;
fifo
->
base
.
start
=
nv04_fifo_start
;
fifo
->
ramfc_desc
=
nv04_ramfc
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
View file @
8f0649b5
#ifndef __NV04_FIFO_H__
#define __NV04_FIFO_H__
#define nv04_fifo(p) container_of((p), struct nv04_fifo, base)
#include "priv.h"
struct
ramfc_desc
{
...
...
@@ -15,14 +16,6 @@ struct nv04_fifo {
struct
ramfc_desc
*
ramfc_desc
;
};
struct
nv04_fifo_base
{
struct
nvkm_fifo_base
base
;
};
int
nv04_fifo_context_ctor
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
struct
nvkm_oclass
*
,
void
*
,
u32
,
struct
nvkm_object
**
);
void
nv04_fifo_dtor
(
struct
nvkm_object
*
);
int
nv04_fifo_init
(
struct
nvkm_object
*
);
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
View file @
8f0649b5
...
...
@@ -39,16 +39,11 @@ nv10_ramfc[] = {
{}
};
static
struct
nvkm_oclass
nv10_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0x10
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
nv04_fifo_context_ctor
,
.
dtor
=
_nvkm_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
static
const
struct
nvkm_fifo_func
nv10_fifo_func
=
{
.
chan
=
{
&
nv10_fifo_dma_oclass
,
NULL
},
};
...
...
@@ -65,10 +60,10 @@ nv10_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
nv10_fifo_func
;
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
nv04_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
nv10_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
nv10_fifo_sclass
;
fifo
->
base
.
pause
=
nv04_fifo_pause
;
fifo
->
base
.
start
=
nv04_fifo_start
;
fifo
->
ramfc_desc
=
nv10_ramfc
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
View file @
8f0649b5
...
...
@@ -47,19 +47,6 @@ nv17_ramfc[] = {
{}
};
static
struct
nvkm_oclass
nv17_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0x17
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
nv04_fifo_context_ctor
,
.
dtor
=
_nvkm_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
},
};
static
int
nv17_fifo_init
(
struct
nvkm_object
*
object
)
{
...
...
@@ -85,7 +72,7 @@ nv17_fifo_init(struct nvkm_object *object)
nvkm_wr32
(
device
,
NV03_PFIFO_RAMFC
,
nvkm_memory_addr
(
ramfc
)
>>
8
|
0x00010000
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
fifo
->
base
.
max
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
fifo
->
base
.
nr
-
1
);
nvkm_wr32
(
device
,
NV03_PFIFO_INTR_0
,
0xffffffff
);
nvkm_wr32
(
device
,
NV03_PFIFO_INTR_EN_0
,
0xffffffff
);
...
...
@@ -96,6 +83,14 @@ nv17_fifo_init(struct nvkm_object *object)
return
0
;
}
static
const
struct
nvkm_fifo_func
nv17_fifo_func
=
{
.
chan
=
{
&
nv17_fifo_dma_oclass
,
NULL
},
};
static
int
nv17_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -109,10 +104,10 @@ nv17_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
nv17_fifo_func
;
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
nv04_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
nv17_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
nv17_fifo_sclass
;
fifo
->
base
.
pause
=
nv04_fifo_pause
;
fifo
->
base
.
start
=
nv04_fifo_start
;
fifo
->
ramfc_desc
=
nv17_ramfc
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
View file @
8f0649b5
...
...
@@ -56,19 +56,6 @@ nv40_ramfc[] = {
{}
};
static
struct
nvkm_oclass
nv40_fifo_cclass
=
{
.
handle
=
NV_ENGCTX
(
FIFO
,
0x40
),
.
ofuncs
=
&
(
struct
nvkm_ofuncs
)
{
.
ctor
=
nv04_fifo_context_ctor
,
.
dtor
=
_nvkm_fifo_context_dtor
,
.
init
=
_nvkm_fifo_context_init
,
.
fini
=
_nvkm_fifo_context_fini
,
.
rd32
=
_nvkm_fifo_context_rd32
,
.
wr32
=
_nvkm_fifo_context_wr32
,
},
};
static
int
nv40_fifo_init
(
struct
nvkm_object
*
object
)
{
...
...
@@ -115,7 +102,7 @@ nv40_fifo_init(struct nvkm_object *object)
break
;
}
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
fifo
->
base
.
max
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH1
,
fifo
->
base
.
nr
-
1
);
nvkm_wr32
(
device
,
NV03_PFIFO_INTR_0
,
0xffffffff
);
nvkm_wr32
(
device
,
NV03_PFIFO_INTR_EN_0
,
0xffffffff
);
...
...
@@ -126,6 +113,14 @@ nv40_fifo_init(struct nvkm_object *object)
return
0
;
}
static
const
struct
nvkm_fifo_func
nv40_fifo_func
=
{
.
chan
=
{
&
nv40_fifo_dma_oclass
,
NULL
},
};
static
int
nv40_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -139,10 +134,10 @@ nv40_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
nv40_fifo_func
;
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
nv04_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
nv40_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
nv40_fifo_sclass
;
fifo
->
base
.
pause
=
nv04_fifo_pause
;
fifo
->
base
.
start
=
nv04_fifo_start
;
fifo
->
ramfc_desc
=
nv40_ramfc
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
View file @
8f0649b5
...
...
@@ -35,7 +35,7 @@ nv50_fifo_runlist_update_locked(struct nv50_fifo *fifo)
fifo
->
cur_runlist
=
!
fifo
->
cur_runlist
;
nvkm_kmap
(
cur
);
for
(
i
=
fifo
->
base
.
min
,
p
=
0
;
i
<
fifo
->
base
.
max
;
i
++
)
{
for
(
i
=
0
,
p
=
0
;
i
<
fifo
->
base
.
nr
;
i
++
)
{
if
(
nvkm_rd32
(
device
,
0x002600
+
(
i
*
4
))
&
0x80000000
)
nvkm_wo32
(
cur
,
p
++
*
4
,
i
);
}
...
...
@@ -94,6 +94,15 @@ nv50_fifo_dtor(struct nvkm_object *object)
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
static
const
struct
nvkm_fifo_func
nv50_fifo_func
=
{
.
chan
=
{
&
nv50_fifo_dma_oclass
,
&
nv50_fifo_gpfifo_oclass
,
NULL
},
};
static
int
nv50_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -108,6 +117,8 @@ nv50_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if
(
ret
)
return
ret
;
fifo
->
base
.
func
=
&
nv50_fifo_func
;
ret
=
nvkm_memory_new
(
device
,
NVKM_MEM_TARGET_INST
,
128
*
4
,
0x1000
,
false
,
&
fifo
->
runlist
[
0
]);
if
(
ret
)
...
...
@@ -120,8 +131,6 @@ nv50_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nv_subdev
(
fifo
)
->
unit
=
0x00000100
;
nv_subdev
(
fifo
)
->
intr
=
nv04_fifo_intr
;
nv_engine
(
fifo
)
->
cclass
=
&
nv50_fifo_cclass
;
nv_engine
(
fifo
)
->
sclass
=
nv50_fifo_sclass
;
fifo
->
base
.
pause
=
nv04_fifo_pause
;
fifo
->
base
.
start
=
nv04_fifo_start
;
return
0
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
View file @
8f0649b5
#ifndef __NV50_FIFO_H__
#define __NV50_FIFO_H__
#define nv50_fifo(p) container_of((p), struct nv50_fifo, base)
#include "priv.h"
struct
nv50_fifo
{
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
View file @
8f0649b5
#ifndef __NVKM_FIFO_PRIV_H__
#define __NVKM_FIFO_PRIV_H__
#include <engine/fifo.h>
#include <core/engctx.h>
void
nv04_fifo_pause
(
struct
nvkm_fifo
*
,
unsigned
long
*
);
void
nv04_fifo_start
(
struct
nvkm_fifo
*
,
unsigned
long
*
);
...
...
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
View file @
8f0649b5
...
...
@@ -1168,10 +1168,14 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
u32
data
=
nvkm_rd32
(
device
,
0x400708
);
u32
code
=
nvkm_rd32
(
device
,
0x400110
);
u32
class
;
int
chid
;
const
char
*
name
=
"unknown"
;
int
chid
=
-
1
;
chan
=
nvkm_fifo_chan_inst
(
device
->
fifo
,
(
u64
)
inst
<<
12
,
&
flags
);
chid
=
chan
?
chan
->
chid
:
-
1
;
if
(
chan
)
{
name
=
chan
->
object
.
client
->
name
;
chid
=
chan
->
chid
;
}
if
(
nv_device
(
gr
)
->
card_type
<
NV_E0
||
subc
<
4
)
class
=
nvkm_rd32
(
device
,
0x404200
+
(
subc
*
4
));
...
...
@@ -1191,8 +1195,8 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
if
(
!
gf100_gr_mthd_sw
(
device
,
class
,
mthd
,
data
))
{
nvkm_error
(
subdev
,
"ILLEGAL_MTHD ch %d [%010llx %s] "
"subc %d class %04x mthd %04x data %08x
\n
"
,
chid
,
inst
<<
12
,
n
vkm_client_name
(
chan
)
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
<<
12
,
n
ame
,
subc
,
class
,
mthd
,
data
);
}
nvkm_wr32
(
device
,
0x400100
,
0x00000010
);
stat
&=
~
0x00000010
;
...
...
@@ -1201,8 +1205,7 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
if
(
stat
&
0x00000020
)
{
nvkm_error
(
subdev
,
"ILLEGAL_CLASS ch %d [%010llx %s] "
"subc %d class %04x mthd %04x data %08x
\n
"
,
chid
,
inst
<<
12
,
nvkm_client_name
(
chan
),
subc
,
class
,
mthd
,
data
);
chid
,
inst
<<
12
,
name
,
subc
,
class
,
mthd
,
data
);
nvkm_wr32
(
device
,
0x400100
,
0x00000020
);
stat
&=
~
0x00000020
;
}
...
...
@@ -1213,14 +1216,14 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
nvkm_error
(
subdev
,
"DATA_ERROR %08x [%s] ch %d [%010llx %s] "
"subc %d class %04x mthd %04x data %08x
\n
"
,
code
,
en
?
en
->
name
:
""
,
chid
,
inst
<<
12
,
n
vkm_client_name
(
chan
)
,
subc
,
class
,
mthd
,
data
);
n
ame
,
subc
,
class
,
mthd
,
data
);
nvkm_wr32
(
device
,
0x400100
,
0x00100000
);
stat
&=
~
0x00100000
;
}
if
(
stat
&
0x00200000
)
{
nvkm_error
(
subdev
,
"TRAP ch %d [%010llx %s]
\n
"
,
chid
,
inst
<<
12
,
n
vkm_client_name
(
chan
)
);
chid
,
inst
<<
12
,
n
ame
);
gf100_gr_trap_intr
(
gr
);
nvkm_wr32
(
device
,
0x400100
,
0x00200000
);
stat
&=
~
0x00200000
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
View file @
8f0649b5
...
...
@@ -230,7 +230,8 @@ nv20_gr_intr(struct nvkm_subdev *subdev)
"nstatus %08x [%s] ch %d [%s] subc %d "
"class %04x mthd %04x data %08x
\n
"
,
show
,
msg
,
nsource
,
src
,
nstatus
,
sta
,
chid
,
nvkm_client_name
(
chan
),
subc
,
class
,
mthd
,
data
);
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
subc
,
class
,
mthd
,
data
);
}
nvkm_fifo_chan_put
(
device
->
fifo
,
flags
,
&
chan
);
...
...
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
View file @
8f0649b5
...
...
@@ -353,7 +353,8 @@ nv40_gr_intr(struct nvkm_subdev *subdev)
"class %04x mthd %04x data %08x
\n
"
,
show
,
msg
,
nsource
,
src
,
nstatus
,
sta
,
chan
?
chan
->
fifo
->
chid
:
-
1
,
inst
<<
4
,
nvkm_client_name
(
chan
),
subc
,
class
,
mthd
,
data
);
chan
?
chan
->
fifo
->
object
.
client
->
name
:
"unknown"
,
subc
,
class
,
mthd
,
data
);
}
spin_unlock_irqrestore
(
&
gr
->
base
.
engine
.
lock
,
flags
);
...
...
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
View file @
8f0649b5
...
...
@@ -608,7 +608,7 @@ nv50_gr_tp_trap(struct nv50_gr *gr, int type, u32 ustatus_old,
static
int
nv50_gr_trap_handler
(
struct
nv50_gr
*
gr
,
u32
display
,
int
chid
,
u64
inst
,
struct
nvkm_fifo_chan
*
chan
)
int
chid
,
u64
inst
,
const
char
*
name
)
{
struct
nvkm_subdev
*
subdev
=
&
gr
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
...
...
@@ -648,8 +648,7 @@ nv50_gr_trap_handler(struct nv50_gr *gr, u32 display,
"ch %d [%010llx %s] subc %d "
"class %04x mthd %04x data %08x%08x "
"400808 %08x 400848 %08x
\n
"
,
chid
,
inst
,
nvkm_client_name
(
chan
),
subc
,
class
,
mthd
,
chid
,
inst
,
name
,
subc
,
class
,
mthd
,
datah
,
datal
,
addr
,
r848
);
}
else
if
(
display
)
{
...
...
@@ -674,9 +673,8 @@ nv50_gr_trap_handler(struct nv50_gr *gr, u32 display,
nvkm_error
(
subdev
,
"ch %d [%010llx %s] subc %d "
"class %04x mthd %04x data %08x "
"40084c %08x
\n
"
,
chid
,
inst
,
nvkm_client_name
(
chan
),
subc
,
class
,
mthd
,
data
,
addr
);
"40084c %08x
\n
"
,
chid
,
inst
,
name
,
subc
,
class
,
mthd
,
data
,
addr
);
}
else
if
(
display
)
{
nvkm_error
(
subdev
,
"no stuck command?
\n
"
);
...
...
@@ -849,11 +847,15 @@ nv50_gr_intr(struct nvkm_subdev *subdev)
u32
show
=
stat
,
show_bitfield
=
stat
;
const
struct
nvkm_enum
*
en
;
unsigned
long
flags
;
const
char
*
name
=
"unknown"
;
char
msg
[
128
];
int
chid
;
int
chid
=
-
1
;
chan
=
nvkm_fifo_chan_inst
(
device
->
fifo
,
(
u64
)
inst
<<
12
,
&
flags
);
chid
=
chan
?
chan
->
chid
:
-
1
;
if
(
chan
)
{
name
=
chan
->
object
.
client
->
name
;
chid
=
chan
->
chid
;
}
if
(
show
&
0x00100000
)
{
u32
ecode
=
nvkm_rd32
(
device
,
0x400110
);
...
...
@@ -864,7 +866,7 @@ nv50_gr_intr(struct nvkm_subdev *subdev)
}
if
(
stat
&
0x00200000
)
{
if
(
!
nv50_gr_trap_handler
(
gr
,
show
,
chid
,
(
u64
)
inst
<<
12
,
chan
))
if
(
!
nv50_gr_trap_handler
(
gr
,
show
,
chid
,
(
u64
)
inst
<<
12
,
name
))
show
&=
~
0x00200000
;
show_bitfield
&=
~
0x00200000
;
}
...
...
@@ -877,8 +879,8 @@ nv50_gr_intr(struct nvkm_subdev *subdev)
nvkm_snprintbf
(
msg
,
sizeof
(
msg
),
nv50_gr_intr_name
,
show
);
nvkm_error
(
subdev
,
"%08x [%s] ch %d [%010llx %s] subc %d "
"class %04x mthd %04x data %08x
\n
"
,
stat
,
msg
,
chid
,
(
u64
)
inst
<<
12
,
nvkm_client_name
(
chan
),
subc
,
class
,
mthd
,
data
);
stat
,
msg
,
chid
,
(
u64
)
inst
<<
12
,
name
,
subc
,
class
,
mthd
,
data
);
}
if
(
nvkm_rd32
(
device
,
0x400824
)
&
(
1
<<
31
))
...
...
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
View file @
8f0649b5
...
...
@@ -231,8 +231,8 @@ nv31_mpeg_intr(struct nvkm_subdev *subdev)
if
(
show
)
{
nvkm_error
(
subdev
,
"ch %d [%s] %08x %08x %08x %08x
\n
"
,
mpeg
->
chan
?
mpeg
->
chan
->
fifo
->
chid
:
-
1
,
nvkm_client_name
(
mpeg
->
chan
),
stat
,
type
,
mthd
,
data
);
mpeg
->
chan
?
mpeg
->
chan
->
fifo
->
object
.
client
->
name
:
"unknown"
,
stat
,
type
,
mthd
,
data
);
}
spin_unlock_irqrestore
(
&
mpeg
->
base
.
engine
.
lock
,
flags
);
...
...
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
View file @
8f0649b5
...
...
@@ -145,13 +145,11 @@ nv44_mpeg_intr(struct nvkm_subdev *subdev)
u32
mthd
=
nvkm_rd32
(
device
,
0x00b234
);
u32
data
=
nvkm_rd32
(
device
,
0x00b238
);
u32
show
=
stat
;
int
chid
=
-
1
;
spin_lock_irqsave
(
&
mpeg
->
base
.
engine
.
lock
,
flags
);
list_for_each_entry
(
temp
,
&
mpeg
->
chan
,
head
)
{
if
(
temp
->
inst
>>
4
==
inst
)
{
chan
=
temp
;
chid
=
chan
->
fifo
->
chid
;
list_del
(
&
chan
->
head
);
list_add
(
&
chan
->
head
,
&
mpeg
->
chan
);
break
;
...
...
@@ -176,7 +174,8 @@ nv44_mpeg_intr(struct nvkm_subdev *subdev)
if
(
show
)
{
nvkm_error
(
subdev
,
"ch %d [%08x %s] %08x %08x %08x %08x
\n
"
,
chid
,
inst
<<
4
,
nvkm_client_name
(
chan
),
chan
?
chan
->
fifo
->
chid
:
-
1
,
inst
<<
4
,
chan
?
chan
->
fifo
->
object
.
client
->
name
:
"unknown"
,
stat
,
type
,
mthd
,
data
);
}
...
...
drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
View file @
8f0649b5
...
...
@@ -84,7 +84,8 @@ g98_sec_intr(struct nvkm_falcon *sec, struct nvkm_fifo_chan *chan)
nvkm_error
(
subdev
,
"DISPATCH_ERROR %04x [%s] ch %d [%010llx %s] "
"subc %d mthd %04x data %08x
\n
"
,
ssta
,
en
?
en
->
name
:
"UNKNOWN"
,
chan
?
chan
->
chid
:
-
1
,
chan
?
chan
->
inst
:
0
,
nvkm_client_name
(
chan
),
chan
?
chan
->
inst
->
addr
:
0
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
subc
,
mthd
,
data
);
}
...
...
drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c
View file @
8f0649b5
...
...
@@ -24,8 +24,8 @@
#include "nv50.h"
#include <core/handle.h>
#include <core/namedb.h>
#include <engine/disp.h>
#include <engine/fifo/chan.h>
#include <subdev/bar.h>
#include <nvif/event.h>
...
...
@@ -136,7 +136,7 @@ nv50_sw_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
return
ret
;
}
chan
->
vblank
.
channel
=
nv
_gpuobj
(
parent
->
parent
)
->
addr
>>
12
;
chan
->
vblank
.
channel
=
nv
km_fifo_chan
(
parent
)
->
inst
->
addr
>>
12
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
View file @
8f0649b5
...
...
@@ -338,7 +338,7 @@ void
gt215_clk_post
(
struct
nvkm_clk
*
clk
,
unsigned
long
*
flags
)
{
struct
nvkm_device
*
device
=
clk
->
subdev
.
device
;
struct
nvkm_fifo
*
fifo
=
nvkm_fifo
(
clk
)
;
struct
nvkm_fifo
*
fifo
=
device
->
fifo
;
if
(
fifo
&&
flags
)
fifo
->
start
(
fifo
,
flags
);
...
...
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
View file @
8f0649b5
...
...
@@ -189,12 +189,14 @@ nv50_fb_intr(struct nvkm_subdev *subdev)
else
sc
=
NULL
;
chan
=
nvkm_fifo_chan_inst
(
fifo
,
inst
,
&
flags
);
nvkm_error
(
subdev
,
"trapped %s at %02x%04x%04x on channel "
"
%08x [%s]
engine %02x [%s] client %02x [%s] "
nvkm_error
(
subdev
,
"trapped %s at %02x%04x%04x on channel
%d [%08x %s]
"
"engine %02x [%s] client %02x [%s] "
"subclient %02x [%s] reason %08x [%s]
\n
"
,
(
trap
[
5
]
&
0x00000100
)
?
"read"
:
"write"
,
trap
[
5
]
&
0xff
,
trap
[
4
]
&
0xffff
,
trap
[
3
]
&
0xffff
,
inst
,
nvkm_client_name
(
chan
),
st0
,
en
?
en
->
name
:
""
,
trap
[
5
]
&
0xff
,
trap
[
4
]
&
0xffff
,
trap
[
3
]
&
0xffff
,
chan
?
chan
->
chid
:
-
1
,
inst
,
chan
?
chan
->
object
.
client
->
name
:
"unknown"
,
st0
,
en
?
en
->
name
:
""
,
st2
,
cl
?
cl
->
name
:
""
,
st3
,
sc
?
sc
->
name
:
""
,
st1
,
re
?
re
->
name
:
""
);
nvkm_fifo_chan_put
(
fifo
,
flags
,
&
chan
);
...
...
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