Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
9a65a38c
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9a65a38c
编写于
8月 20, 2015
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nouveau/fifo: split user classes out from engine implementations
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
0ce41e3c
变更
45
展开全部
隐藏空白更改
内联
并排
Showing
45 changed file
with
3147 addition
and
2754 deletion
+3147
-2754
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
+0
-24
drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
+17
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
+29
-165
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
+162
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
+28
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
+231
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h
+23
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h
+27
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv04.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv04.h
+24
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c
+259
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h
+42
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c
+127
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
+282
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.c
+102
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.c
+104
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.c
+225
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c
+115
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
+7
-417
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
+74
-399
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h
+26
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
+21
-382
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
+29
-10
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm204.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm204.c
+1
-8
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c
+122
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
+304
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
+357
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm204.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm204.c
+32
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c
+110
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
+32
-297
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
+1
-145
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
+2
-90
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
+25
-113
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
+25
-233
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
+30
-445
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
+4
-26
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
+8
-0
drivers/gpu/drm/nouveau/nvkm/engine/fifo/regsnv04.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/regsnv04.h
+132
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c
+1
-0
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c
+1
-0
未找到文件。
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
浏览文件 @
9a65a38c
...
...
@@ -18,30 +18,6 @@ nvkm_fifo_chan(void *obj)
return
(
void
*
)
nv_namedb
(
obj
);
}
#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))
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
*
);
#define _nvkm_fifo_channel_init _nvkm_namedb_init
#define _nvkm_fifo_channel_fini _nvkm_namedb_fini
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
**
);
#include <core/gpuobj.h>
struct
nvkm_fifo_base
{
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
浏览文件 @
9a65a38c
...
...
@@ -11,3 +11,20 @@ nvkm-y += nvkm/engine/fifo/gk20a.o
nvkm-y += nvkm/engine/fifo/gk208.o
nvkm-y += nvkm/engine/fifo/gm204.o
nvkm-y += nvkm/engine/fifo/gm20b.o
nvkm-y += nvkm/engine/fifo/chan.o
nvkm-y += nvkm/engine/fifo/channv50.o
nvkm-y += nvkm/engine/fifo/chang84.o
nvkm-y += nvkm/engine/fifo/dmanv04.o
nvkm-y += nvkm/engine/fifo/dmanv10.o
nvkm-y += nvkm/engine/fifo/dmanv17.o
nvkm-y += nvkm/engine/fifo/dmanv40.o
nvkm-y += nvkm/engine/fifo/dmanv50.o
nvkm-y += nvkm/engine/fifo/dmag84.o
nvkm-y += nvkm/engine/fifo/gpfifonv50.o
nvkm-y += nvkm/engine/fifo/gpfifog84.o
nvkm-y += nvkm/engine/fifo/gpfifogf100.o
nvkm-y += nvkm/engine/fifo/gpfifogk104.o
nvkm-y += nvkm/engine/fifo/gpfifogm204.o
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
浏览文件 @
9a65a38c
...
...
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
#include <engine/fifo.h>
#include "priv.h"
#include "chan.h"
#include <core/client.h>
#include <core/handle.h>
#include <core/notify.h>
#include <engine/dma.h>
#include <nvif/class.h>
#include <nvif/event.h>
#include <nvif/unpack.h>
...
...
@@ -74,138 +72,51 @@ nvkm_fifo_chan_chid(struct nvkm_fifo *fifo, int chid, unsigned long *rflags)
}
static
int
nvkm_fifo_event_ctor
(
struct
nvkm_object
*
object
,
void
*
data
,
u32
size
,
struct
nvkm_notify
*
notify
)
{
if
(
size
==
0
)
{
notify
->
size
=
0
;
notify
->
types
=
1
;
notify
->
index
=
0
;
return
0
;
}
return
-
ENOSYS
;
}
static
const
struct
nvkm_event_func
nvkm_fifo_event_func
=
{
.
ctor
=
nvkm_fifo_event_ctor
,
};
int
nvkm_fifo_channel_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_chid
(
struct
nvkm_fifo
*
fifo
,
struct
nvkm_object
*
object
)
{
struct
nvkm_client
*
client
=
nvkm_client
(
parent
);
struct
nvkm_dmaobj
*
dmaobj
;
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_dma
*
dma
=
device
->
dma
;
unsigned
long
flags
;
int
ret
;
/* create base object class */
ret
=
nvkm_namedb_create_
(
parent
,
engine
,
oclass
,
0
,
NULL
,
engmask
,
len
,
ptr
);
chan
=
*
ptr
;
if
(
ret
)
return
ret
;
/* validate dma object representing push buffer */
if
(
pushbuf
)
{
dmaobj
=
nvkm_dma_search
(
dma
,
client
,
pushbuf
);
if
(
!
dmaobj
)
return
-
ENOENT
;
ret
=
dmaobj
->
func
->
bind
(
dmaobj
,
&
base
->
gpuobj
,
16
,
&
chan
->
pushgpu
);
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
;
}
}
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
int
engidx
=
nv_hclass
(
fifo
)
&
0xff
;
if
(
chan
->
chid
==
fifo
->
max
)
{
nvkm_error
(
subdev
,
"no free channels
\n
"
);
return
-
ENOSPC
;
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
;
}
chan
->
addr
=
nv_device_resource_start
(
device
,
bar
)
+
addr
+
size
*
chan
->
chid
;
chan
->
size
=
size
;
nvkm_event_send
(
&
fifo
->
cevent
,
1
,
0
,
NULL
,
0
);
return
0
;
return
-
1
;
}
void
nvkm_
fifo_channel_destroy
(
struct
nvkm_fifo_chan
*
chan
)
const
char
*
nvkm_
client_name_for_fifo_chid
(
struct
nvkm_fifo
*
fifo
,
u32
chid
)
{
struct
nvkm_fifo
*
fifo
=
(
void
*
)
nv_object
(
chan
)
->
engine
;
struct
nvkm_fifo
_chan
*
chan
=
NULL
;
unsigned
long
flags
;
if
(
chan
->
user
)
iounmap
(
chan
->
user
);
spin_lock_irqsave
(
&
fifo
->
lock
,
flags
);
fifo
->
channel
[
chan
->
chid
]
=
NULL
;
if
(
chid
>=
fifo
->
min
&&
chid
<=
fifo
->
max
)
chan
=
(
void
*
)
fifo
->
channel
[
chid
];
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
nvkm_gpuobj_del
(
&
chan
->
pushgpu
);
nvkm_namedb_destroy
(
&
chan
->
namedb
);
}
void
_nvkm_fifo_channel_dtor
(
struct
nvkm_object
*
object
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
nvkm_fifo_channel_destroy
(
chan
);
}
int
_nvkm_fifo_channel_map
(
struct
nvkm_object
*
object
,
u64
*
addr
,
u32
*
size
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
*
addr
=
chan
->
addr
;
*
size
=
chan
->
size
;
return
0
;
return
nvkm_client_name
(
chan
);
}
u32
_nvkm_fifo_channel_rd32
(
struct
nvkm_object
*
object
,
u64
addr
)
static
int
nvkm_fifo_event_ctor
(
struct
nvkm_object
*
object
,
void
*
data
,
u32
size
,
struct
nvkm_notify
*
notify
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
if
(
unlikely
(
!
chan
->
user
))
{
chan
->
user
=
ioremap
(
chan
->
addr
,
chan
->
size
)
;
if
(
WARN_ON_ONCE
(
chan
->
user
==
NULL
))
return
0
;
if
(
size
==
0
)
{
notify
->
size
=
0
;
notify
->
types
=
1
;
notify
->
index
=
0
;
return
0
;
}
return
ioread32_native
(
chan
->
user
+
addr
)
;
return
-
ENOSYS
;
}
void
_nvkm_fifo_channel_wr32
(
struct
nvkm_object
*
object
,
u64
addr
,
u32
data
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
if
(
unlikely
(
!
chan
->
user
))
{
chan
->
user
=
ioremap
(
chan
->
addr
,
chan
->
size
);
if
(
WARN_ON_ONCE
(
chan
->
user
==
NULL
))
return
;
}
iowrite32_native
(
data
,
chan
->
user
+
addr
);
}
static
const
struct
nvkm_event_func
nvkm_fifo_event_func
=
{
.
ctor
=
nvkm_fifo_event_ctor
,
};
int
nvkm_fifo_uevent_ctor
(
struct
nvkm_object
*
object
,
void
*
data
,
u32
size
,
...
...
@@ -233,53 +144,6 @@ nvkm_fifo_uevent(struct nvkm_fifo *fifo)
nvkm_event_send
(
&
fifo
->
uevent
,
1
,
0
,
&
rep
,
sizeof
(
rep
));
}
int
_nvkm_fifo_channel_ntfy
(
struct
nvkm_object
*
object
,
u32
type
,
struct
nvkm_event
**
event
)
{
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
;
}
break
;
default:
break
;
}
return
-
EINVAL
;
}
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
);
}
void
nvkm_fifo_destroy
(
struct
nvkm_fifo
*
fifo
)
{
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
0 → 100644
浏览文件 @
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 "chan.h"
#include <core/client.h>
#include <engine/dma.h>
#include <nvif/class.h>
int
_nvkm_fifo_channel_ntfy
(
struct
nvkm_object
*
object
,
u32
type
,
struct
nvkm_event
**
event
)
{
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
;
}
break
;
default:
break
;
}
return
-
EINVAL
;
}
int
_nvkm_fifo_channel_map
(
struct
nvkm_object
*
object
,
u64
*
addr
,
u32
*
size
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
*
addr
=
chan
->
addr
;
*
size
=
chan
->
size
;
return
0
;
}
u32
_nvkm_fifo_channel_rd32
(
struct
nvkm_object
*
object
,
u64
addr
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
if
(
unlikely
(
!
chan
->
user
))
{
chan
->
user
=
ioremap
(
chan
->
addr
,
chan
->
size
);
if
(
WARN_ON_ONCE
(
chan
->
user
==
NULL
))
return
0
;
}
return
ioread32_native
(
chan
->
user
+
addr
);
}
void
_nvkm_fifo_channel_wr32
(
struct
nvkm_object
*
object
,
u64
addr
,
u32
data
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
if
(
unlikely
(
!
chan
->
user
))
{
chan
->
user
=
ioremap
(
chan
->
addr
,
chan
->
size
);
if
(
WARN_ON_ONCE
(
chan
->
user
==
NULL
))
return
;
}
iowrite32_native
(
data
,
chan
->
user
+
addr
);
}
void
nvkm_fifo_channel_destroy
(
struct
nvkm_fifo_chan
*
chan
)
{
struct
nvkm_fifo
*
fifo
=
(
void
*
)
nv_object
(
chan
)
->
engine
;
unsigned
long
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_gpuobj_del
(
&
chan
->
pushgpu
);
nvkm_namedb_destroy
(
&
chan
->
namedb
);
}
void
_nvkm_fifo_channel_dtor
(
struct
nvkm_object
*
object
)
{
struct
nvkm_fifo_chan
*
chan
=
(
void
*
)
object
;
nvkm_fifo_channel_destroy
(
chan
);
}
int
nvkm_fifo_channel_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
)
{
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_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
;
if
(
ret
)
return
ret
;
/* validate dma object representing push buffer */
if
(
pushbuf
)
{
dmaobj
=
nvkm_dma_search
(
device
->
dma
,
client
,
pushbuf
);
if
(
!
dmaobj
)
return
-
ENOENT
;
ret
=
nvkm_object_bind
(
&
dmaobj
->
object
,
&
base
->
gpuobj
,
16
,
&
chan
->
pushgpu
);
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
;
}
}
spin_unlock_irqrestore
(
&
fifo
->
lock
,
flags
);
if
(
chan
->
chid
==
fifo
->
max
)
{
nvkm_error
(
subdev
,
"no free channels
\n
"
);
return
-
ENOSPC
;
}
chan
->
addr
=
nv_device_resource_start
(
device
,
bar
)
+
addr
+
size
*
chan
->
chid
;
chan
->
size
=
size
;
nvkm_event_send
(
&
fifo
->
cevent
,
1
,
0
,
NULL
,
0
);
return
0
;
}
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
0 → 100644
浏览文件 @
9a65a38c
#ifndef __NVKM_FIFO_CHAN_H__
#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))
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
*
);
#define _nvkm_fifo_channel_init _nvkm_namedb_init
#define _nvkm_fifo_channel_fini _nvkm_namedb_fini
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
**
);
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
0 → 100644
浏览文件 @
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 "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <subdev/timer.h>
int
g84_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
{
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
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
engn
=
0
;
addr
=
0x0020
;
break
;
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_BSP
:
case
NVDEV_ENGINE_MSVLD
:
engn
=
5
;
addr
=
0x0080
;
break
;
case
NVDEV_ENGINE_CIPHER
:
case
NVDEV_ENGINE_SEC
:
engn
=
4
;
addr
=
0x00a0
;
break
;
case
NVDEV_ENGINE_CE0
:
engn
=
2
;
addr
=
0x00c0
;
break
;
default:
return
-
EINVAL
;
}
save
=
nvkm_mask
(
device
,
0x002520
,
0x0000003f
,
1
<<
engn
);
nvkm_wr32
(
device
,
0x0032fc
,
nv_gpuobj
(
base
)
->
addr
>>
12
);
done
=
nvkm_msec
(
device
,
2000
,
if
(
nvkm_rd32
(
device
,
0x0032fc
)
!=
0xffffffff
)
break
;
)
>=
0
;
nvkm_wr32
(
device
,
0x002520
,
save
);
if
(
!
done
)
{
nvkm_error
(
subdev
,
"channel %d [%s] unload timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
));
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
);
return
0
;
}
int
g84_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
{
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
;
}
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
;
}
int
g84_fifo_object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
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
;
}
}
return
nvkm_ramht_insert
(
chan
->
ramht
,
NULL
,
0
,
0
,
handle
,
context
);
}
int
g84_fifo_chan_init
(
struct
nvkm_object
*
object
)
{
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
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
;
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
|
ramfc
->
addr
>>
8
);
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
)
{
struct
nvkm_device
*
device
=
nv_engine
(
engine
)
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x10000
,
0x1000
,
NVOBJ_FLAG_HEAP
,
&
base
);
*
pobject
=
nv_object
(
base
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x0200
,
0
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
eng
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x4000
,
0
,
false
,
&
base
->
base
.
gpuobj
,
&
base
->
pgd
);
if
(
ret
)
return
ret
;
ret
=
nvkm_vm_ref
(
nvkm_client
(
parent
)
->
vm
,
&
base
->
vm
,
base
->
pgd
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x1000
,
0x400
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
cache
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x100
,
0x100
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
ramfc
);
if
(
ret
)
return
ret
;
return
0
;
}
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
0 → 100644
浏览文件 @
9a65a38c
#ifndef __GF100_FIFO_CHAN_H__
#define __GF100_FIFO_CHAN_H__
#include "chan.h"
#include "gf100.h"
struct
gf100_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_vm
*
vm
;
};
struct
gf100_fifo_chan
{
struct
nvkm_fifo_chan
base
;
enum
{
STOPPED
,
RUNNING
,
KILLED
}
state
;
};
extern
struct
nvkm_oclass
gf100_fifo_cclass
;
extern
struct
nvkm_oclass
gf100_fifo_sclass
[];
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h
0 → 100644
浏览文件 @
9a65a38c
#ifndef __GK104_FIFO_CHAN_H__
#define __GK104_FIFO_CHAN_H__
#include "chan.h"
#include "gk104.h"
struct
gk104_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_vm
*
vm
;
};
struct
gk104_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
engine
;
enum
{
STOPPED
,
RUNNING
,
KILLED
}
state
;
};
extern
struct
nvkm_oclass
gk104_fifo_cclass
;
extern
struct
nvkm_oclass
gk104_fifo_sclass
[];
extern
struct
nvkm_ofuncs
gk104_fifo_chan_ofuncs
;
extern
struct
nvkm_oclass
gm204_fifo_sclass
[];
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv04.h
0 → 100644
浏览文件 @
9a65a38c
#ifndef __NV04_FIFO_CHAN_H__
#define __NV04_FIFO_CHAN_H__
#include "chan.h"
#include "nv04.h"
struct
nv04_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
subc
[
8
];
u32
ramfc
;
};
int
nv04_fifo_object_attach
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
u32
);
void
nv04_fifo_object_detach
(
struct
nvkm_object
*
,
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
[];
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c
0 → 100644
浏览文件 @
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 "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <subdev/timer.h>
int
nv50_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
{
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
,
me
;
int
ret
=
0
;
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
;
}
/* HW bug workaround:
*
* PFIFO will hang forever if the connected engines don't report
* that they've processed the context switch request.
*
* In order for the kickoff to work, we need to ensure all the
* connected engines are in a state where they can answer.
*
* Newer chipsets don't seem to suffer from this issue, and well,
* there's also a "ignore these engines" bitmask reg we can use
* if we hit the issue there..
*/
me
=
nvkm_mask
(
device
,
0x00b860
,
0x00000001
,
0x00000001
);
/* do the kickoff... */
nvkm_wr32
(
device
,
0x0032fc
,
nv_gpuobj
(
base
)
->
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
));
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
);
}
return
ret
;
}
int
nv50_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
{
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
;
}
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
;
}
void
nv50_fifo_object_detach
(
struct
nvkm_object
*
parent
,
int
cookie
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
nvkm_ramht_remove
(
chan
->
ramht
,
cookie
);
}
int
nv50_fifo_object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
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
;
}
}
return
nvkm_ramht_insert
(
chan
->
ramht
,
NULL
,
0
,
0
,
handle
,
context
);
}
int
nv50_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
nv50_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
/* remove channel from runlist, fifo will unload context */
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
)
{
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
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
;
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
|
ramfc
->
addr
>>
12
);
nv50_fifo_runlist_update
(
fifo
);
return
0
;
}
void
nv50_fifo_chan_dtor
(
struct
nvkm_object
*
object
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
object
;
nvkm_ramht_del
(
&
chan
->
ramht
);
nvkm_fifo_channel_destroy
(
&
chan
->
base
);
}
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
int
nv50_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
nv50_fifo_base
*
base
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x10000
,
0x1000
,
NVOBJ_FLAG_HEAP
,
&
base
);
*
pobject
=
nv_object
(
base
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x0200
,
0x1000
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
ramfc
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x1200
,
0
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
eng
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x4000
,
0
,
false
,
&
base
->
base
.
gpuobj
,
&
base
->
pgd
);
if
(
ret
)
return
ret
;
ret
=
nvkm_vm_ref
(
nvkm_client
(
parent
)
->
vm
,
&
base
->
vm
,
base
->
pgd
);
if
(
ret
)
return
ret
;
return
0
;
}
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
0 → 100644
浏览文件 @
9a65a38c
#ifndef __NV50_FIFO_CHAN_H__
#define __NV50_FIFO_CHAN_H__
#include "chan.h"
#include "nv50.h"
struct
nv50_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
nvkm_gpuobj
*
ramfc
;
struct
nvkm_gpuobj
*
cache
;
struct
nvkm_gpuobj
*
eng
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_vm
*
vm
;
};
struct
nv50_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
subc
[
8
];
struct
nvkm_ramht
*
ramht
;
};
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
;
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
;
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c
0 → 100644
浏览文件 @
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 "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <nvif/class.h>
#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
)
{
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_chan
*
chan
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d vm %llx "
"pushbuf %llx offset %016llx
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
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
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
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
;
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
)
|
(
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
);
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
},
{}
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
0 → 100644
浏览文件 @
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 "channv04.h"
#include "regsnv04.h"
#include <core/client.h>
#include <core/ramht.h>
#include <subdev/instmem.h>
#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
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
mutex_lock
(
&
nv_subdev
(
fifo
)
->
mutex
);
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
)
{
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
;
}
}
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
;
}
int
nv04_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_memory
*
fctx
=
device
->
imem
->
ramfc
;
struct
ramfc_desc
*
c
;
unsigned
long
flags
;
u32
data
=
chan
->
ramfc
;
u32
chid
;
/* prevent fifo context switches */
spin_lock_irqsave
(
&
fifo
->
base
.
lock
,
flags
);
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
;
if
(
chid
==
chan
->
base
.
chid
)
{
nvkm_mask
(
device
,
NV04_PFIFO_CACHE1_DMA_PUSH
,
0x00000001
,
0
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH0
,
0
);
nvkm_mask
(
device
,
NV04_PFIFO_CACHE1_PULL0
,
0x00000001
,
0
);
c
=
fifo
->
ramfc_desc
;
do
{
u32
rm
=
((
1ULL
<<
c
->
bits
)
-
1
)
<<
c
->
regs
;
u32
cm
=
((
1ULL
<<
c
->
bits
)
-
1
)
<<
c
->
ctxs
;
u32
rv
=
(
nvkm_rd32
(
device
,
c
->
regp
)
&
rm
)
>>
c
->
regs
;
u32
cv
=
(
nvkm_ro32
(
fctx
,
c
->
ctxp
+
data
)
&
~
cm
);
nvkm_wo32
(
fctx
,
c
->
ctxp
+
data
,
cv
|
(
rv
<<
c
->
ctxs
));
}
while
((
++
c
)
->
bits
);
c
=
fifo
->
ramfc_desc
;
do
{
nvkm_wr32
(
device
,
c
->
regp
,
0x00000000
);
}
while
((
++
c
)
->
bits
);
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_PUSH0
,
1
);
nvkm_wr32
(
device
,
NV04_PFIFO_CACHE1_PULL0
,
1
);
}
/* restore normal operation, after disabling dma mode */
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
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
object
;
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
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
struct
ramfc_desc
*
c
=
fifo
->
ramfc_desc
;
nvkm_kmap
(
imem
->
ramfc
);
do
{
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
c
->
ctxp
,
0x00000000
);
}
while
((
++
c
)
->
bits
);
nvkm_done
(
imem
->
ramfc
);
nvkm_fifo_channel_destroy
(
&
chan
->
base
);
}
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
)
{
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
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
}
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
(
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
.
pushgpu
->
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
|
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN
|
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8
);
nvkm_done
(
imem
->
ramfc
);
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
,
},
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.c
0 → 100644
浏览文件 @
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 "channv04.h"
#include "regsnv04.h"
#include <core/client.h>
#include <subdev/instmem.h>
#include <nvif/class.h>
#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
)
{
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
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
}
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
(
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
.
pushgpu
->
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
|
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN
|
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8
);
nvkm_done
(
imem
->
ramfc
);
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
},
{}
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.c
0 → 100644
浏览文件 @
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 "channv04.h"
#include "regsnv04.h"
#include <core/client.h>
#include <subdev/instmem.h>
#include <nvif/class.h>
#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
)
{
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
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
}
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
(
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
.
pushgpu
->
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
|
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN
|
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8
);
nvkm_done
(
imem
->
ramfc
);
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
},
{}
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.c
0 → 100644
浏览文件 @
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 "channv04.h"
#include "regsnv04.h"
#include <core/client.h>
#include <core/ramht.h>
#include <subdev/instmem.h>
#include <nvif/class.h>
#include <nvif/unpack.h>
static
int
nv40_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
engctx
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
unsigned
long
flags
;
u32
reg
,
ctx
;
switch
(
nv_engidx
(
engctx
->
engine
))
{
case
NVDEV_ENGINE_SW
:
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
)
nvkm_wr32
(
device
,
reg
,
0x00000000
);
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
ctx
,
0x00000000
);
nvkm_done
(
imem
->
ramfc
);
nvkm_mask
(
device
,
0x002500
,
0x00000001
,
0x00000001
);
spin_unlock_irqrestore
(
&
fifo
->
base
.
lock
,
flags
);
return
0
;
}
static
int
nv40_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engctx
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
parent
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
parent
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_instmem
*
imem
=
device
->
imem
;
unsigned
long
flags
;
u32
reg
,
ctx
;
switch
(
nv_engidx
(
engctx
->
engine
))
{
case
NVDEV_ENGINE_SW
:
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
);
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
);
nvkm_kmap
(
imem
->
ramfc
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
ctx
,
nv_engctx
(
engctx
)
->
addr
);
nvkm_done
(
imem
->
ramfc
);
nvkm_mask
(
device
,
0x002500
,
0x00000001
,
0x00000001
);
spin_unlock_irqrestore
(
&
fifo
->
base
.
lock
,
flags
);
return
0
;
}
static
int
nv40_fifo_object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
{
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
|=
0x00100000
;
break
;
case
NVDEV_ENGINE_MPEG
:
context
|=
0x00200000
;
break
;
default:
return
-
EINVAL
;
}
}
context
|=
chid
<<
23
;
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_chan_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
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
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
}
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
(
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
.
pushgpu
->
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
|
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN
|
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8
);
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
0x3c
,
0x0001ffff
);
nvkm_done
(
imem
->
ramfc
);
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
},
{}
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c
0 → 100644
浏览文件 @
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 "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <nvif/class.h>
#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
)
{
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_chan
*
chan
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d vm %llx "
"pushbuf %llx offset %016llx
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
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
;
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
)
|
(
4
<<
24
)
/* SEARCH_FULL */
|
(
chan
->
ramht
->
gpuobj
->
node
->
offset
>>
4
));
nvkm_done
(
base
->
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
},
{}
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
浏览文件 @
9a65a38c
...
...
@@ -22,432 +22,22 @@
* Authors: Ben Skeggs
*/
#include "nv50.h"
#include "nv04.h"
#include <core/client.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/unpack.h>
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static
int
g84_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
{
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
;
}
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
g84_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
{
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
(
nv_engidx
(
object
->
engine
))
{
case
NVDEV_ENGINE_SW
:
return
0
;
case
NVDEV_ENGINE_GR
:
engn
=
0
;
addr
=
0x0020
;
break
;
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_BSP
:
case
NVDEV_ENGINE_MSVLD
:
engn
=
5
;
addr
=
0x0080
;
break
;
case
NVDEV_ENGINE_CIPHER
:
case
NVDEV_ENGINE_SEC
:
engn
=
4
;
addr
=
0x00a0
;
break
;
case
NVDEV_ENGINE_CE0
:
engn
=
2
;
addr
=
0x00c0
;
break
;
default:
return
-
EINVAL
;
}
save
=
nvkm_mask
(
device
,
0x002520
,
0x0000003f
,
1
<<
engn
);
nvkm_wr32
(
device
,
0x0032fc
,
nv_gpuobj
(
base
)
->
addr
>>
12
);
done
=
nvkm_msec
(
device
,
2000
,
if
(
nvkm_rd32
(
device
,
0x0032fc
)
!=
0xffffffff
)
break
;
)
>=
0
;
nvkm_wr32
(
device
,
0x002520
,
save
);
if
(
!
done
)
{
nvkm_error
(
subdev
,
"channel %d [%s] unload timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
));
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
);
return
0
;
}
static
int
g84_fifo_object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
{
struct
nv50_fifo_chan
*
chan
=
(
void
*
)
parent
;
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
;
}
}
return
nvkm_ramht_insert
(
chan
->
ramht
,
NULL
,
0
,
0
,
handle
,
context
);
}
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
)
{
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_chan
*
chan
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %016llx
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
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
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
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
;
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
)
|
(
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
);
return
0
;
}
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
)
{
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_chan
*
chan
;
u64
ioffset
,
ilength
;
int
ret
;
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 pushbuf %llx "
"ioffset %016llx ilength %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
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
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
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
;
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
)
|
(
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
);
return
0
;
}
static
int
g84_fifo_chan_init
(
struct
nvkm_object
*
object
)
{
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
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
;
nvkm_wr32
(
device
,
0x002600
+
(
chid
*
4
),
0x80000000
|
ramfc
->
addr
>>
8
);
nv50_fifo_playlist_update
(
fifo
);
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
};
static
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
};
static
struct
nvkm_oclass
g84_fifo_sclass
[]
=
{
{
G82_CHANNEL_DMA
,
&
g84_fifo_ofuncs_dma
},
{
G82_CHANNEL_GPFIFO
,
&
g84_fifo_ofuncs_ind
},
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
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
)
{
struct
nvkm_device
*
device
=
nv_engine
(
engine
)
->
subdev
.
device
;
struct
nv50_fifo_base
*
base
;
int
ret
;
ret
=
nvkm_fifo_context_create
(
parent
,
engine
,
oclass
,
NULL
,
0x10000
,
0x1000
,
NVOBJ_FLAG_HEAP
,
&
base
);
*
pobject
=
nv_object
(
base
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x0200
,
0
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
eng
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x4000
,
0
,
false
,
&
base
->
base
.
gpuobj
,
&
base
->
pgd
);
if
(
ret
)
return
ret
;
ret
=
nvkm_vm_ref
(
nvkm_client
(
parent
)
->
vm
,
&
base
->
vm
,
base
->
pgd
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x1000
,
0x400
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
cache
);
if
(
ret
)
return
ret
;
ret
=
nvkm_gpuobj_new
(
device
,
0x100
,
0x100
,
true
,
&
base
->
base
.
gpuobj
,
&
base
->
ramfc
);
if
(
ret
)
return
ret
;
return
0
;
}
static
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
,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
#include "channv50.h"
static
void
g84_fifo_uevent_
init
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
g84_fifo_uevent_
fini
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x40000000
,
0x
4
0000000
);
nvkm_mask
(
device
,
0x002140
,
0x40000000
,
0x
0
0000000
);
}
static
void
g84_fifo_uevent_
fini
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
g84_fifo_uevent_
init
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x40000000
,
0x
0
0000000
);
nvkm_mask
(
device
,
0x002140
,
0x40000000
,
0x
4
0000000
);
}
static
const
struct
nvkm_event_func
...
...
@@ -472,12 +62,12 @@ g84_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
return
ret
;
ret
=
nvkm_memory_new
(
device
,
NVKM_MEM_TARGET_INST
,
128
*
4
,
0x1000
,
false
,
&
fifo
->
play
list
[
0
]);
false
,
&
fifo
->
run
list
[
0
]);
if
(
ret
)
return
ret
;
ret
=
nvkm_memory_new
(
device
,
NVKM_MEM_TARGET_INST
,
128
*
4
,
0x1000
,
false
,
&
fifo
->
play
list
[
1
]);
false
,
&
fifo
->
run
list
[
1
]);
if
(
ret
)
return
ret
;
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
浏览文件 @
9a65a38c
...
...
@@ -21,61 +21,41 @@
*
* Authors: Ben Skeggs
*/
#include <engine/fifo.h>
#include "gf100.h"
#include "changf100.h"
#include <core/client.h>
#include <core/engctx.h>
#include <core/enum.h>
#include <core/handle.h>
#include <subdev/bar.h>
#include <subdev/fb.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
#include <engine/sw.h>
#include <nvif/class.h>
#include <nvif/ioctl.h>
#include <nvif/unpack.h>
struct
gf100_fifo
{
struct
nvkm_fifo
base
;
struct
work_struct
fault
;
u64
mask
;
struct
{
struct
nvkm_memory
*
mem
[
2
];
int
active
;
wait_queue_head_t
wait
;
}
runlist
;
struct
{
struct
nvkm_memory
*
mem
;
struct
nvkm_vma
bar
;
}
user
;
int
spoon_nr
;
};
struct
gf100_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_vm
*
vm
;
};
static
void
gf100_fifo_uevent_init
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x80000000
);
}
struct
gf100_fifo_chan
{
struct
nvkm_fifo_chan
base
;
enum
{
STOPPED
,
RUNNING
,
KILLED
}
state
;
};
static
void
gf100_fifo_uevent_fini
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x00000000
);
}
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static
const
struct
nvkm_event_func
gf100_fifo_uevent_func
=
{
.
ctor
=
nvkm_fifo_uevent_ctor
,
.
init
=
gf100_fifo_uevent_init
,
.
fini
=
gf100_fifo_uevent_fini
,
};
static
void
void
gf100_fifo_runlist_update
(
struct
gf100_fifo
*
fifo
)
{
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
...
...
@@ -108,289 +88,6 @@ gf100_fifo_runlist_update(struct gf100_fifo *fifo)
mutex_unlock
(
&
nv_subdev
(
fifo
)
->
mutex
);
}
static
int
gf100_fifo_context_attach
(
struct
nvkm_object
*
parent
,
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
;
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
;
nv_engctx
(
ectx
)
->
addr
=
nv_gpuobj
(
base
)
->
addr
>>
12
;
}
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
;
}
static
int
gf100_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
{
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
))
{
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
;
}
nvkm_wr32
(
device
,
0x002634
,
chan
->
base
.
chid
);
if
(
nvkm_msec
(
device
,
2000
,
if
(
nvkm_rd32
(
device
,
0x002634
)
==
chan
->
base
.
chid
)
break
;
)
<
0
)
{
nvkm_error
(
subdev
,
"channel %d [%s] kick timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
));
if
(
suspend
)
return
-
EBUSY
;
}
nvkm_kmap
(
engn
);
nvkm_wo32
(
engn
,
addr
+
0x00
,
0x00000000
);
nvkm_wo32
(
engn
,
addr
+
0x04
,
0x00000000
);
nvkm_done
(
engn
);
return
0
;
}
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
)
{
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_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 "
"ioffset %016llx ilength %08x
\n
"
,
args
->
v0
.
version
,
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
);
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
;
usermem
=
chan
->
base
.
chid
*
0x1000
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
nvkm_kmap
(
fifo
->
user
.
mem
);
for
(
i
=
0
;
i
<
0x1000
;
i
+=
4
)
nvkm_wo32
(
fifo
->
user
.
mem
,
usermem
+
i
,
0x00000000
);
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
int
gf100_fifo_chan_init
(
struct
nvkm_object
*
object
)
{
struct
nvkm_gpuobj
*
base
=
nv_gpuobj
(
object
->
parent
);
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gf100_fifo_chan
*
chan
=
(
void
*
)
object
;
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
;
nvkm_wr32
(
device
,
0x003000
+
(
chid
*
8
),
0xc0000000
|
base
->
addr
>>
12
);
if
(
chan
->
state
==
STOPPED
&&
(
chan
->
state
=
RUNNING
)
==
RUNNING
)
{
nvkm_wr32
(
device
,
0x003004
+
(
chid
*
8
),
0x001f0001
);
gf100_fifo_runlist_update
(
fifo
);
}
return
0
;
}
static
void
gf100_fifo_intr_engine
(
struct
gf100_fifo
*
fifo
);
static
int
gf100_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gf100_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
if
(
chan
->
state
==
RUNNING
&&
(
chan
->
state
=
STOPPED
)
==
STOPPED
)
{
nvkm_mask
(
device
,
0x003004
+
(
chid
*
8
),
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
);
}
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
};
static
struct
nvkm_oclass
gf100_fifo_sclass
[]
=
{
{
FERMI_CHANNEL_GPFIFO
,
&
gf100_fifo_ofuncs
},
{}
};
/*******************************************************************************
* FIFO context - instmem heap and vm setup
******************************************************************************/
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
;
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
);
}
static
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
,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static
inline
int
gf100_fifo_engidx
(
struct
gf100_fifo
*
fifo
,
u32
engn
)
{
...
...
@@ -739,7 +436,7 @@ gf100_fifo_intr_engine_unit(struct gf100_fifo *fifo, int engn)
}
}
static
void
void
gf100_fifo_intr_engine
(
struct
gf100_fifo
*
fifo
)
{
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
...
...
@@ -825,28 +522,62 @@ gf100_fifo_intr(struct nvkm_subdev *subdev)
}
}
static
void
gf100_fifo_
uevent_init
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
static
int
gf100_fifo_
init
(
struct
nvkm_object
*
object
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x80000000
);
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
int
ret
,
i
;
ret
=
nvkm_fifo_init
(
&
fifo
->
base
);
if
(
ret
)
return
ret
;
nvkm_wr32
(
device
,
0x000204
,
0xffffffff
);
nvkm_wr32
(
device
,
0x002204
,
0xffffffff
);
fifo
->
spoon_nr
=
hweight32
(
nvkm_rd32
(
device
,
0x002204
));
nvkm_debug
(
subdev
,
"%d PBDMA unit(s)
\n
"
,
fifo
->
spoon_nr
);
/* assign engines to PBDMAs */
if
(
fifo
->
spoon_nr
>=
3
)
{
nvkm_wr32
(
device
,
0x002208
,
~
(
1
<<
0
));
/* PGRAPH */
nvkm_wr32
(
device
,
0x00220c
,
~
(
1
<<
1
));
/* PVP */
nvkm_wr32
(
device
,
0x002210
,
~
(
1
<<
1
));
/* PMSPP */
nvkm_wr32
(
device
,
0x002214
,
~
(
1
<<
1
));
/* PMSVLD */
nvkm_wr32
(
device
,
0x002218
,
~
(
1
<<
2
));
/* PCE0 */
nvkm_wr32
(
device
,
0x00221c
,
~
(
1
<<
1
));
/* PCE1 */
}
/* PBDMA[n] */
for
(
i
=
0
;
i
<
fifo
->
spoon_nr
;
i
++
)
{
nvkm_mask
(
device
,
0x04013c
+
(
i
*
0x2000
),
0x10000100
,
0x00000000
);
nvkm_wr32
(
device
,
0x040108
+
(
i
*
0x2000
),
0xffffffff
);
/* INTR */
nvkm_wr32
(
device
,
0x04010c
+
(
i
*
0x2000
),
0xfffffeff
);
/* INTREN */
}
nvkm_mask
(
device
,
0x002200
,
0x00000001
,
0x00000001
);
nvkm_wr32
(
device
,
0x002254
,
0x10000000
|
fifo
->
user
.
bar
.
offset
>>
12
);
nvkm_wr32
(
device
,
0x002100
,
0xffffffff
);
nvkm_wr32
(
device
,
0x002140
,
0x7fffffff
);
nvkm_wr32
(
device
,
0x002628
,
0x00000001
);
/* ENGINE_INTR_EN */
return
0
;
}
static
void
gf100_fifo_
uevent_fini
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
gf100_fifo_
dtor
(
struct
nvkm_object
*
object
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x00000000
);
}
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
;
static
const
struct
nvkm_event_func
gf100_fifo_uevent_func
=
{
.
ctor
=
nvkm_fifo_uevent_ctor
,
.
init
=
gf100_fifo_uevent_init
,
.
fini
=
gf100_fifo_uevent_fini
,
};
nvkm_vm_put
(
&
fifo
->
user
.
bar
);
nvkm_memory_del
(
&
fifo
->
user
.
mem
);
nvkm_memory_del
(
&
fifo
->
runlist
.
mem
[
0
]);
nvkm_memory_del
(
&
fifo
->
runlist
.
mem
[
1
]);
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
static
int
gf100_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
...
...
@@ -899,62 +630,6 @@ gf100_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
return
0
;
}
static
void
gf100_fifo_dtor
(
struct
nvkm_object
*
object
)
{
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
;
nvkm_vm_put
(
&
fifo
->
user
.
bar
);
nvkm_memory_del
(
&
fifo
->
user
.
mem
);
nvkm_memory_del
(
&
fifo
->
runlist
.
mem
[
0
]);
nvkm_memory_del
(
&
fifo
->
runlist
.
mem
[
1
]);
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
static
int
gf100_fifo_init
(
struct
nvkm_object
*
object
)
{
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
int
ret
,
i
;
ret
=
nvkm_fifo_init
(
&
fifo
->
base
);
if
(
ret
)
return
ret
;
nvkm_wr32
(
device
,
0x000204
,
0xffffffff
);
nvkm_wr32
(
device
,
0x002204
,
0xffffffff
);
fifo
->
spoon_nr
=
hweight32
(
nvkm_rd32
(
device
,
0x002204
));
nvkm_debug
(
subdev
,
"%d PBDMA unit(s)
\n
"
,
fifo
->
spoon_nr
);
/* assign engines to PBDMAs */
if
(
fifo
->
spoon_nr
>=
3
)
{
nvkm_wr32
(
device
,
0x002208
,
~
(
1
<<
0
));
/* PGRAPH */
nvkm_wr32
(
device
,
0x00220c
,
~
(
1
<<
1
));
/* PVP */
nvkm_wr32
(
device
,
0x002210
,
~
(
1
<<
1
));
/* PMSPP */
nvkm_wr32
(
device
,
0x002214
,
~
(
1
<<
1
));
/* PMSVLD */
nvkm_wr32
(
device
,
0x002218
,
~
(
1
<<
2
));
/* PCE0 */
nvkm_wr32
(
device
,
0x00221c
,
~
(
1
<<
1
));
/* PCE1 */
}
/* PBDMA[n] */
for
(
i
=
0
;
i
<
fifo
->
spoon_nr
;
i
++
)
{
nvkm_mask
(
device
,
0x04013c
+
(
i
*
0x2000
),
0x10000100
,
0x00000000
);
nvkm_wr32
(
device
,
0x040108
+
(
i
*
0x2000
),
0xffffffff
);
/* INTR */
nvkm_wr32
(
device
,
0x04010c
+
(
i
*
0x2000
),
0xfffffeff
);
/* INTREN */
}
nvkm_mask
(
device
,
0x002200
,
0x00000001
,
0x00000001
);
nvkm_wr32
(
device
,
0x002254
,
0x10000000
|
fifo
->
user
.
bar
.
offset
>>
12
);
nvkm_wr32
(
device
,
0x002100
,
0xffffffff
);
nvkm_wr32
(
device
,
0x002140
,
0x7fffffff
);
nvkm_wr32
(
device
,
0x002628
,
0x00000001
);
/* ENGINE_INTR_EN */
return
0
;
}
struct
nvkm_oclass
*
gf100_fifo_oclass
=
&
(
struct
nvkm_oclass
)
{
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h
0 → 100644
浏览文件 @
9a65a38c
#ifndef __GF100_FIFO_H__
#define __GF100_FIFO_H__
#include "priv.h"
struct
gf100_fifo
{
struct
nvkm_fifo
base
;
struct
work_struct
fault
;
u64
mask
;
struct
{
struct
nvkm_memory
*
mem
[
2
];
int
active
;
wait_queue_head_t
wait
;
}
runlist
;
struct
{
struct
nvkm_memory
*
mem
;
struct
nvkm_vma
bar
;
}
user
;
int
spoon_nr
;
};
void
gf100_fifo_intr_engine
(
struct
gf100_fifo
*
);
void
gf100_fifo_runlist_update
(
struct
gf100_fifo
*
);
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
浏览文件 @
9a65a38c
...
...
@@ -22,20 +22,15 @@
* Authors: Ben Skeggs
*/
#include "gk104.h"
#include "changk104.h"
#include <core/client.h>
#include <core/engctx.h>
#include <core/enum.h>
#include <core/handle.h>
#include <subdev/bar.h>
#include <subdev/fb.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
#include <engine/sw.h>
#include <nvif/class.h>
#include <nvif/ioctl.h>
#include <nvif/unpack.h>
#define _(a,b) { (a), ((1ULL << (a)) | (b)) }
static
const
struct
{
...
...
@@ -54,47 +49,30 @@ static const struct {
#undef _
#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
struct
gk104_fifo_engn
{
struct
nvkm_memory
*
runlist
[
2
];
int
cur_runlist
;
wait_queue_head_t
wait
;
};
struct
gk104_fifo
{
struct
nvkm_fifo
base
;
struct
work_struct
fault
;
u64
mask
;
struct
gk104_fifo_engn
engine
[
FIFO_ENGINE_NR
];
struct
{
struct
nvkm_memory
*
mem
;
struct
nvkm_vma
bar
;
}
user
;
int
spoon_nr
;
};
static
void
gk104_fifo_uevent_fini
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x00000000
);
}
struct
gk104_fifo_base
{
struct
nvkm_fifo_base
base
;
struct
nvkm_gpuobj
*
pgd
;
struct
nvkm_vm
*
vm
;
};
static
void
gk104_fifo_uevent_init
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x80000000
);
}
struct
gk104_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
engine
;
enum
{
STOPPED
,
RUNNING
,
KILLED
}
state
;
static
const
struct
nvkm_event_func
gk104_fifo_uevent_func
=
{
.
ctor
=
nvkm_fifo_uevent_ctor
,
.
init
=
gk104_fifo_uevent_init
,
.
fini
=
gk104_fifo_uevent_fini
,
};
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static
void
void
gk104_fifo_runlist_update
(
struct
gk104_fifo
*
fifo
,
u32
engine
)
{
struct
gk104_fifo_engn
*
engn
=
&
fifo
->
engine
[
engine
];
...
...
@@ -128,322 +106,6 @@ gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
mutex_unlock
(
&
nv_subdev
(
fifo
)
->
mutex
);
}
static
int
gk104_fifo_context_attach
(
struct
nvkm_object
*
parent
,
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
;
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
;
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
;
}
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
;
}
static
int
gk104_fifo_chan_kick
(
struct
gk104_fifo_chan
*
chan
)
{
struct
nvkm_object
*
obj
=
(
void
*
)
chan
;
struct
gk104_fifo
*
fifo
=
(
void
*
)
obj
->
engine
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
nvkm_wr32
(
device
,
0x002634
,
chan
->
base
.
chid
);
if
(
nvkm_msec
(
device
,
2000
,
if
(
!
(
nvkm_rd32
(
device
,
0x002634
)
&
0x00100000
))
break
;
)
<
0
)
{
nvkm_error
(
subdev
,
"channel %d [%s] kick timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
));
return
-
EBUSY
;
}
return
0
;
}
static
int
gk104_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
{
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
;
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_MSVLD
:
addr
=
0x0270
;
break
;
case
NVDEV_ENGINE_MSPDEC
:
addr
=
0x0250
;
break
;
case
NVDEV_ENGINE_MSPPP
:
addr
=
0x0260
;
break
;
default:
return
-
EINVAL
;
}
ret
=
gk104_fifo_chan_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
);
}
return
0
;
}
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
)
{
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_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 "
"ioffset %016llx ilength %08x engine %08x
\n
"
,
args
->
v0
.
version
,
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
))
continue
;
engines
|=
(
1
<<
i
);
}
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
);
}
engines
&=
args
->
v0
.
engine
;
if
(
!
engines
)
{
nvif_ioctl
(
parent
,
"unsupported engines %08x
\n
"
,
args
->
v0
.
engine
);
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
);
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
;
usermem
=
chan
->
base
.
chid
*
0x200
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
nvkm_kmap
(
fifo
->
user
.
mem
);
for
(
i
=
0
;
i
<
0x200
;
i
+=
4
)
nvkm_wo32
(
fifo
->
user
.
mem
,
usermem
+
i
,
0x00000000
);
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
;
}
static
int
gk104_fifo_chan_init
(
struct
nvkm_object
*
object
)
{
struct
nvkm_gpuobj
*
base
=
nv_gpuobj
(
object
->
parent
);
struct
gk104_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gk104_fifo_chan
*
chan
=
(
void
*
)
object
;
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
;
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
);
gk104_fifo_runlist_update
(
fifo
,
chan
->
engine
);
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
),
0x00000400
,
0x00000400
);
}
return
0
;
}
static
int
gk104_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
gk104_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gk104_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
if
(
chan
->
state
==
RUNNING
&&
(
chan
->
state
=
STOPPED
)
==
STOPPED
)
{
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
),
0x00000800
,
0x00000800
);
gk104_fifo_runlist_update
(
fifo
,
chan
->
engine
);
}
nvkm_wr32
(
device
,
0x800000
+
(
chid
*
8
),
0x00000000
);
return
nvkm_fifo_channel_fini
(
&
chan
->
base
,
suspend
);
}
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
};
static
struct
nvkm_oclass
gk104_fifo_sclass
[]
=
{
{
KEPLER_CHANNEL_GPFIFO_A
,
&
gk104_fifo_chan_ofuncs
},
{}
};
/*******************************************************************************
* FIFO context - instmem heap and vm setup
******************************************************************************/
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
;
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
);
}
static
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
,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static
inline
int
gk104_fifo_engidx
(
struct
gk104_fifo
*
fifo
,
u32
engn
)
{
...
...
@@ -998,29 +660,6 @@ gk104_fifo_intr(struct nvkm_subdev *subdev)
}
}
static
void
gk104_fifo_uevent_init
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x80000000
);
}
static
void
gk104_fifo_uevent_fini
(
struct
nvkm_event
*
event
,
int
type
,
int
index
)
{
struct
nvkm_fifo
*
fifo
=
container_of
(
event
,
typeof
(
*
fifo
),
uevent
);
struct
nvkm_device
*
device
=
fifo
->
engine
.
subdev
.
device
;
nvkm_mask
(
device
,
0x002140
,
0x80000000
,
0x00000000
);
}
static
const
struct
nvkm_event_func
gk104_fifo_uevent_func
=
{
.
ctor
=
nvkm_fifo_uevent_ctor
,
.
init
=
gk104_fifo_uevent_init
,
.
fini
=
gk104_fifo_uevent_fini
,
};
int
gk104_fifo_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
浏览文件 @
9a65a38c
#ifndef __
NVKM_FIFO_NVE0
_H__
#define __
NVKM_FIFO_NVE0
_H__
#include
<engine/fifo.h>
#ifndef __
GK104_FIFO
_H__
#define __
GK104_FIFO
_H__
#include
"priv.h"
int
gk104_fifo_ctor
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
struct
nvkm_oclass
*
,
void
*
,
u32
,
struct
nvkm_object
**
);
void
gk104_fifo_dtor
(
struct
nvkm_object
*
);
int
gk104_fifo_init
(
struct
nvkm_object
*
);
int
gk104_fifo_fini
(
struct
nvkm_object
*
,
bool
);
struct
gk104_fifo_engn
{
struct
nvkm_memory
*
runlist
[
2
];
int
cur_runlist
;
wait_queue_head_t
wait
;
};
struct
gk104_fifo
{
struct
nvkm_fifo
base
;
struct
work_struct
fault
;
u64
mask
;
struct
gk104_fifo_engn
engine
[
7
];
struct
{
struct
nvkm_memory
*
mem
;
struct
nvkm_vma
bar
;
}
user
;
int
spoon_nr
;
};
struct
gk104_fifo_impl
{
struct
nvkm_oclass
base
;
u32
channels
;
};
extern
struct
nvkm_ofuncs
gk104_fifo_chan_ofuncs
;
int
gk104_fifo_ctor
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
struct
nvkm_oclass
*
,
void
*
,
u32
,
struct
nvkm_object
**
);
void
gk104_fifo_dtor
(
struct
nvkm_object
*
);
int
gk104_fifo_init
(
struct
nvkm_object
*
);
int
gk104_fifo_fini
(
struct
nvkm_object
*
,
bool
);
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
,
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm204.c
浏览文件 @
9a65a38c
...
...
@@ -22,14 +22,7 @@
* Authors: Ben Skeggs
*/
#include "gk104.h"
#include <nvif/class.h>
static
struct
nvkm_oclass
gm204_fifo_sclass
[]
=
{
{
MAXWELL_CHANNEL_GPFIFO_A
,
&
gk104_fifo_chan_ofuncs
},
{}
};
#include "changk104.h"
int
gm204_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c
0 → 100644
浏览文件 @
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 "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <nvif/class.h>
#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
)
{
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_chan
*
chan
;
u64
ioffset
,
ilength
;
int
ret
;
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 "
"pushbuf %llx ioffset %016llx "
"ilength %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
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
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
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
;
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
)
|
(
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
);
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
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
0 → 100644
浏览文件 @
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 "changf100.h"
#include <core/client.h>
#include <subdev/fb.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/unpack.h>
static
int
gf100_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
{
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
))
{
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
;
}
nvkm_wr32
(
device
,
0x002634
,
chan
->
base
.
chid
);
if
(
nvkm_msec
(
device
,
2000
,
if
(
nvkm_rd32
(
device
,
0x002634
)
==
chan
->
base
.
chid
)
break
;
)
<
0
)
{
nvkm_error
(
subdev
,
"channel %d [%s] kick timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
));
if
(
suspend
)
return
-
EBUSY
;
}
nvkm_kmap
(
engn
);
nvkm_wo32
(
engn
,
addr
+
0x00
,
0x00000000
);
nvkm_wo32
(
engn
,
addr
+
0x04
,
0x00000000
);
nvkm_done
(
engn
);
return
0
;
}
static
int
gf100_fifo_context_attach
(
struct
nvkm_object
*
parent
,
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
;
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
;
nv_engctx
(
ectx
)
->
addr
=
nv_gpuobj
(
base
)
->
addr
>>
12
;
}
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
;
}
static
int
gf100_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gf100_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
if
(
chan
->
state
==
RUNNING
&&
(
chan
->
state
=
STOPPED
)
==
STOPPED
)
{
nvkm_mask
(
device
,
0x003004
+
(
chid
*
8
),
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
);
}
static
int
gf100_fifo_chan_init
(
struct
nvkm_object
*
object
)
{
struct
nvkm_gpuobj
*
base
=
nv_gpuobj
(
object
->
parent
);
struct
gf100_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gf100_fifo_chan
*
chan
=
(
void
*
)
object
;
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
;
nvkm_wr32
(
device
,
0x003000
+
(
chid
*
8
),
0xc0000000
|
base
->
addr
>>
12
);
if
(
chan
->
state
==
STOPPED
&&
(
chan
->
state
=
RUNNING
)
==
RUNNING
)
{
nvkm_wr32
(
device
,
0x003004
+
(
chid
*
8
),
0x001f0001
);
gf100_fifo_runlist_update
(
fifo
);
}
return
0
;
}
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
)
{
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_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"
"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
);
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
;
usermem
=
chan
->
base
.
chid
*
0x1000
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
nvkm_kmap
(
fifo
->
user
.
mem
);
for
(
i
=
0
;
i
<
0x1000
;
i
+=
4
)
nvkm_wo32
(
fifo
->
user
.
mem
,
usermem
+
i
,
0x00000000
);
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
;
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
,
},
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
0 → 100644
浏览文件 @
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 "changk104.h"
#include <core/client.h>
#include <subdev/fb.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
#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
)
{
struct
nvkm_object
*
obj
=
(
void
*
)
chan
;
struct
gk104_fifo
*
fifo
=
(
void
*
)
obj
->
engine
;
struct
nvkm_subdev
*
subdev
=
&
fifo
->
base
.
engine
.
subdev
;
struct
nvkm_device
*
device
=
subdev
->
device
;
nvkm_wr32
(
device
,
0x002634
,
chan
->
base
.
chid
);
if
(
nvkm_msec
(
device
,
2000
,
if
(
!
(
nvkm_rd32
(
device
,
0x002634
)
&
0x00100000
))
break
;
)
<
0
)
{
nvkm_error
(
subdev
,
"channel %d [%s] kick timeout
\n
"
,
chan
->
base
.
chid
,
nvkm_client_name
(
chan
));
return
-
EBUSY
;
}
return
0
;
}
static
int
gk104_fifo_context_detach
(
struct
nvkm_object
*
parent
,
bool
suspend
,
struct
nvkm_object
*
object
)
{
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
;
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_MSVLD
:
addr
=
0x0270
;
break
;
case
NVDEV_ENGINE_MSPDEC
:
addr
=
0x0250
;
break
;
case
NVDEV_ENGINE_MSPPP
:
addr
=
0x0260
;
break
;
default:
return
-
EINVAL
;
}
ret
=
gk104_fifo_chan_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
);
}
return
0
;
}
static
int
gk104_fifo_context_attach
(
struct
nvkm_object
*
parent
,
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
;
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
;
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
;
}
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
;
}
static
int
gk104_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
gk104_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gk104_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
u32
chid
=
chan
->
base
.
chid
;
if
(
chan
->
state
==
RUNNING
&&
(
chan
->
state
=
STOPPED
)
==
STOPPED
)
{
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
),
0x00000800
,
0x00000800
);
gk104_fifo_runlist_update
(
fifo
,
chan
->
engine
);
}
nvkm_wr32
(
device
,
0x800000
+
(
chid
*
8
),
0x00000000
);
return
nvkm_fifo_channel_fini
(
&
chan
->
base
,
suspend
);
}
static
int
gk104_fifo_chan_init
(
struct
nvkm_object
*
object
)
{
struct
nvkm_gpuobj
*
base
=
nv_gpuobj
(
object
->
parent
);
struct
gk104_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
gk104_fifo_chan
*
chan
=
(
void
*
)
object
;
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
;
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
);
gk104_fifo_runlist_update
(
fifo
,
chan
->
engine
);
nvkm_mask
(
device
,
0x800004
+
(
chid
*
8
),
0x00000400
,
0x00000400
);
}
return
0
;
}
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
)
{
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_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"
"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
))
continue
;
engines
|=
(
1
<<
i
);
}
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
);
}
engines
&=
args
->
v0
.
engine
;
if
(
!
engines
)
{
nvif_ioctl
(
parent
,
"unsupported engines %08x
\n
"
,
args
->
v0
.
engine
);
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
);
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
;
usermem
=
chan
->
base
.
chid
*
0x200
;
ioffset
=
args
->
v0
.
ioffset
;
ilength
=
order_base_2
(
args
->
v0
.
ilength
/
8
);
nvkm_kmap
(
fifo
->
user
.
mem
);
for
(
i
=
0
;
i
<
0x200
;
i
+=
4
)
nvkm_wo32
(
fifo
->
user
.
mem
,
usermem
+
i
,
0x00000000
);
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
;
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
,
},
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm204.c
0 → 100644
浏览文件 @
9a65a38c
/*
* Copyright 2015 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 "changk104.h"
#include <nvif/class.h>
struct
nvkm_oclass
gm204_fifo_sclass
[]
=
{
{
MAXWELL_CHANNEL_GPFIFO_A
,
&
gk104_fifo_chan_ofuncs
},
{}
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c
0 → 100644
浏览文件 @
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 "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <nvif/class.h>
#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
)
{
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_chan
*
chan
;
u64
ioffset
,
ilength
;
int
ret
;
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 "
"pushbuf %llx ioffset %016llx "
"ilength %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
vm
,
args
->
v0
.
pushbuf
,
args
->
v0
.
ioffset
,
args
->
v0
.
ilength
);
if
(
args
->
v0
.
vm
)
return
-
ENOENT
;
}
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
;
ret
=
nvkm_ramht_new
(
device
,
0x8000
,
16
,
&
base
->
base
.
gpuobj
,
&
chan
->
ramht
);
if
(
ret
)
return
ret
;
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
)
|
(
4
<<
24
)
/* SEARCH_FULL */
|
(
chan
->
ramht
->
gpuobj
->
node
->
offset
>>
4
));
nvkm_done
(
base
->
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
};
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
浏览文件 @
9a65a38c
...
...
@@ -22,18 +22,15 @@
* Authors: Ben Skeggs
*/
#include "nv04.h"
#include "channv04.h"
#include "regsnv04.h"
#include <core/client.h>
#include <core/engctx.h>
#include <core/handle.h>
#include <core/ramht.h>
#include <subdev/instmem.h>
#include <subdev/timer.h>
#include <engine/sw.h>
#include <nvif/class.h>
#include <nvif/unpack.h>
static
struct
ramfc_desc
nv04_ramfc
[]
=
{
{
32
,
0
,
0x00
,
0
,
NV04_PFIFO_CACHE1_DMA_PUT
},
...
...
@@ -47,268 +44,6 @@ nv04_ramfc[] = {
{}
};
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
int
nv04_fifo_object_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
,
u32
handle
)
{
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
;
}
}
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
;
}
void
nv04_fifo_object_detach
(
struct
nvkm_object
*
parent
,
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
);
nvkm_ramht_remove
(
imem
->
ramht
,
cookie
);
mutex_unlock
(
&
nv_subdev
(
fifo
)
->
mutex
);
}
int
nv04_fifo_context_attach
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
object
)
{
nv_engctx
(
object
)
->
addr
=
nvkm_fifo_chan
(
parent
)
->
chid
;
return
0
;
}
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
)
{
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
;
int
ret
;
nvif_ioctl
(
parent
,
"create channel dma size %d
\n
"
,
size
);
if
(
nvif_unpack
(
args
->
v0
,
0
,
0
,
false
))
{
nvif_ioctl
(
parent
,
"create channel dma vers %d pushbuf %llx "
"offset %08x
\n
"
,
args
->
v0
.
version
,
args
->
v0
.
pushbuf
,
args
->
v0
.
offset
);
}
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
(
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
.
pushgpu
->
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
|
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN
|
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8
);
nvkm_done
(
imem
->
ramfc
);
return
0
;
}
void
nv04_fifo_chan_dtor
(
struct
nvkm_object
*
object
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_instmem
*
imem
=
fifo
->
base
.
engine
.
subdev
.
device
->
imem
;
struct
ramfc_desc
*
c
=
fifo
->
ramfc_desc
;
nvkm_kmap
(
imem
->
ramfc
);
do
{
nvkm_wo32
(
imem
->
ramfc
,
chan
->
ramfc
+
c
->
ctxp
,
0x00000000
);
}
while
((
++
c
)
->
bits
);
nvkm_done
(
imem
->
ramfc
);
nvkm_fifo_channel_destroy
(
&
chan
->
base
);
}
int
nv04_fifo_chan_init
(
struct
nvkm_object
*
object
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
object
;
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
;
}
int
nv04_fifo_chan_fini
(
struct
nvkm_object
*
object
,
bool
suspend
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
->
engine
;
struct
nv04_fifo_chan
*
chan
=
(
void
*
)
object
;
struct
nvkm_device
*
device
=
fifo
->
base
.
engine
.
subdev
.
device
;
struct
nvkm_memory
*
fctx
=
device
->
imem
->
ramfc
;
struct
ramfc_desc
*
c
;
unsigned
long
flags
;
u32
data
=
chan
->
ramfc
;
u32
chid
;
/* prevent fifo context switches */
spin_lock_irqsave
(
&
fifo
->
base
.
lock
,
flags
);
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
;
if
(
chid
==
chan
->
base
.
chid
)
{
nvkm_mask
(
device
,
NV04_PFIFO_CACHE1_DMA_PUSH
,
0x00000001
,
0
);
nvkm_wr32
(
device
,
NV03_PFIFO_CACHE1_PUSH0
,
0
);
nvkm_mask
(
device
,
NV04_PFIFO_CACHE1_PULL0
,
0x00000001
,
0
);
c
=
fifo
->
ramfc_desc
;
do
{
u32
rm
=
((
1ULL
<<
c
->
bits
)
-
1
)
<<
c
->
regs
;
u32
cm
=
((
1ULL
<<
c
->
bits
)
-
1
)
<<
c
->
ctxs
;
u32
rv
=
(
nvkm_rd32
(
device
,
c
->
regp
)
&
rm
)
>>
c
->
regs
;
u32
cv
=
(
nvkm_ro32
(
fctx
,
c
->
ctxp
+
data
)
&
~
cm
);
nvkm_wo32
(
fctx
,
c
->
ctxp
+
data
,
cv
|
(
rv
<<
c
->
ctxs
));
}
while
((
++
c
)
->
bits
);
c
=
fifo
->
ramfc_desc
;
do
{
nvkm_wr32
(
device
,
c
->
regp
,
0x00000000
);
}
while
((
++
c
)
->
bits
);
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_PUSH0
,
1
);
nvkm_wr32
(
device
,
NV04_PFIFO_CACHE1_PULL0
,
1
);
}
/* restore normal operation, after disabling dma mode */
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
);
}
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
};
static
struct
nvkm_oclass
nv04_fifo_sclass
[]
=
{
{
NV03_CHANNEL_DMA
,
&
nv04_fifo_ofuncs
},
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
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
;
}
static
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
,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
void
nv04_fifo_pause
(
struct
nvkm_fifo
*
obj
,
unsigned
long
*
pflags
)
__acquires
(
fifo
->
base
.
lock
)
...
...
@@ -552,36 +287,6 @@ nv04_fifo_intr(struct nvkm_subdev *subdev)
nvkm_wr32
(
device
,
NV03_PFIFO_CACHES
,
reassign
);
}
static
int
nv04_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nv04_fifo
*
fifo
;
int
ret
;
ret
=
nvkm_fifo_create
(
parent
,
engine
,
oclass
,
0
,
15
,
&
fifo
);
*
pobject
=
nv_object
(
fifo
);
if
(
ret
)
return
ret
;
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
;
return
0
;
}
void
nv04_fifo_dtor
(
struct
nvkm_object
*
object
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
;
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
int
nv04_fifo_init
(
struct
nvkm_object
*
object
)
{
...
...
@@ -617,6 +322,36 @@ nv04_fifo_init(struct nvkm_object *object)
return
0
;
}
void
nv04_fifo_dtor
(
struct
nvkm_object
*
object
)
{
struct
nv04_fifo
*
fifo
=
(
void
*
)
object
;
nvkm_fifo_destroy
(
&
fifo
->
base
);
}
static
int
nv04_fifo_ctor
(
struct
nvkm_object
*
parent
,
struct
nvkm_object
*
engine
,
struct
nvkm_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nvkm_object
**
pobject
)
{
struct
nv04_fifo
*
fifo
;
int
ret
;
ret
=
nvkm_fifo_create
(
parent
,
engine
,
oclass
,
0
,
15
,
&
fifo
);
*
pobject
=
nv_object
(
fifo
);
if
(
ret
)
return
ret
;
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
;
return
0
;
}
struct
nvkm_oclass
*
nv04_fifo_oclass
=
&
(
struct
nvkm_oclass
)
{
.
handle
=
NV_ENGINE
(
FIFO
,
0x04
),
...
...
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
浏览文件 @
9a65a38c
#ifndef __NV04_FIFO_H__
#define __NV04_FIFO_H__
#include <engine/fifo.h>
#define NV04_PFIFO_DELAY_0 0x00002040
#define NV04_PFIFO_DMA_TIMESLICE 0x00002044
#define NV04_PFIFO_NEXT_CHANNEL 0x00002050
#define NV03_PFIFO_INTR_0 0x00002100
#define NV03_PFIFO_INTR_EN_0 0x00002140
# define NV_PFIFO_INTR_CACHE_ERROR (1<<0)
# define NV_PFIFO_INTR_RUNOUT (1<<4)
# define NV_PFIFO_INTR_RUNOUT_OVERFLOW (1<<8)
# define NV_PFIFO_INTR_DMA_PUSHER (1<<12)
# define NV_PFIFO_INTR_DMA_PT (1<<16)
# define NV_PFIFO_INTR_SEMAPHORE (1<<20)
# define NV_PFIFO_INTR_ACQUIRE_TIMEOUT (1<<24)
#define NV03_PFIFO_RAMHT 0x00002210
#define NV03_PFIFO_RAMFC 0x00002214
#define NV03_PFIFO_RAMRO 0x00002218
#define NV40_PFIFO_RAMFC 0x00002220
#define NV03_PFIFO_CACHES 0x00002500
#define NV04_PFIFO_MODE 0x00002504
#define NV04_PFIFO_DMA 0x00002508
#define NV04_PFIFO_SIZE 0x0000250c
#define NV50_PFIFO_CTX_TABLE(c) (0x2600+(c)*4)
#define NV50_PFIFO_CTX_TABLE__SIZE 128
#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED (1<<31)
#define NV50_PFIFO_CTX_TABLE_UNK30_BAD (1<<30)
#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80 0x0FFFFFFF
#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84 0x00FFFFFF
#define NV03_PFIFO_CACHE0_PUSH0 0x00003000
#define NV03_PFIFO_CACHE0_PULL0 0x00003040
#define NV04_PFIFO_CACHE0_PULL0 0x00003050
#define NV04_PFIFO_CACHE0_PULL1 0x00003054
#define NV03_PFIFO_CACHE1_PUSH0 0x00003200
#define NV03_PFIFO_CACHE1_PUSH1 0x00003204
#define NV03_PFIFO_CACHE1_PUSH1_DMA (1<<8)
#define NV40_PFIFO_CACHE1_PUSH1_DMA (1<<16)
#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000000f
#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000001f
#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000007f
#define NV03_PFIFO_CACHE1_PUT 0x00003210
#define NV04_PFIFO_CACHE1_DMA_PUSH 0x00003220
#define NV04_PFIFO_CACHE1_DMA_FETCH 0x00003224
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000008
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000010
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000018
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000020
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000028
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000030
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000038
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000040
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000048
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x00000050
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x00000058
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x00000060
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x00000068
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x00000070
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x00000078
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000080
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000088
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000090
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000098
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x000000A0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x000000A8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x000000B0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x000000B8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x000000C0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x000000C8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x000000D0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x000000D8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x000000E0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x000000E8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x000000F0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x000000F8
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 0x0000E000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00002000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00004000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00006000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00008000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x0000A000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x0000C000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x0000E000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 0x001F0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00010000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00020000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00030000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00040000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00050000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00060000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00070000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00080000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00090000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x000A0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x000B0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x000C0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x000D0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x000E0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x000F0000
# define NV_PFIFO_CACHE1_ENDIAN 0x80000000
# define NV_PFIFO_CACHE1_LITTLE_ENDIAN 0x7FFFFFFF
# define NV_PFIFO_CACHE1_BIG_ENDIAN 0x80000000
#define NV04_PFIFO_CACHE1_DMA_STATE 0x00003228
#define NV04_PFIFO_CACHE1_DMA_INSTANCE 0x0000322c
#define NV04_PFIFO_CACHE1_DMA_CTL 0x00003230
#define NV04_PFIFO_CACHE1_DMA_PUT 0x00003240
#define NV04_PFIFO_CACHE1_DMA_GET 0x00003244
#define NV10_PFIFO_CACHE1_REF_CNT 0x00003248
#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000324C
#define NV03_PFIFO_CACHE1_PULL0 0x00003240
#define NV04_PFIFO_CACHE1_PULL0 0x00003250
# define NV04_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000010
# define NV04_PFIFO_CACHE1_PULL0_HASH_BUSY 0x00001000
#define NV03_PFIFO_CACHE1_PULL1 0x00003250
#define NV04_PFIFO_CACHE1_PULL1 0x00003254
#define NV04_PFIFO_CACHE1_HASH 0x00003258
#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT 0x00003260
#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP 0x00003264
#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE 0x00003268
#define NV10_PFIFO_CACHE1_SEMAPHORE 0x0000326C
#define NV03_PFIFO_CACHE1_GET 0x00003270
#define NV04_PFIFO_CACHE1_ENGINE 0x00003280
#define NV04_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0
#define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0
#define NV40_PFIFO_UNK32E4 0x000032E4
#define NV04_PFIFO_CACHE1_METHOD(i) (0x00003800+(i*8))
#define NV04_PFIFO_CACHE1_DATA(i) (0x00003804+(i*8))
#define NV40_PFIFO_CACHE1_METHOD(i) (0x00090000+(i*8))
#define NV40_PFIFO_CACHE1_DATA(i) (0x00090004+(i*8))
#include "priv.h"
struct
ramfc_desc
{
unsigned
bits
:
6
;
...
...
@@ -148,25 +19,10 @@ struct nv04_fifo_base {
struct
nvkm_fifo_base
base
;
};
struct
nv04_fifo_chan
{
struct
nvkm_fifo_chan
base
;
u32
subc
[
8
];
u32
ramfc
;
};
int
nv04_fifo_object_attach
(
struct
nvkm_object
*
,
struct
nvkm_object
*
,
u32
);
void
nv04_fifo_object_detach
(
struct
nvkm_object
*
,
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
);
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
*
);
void
nv04_fifo_pause
(
struct
nvkm_fifo
*
,
unsigned
long
*
);
void
nv04_fifo_start
(
struct
nvkm_fifo
*
,
unsigned
long
*
);
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
0 → 100644
浏览文件 @
9a65a38c
#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
*
);
#endif
drivers/gpu/drm/nouveau/nvkm/engine/fifo/regsnv04.h
0 → 100644
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
浏览文件 @
9a65a38c
...
...
@@ -26,6 +26,7 @@
#include <core/client.h>
#include <engine/fifo.h>
#include <engine/fifo/chan.h>
#include <subdev/instmem.h>
#include <subdev/timer.h>
...
...
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c
浏览文件 @
9a65a38c
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录