Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
370c00f9
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
370c00f9
编写于
8月 14, 2012
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nv50/disp: initial implementation of the various channel object classes
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
446b05a0
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
601 addition
and
112 deletion
+601
-112
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+406
-85
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
+37
-3
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
+9
-6
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
+9
-6
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
+9
-6
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
+9
-6
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
+15
-0
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
+4
-0
drivers/gpu/drm/nouveau/core/include/core/class.h
drivers/gpu/drm/nouveau/core/include/core/class.h
+103
-0
未找到文件。
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
浏览文件 @
370c00f9
...
...
@@ -22,26 +22,198 @@
* Authors: Ben Skeggs
*/
#include <core/object.h>
#include <core/parent.h>
#include <core/handle.h>
#include <core/class.h>
#include <engine/software.h>
#include <engine/disp.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/bar.h>
#include "nv50.h"
/*******************************************************************************
* EVO channel
common helper
s
* EVO channel
base clas
s
******************************************************************************/
static
u32
int
nv50_disp_chan_create_
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
int
chid
,
int
length
,
void
**
pobject
)
{
struct
nv50_disp_base
*
base
=
(
void
*
)
parent
;
struct
nv50_disp_chan
*
chan
;
int
ret
;
if
(
base
->
chan
&
(
1
<<
chid
))
return
-
EBUSY
;
base
->
chan
|=
(
1
<<
chid
);
ret
=
nouveau_namedb_create_
(
parent
,
engine
,
oclass
,
0
,
NULL
,
(
1ULL
<<
NVDEV_ENGINE_DMAOBJ
),
length
,
pobject
);
chan
=
*
pobject
;
if
(
ret
)
return
ret
;
chan
->
chid
=
chid
;
return
0
;
}
void
nv50_disp_chan_destroy
(
struct
nv50_disp_chan
*
chan
)
{
struct
nv50_disp_base
*
base
=
(
void
*
)
nv_object
(
chan
)
->
parent
;
base
->
chan
&=
~
(
1
<<
chan
->
chid
);
nouveau_namedb_destroy
(
&
chan
->
base
);
}
u32
nv50_disp_chan_rd32
(
struct
nouveau_object
*
object
,
u64
addr
)
{
return
0xdeadcafe
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
return
nv_rd32
(
priv
,
0x640000
+
(
chan
->
chid
*
0x1000
)
+
addr
);
}
static
void
void
nv50_disp_chan_wr32
(
struct
nouveau_object
*
object
,
u64
addr
,
u32
data
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
nv_wr32
(
priv
,
0x640000
+
(
chan
->
chid
*
0x1000
)
+
addr
,
data
);
}
/*******************************************************************************
* EVO DMA channel base class
******************************************************************************/
static
int
nv50_disp_dmac_object_attach
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
object
,
u32
name
)
{
struct
nv50_disp_base
*
base
=
(
void
*
)
parent
->
parent
;
struct
nv50_disp_chan
*
chan
=
(
void
*
)
parent
;
u32
addr
=
nv_gpuobj
(
object
)
->
node
->
offset
;
u32
chid
=
chan
->
chid
;
u32
data
=
(
chid
<<
28
)
|
(
addr
<<
10
)
|
chid
;
return
nouveau_ramht_insert
(
base
->
ramht
,
chid
,
name
,
data
);
}
static
void
nv50_disp_dmac_object_detach
(
struct
nouveau_object
*
parent
,
int
cookie
)
{
struct
nv50_disp_base
*
base
=
(
void
*
)
parent
->
parent
;
nouveau_ramht_remove
(
base
->
ramht
,
cookie
);
}
int
nv50_disp_dmac_create_
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
u32
pushbuf
,
int
chid
,
int
length
,
void
**
pobject
)
{
struct
nv50_disp_dmac
*
dmac
;
int
ret
;
ret
=
nv50_disp_chan_create_
(
parent
,
engine
,
oclass
,
chid
,
length
,
pobject
);
dmac
=
*
pobject
;
if
(
ret
)
return
ret
;
dmac
->
pushdma
=
(
void
*
)
nouveau_handle_ref
(
parent
,
pushbuf
);
if
(
!
dmac
->
pushdma
)
return
-
ENOENT
;
switch
(
nv_mclass
(
dmac
->
pushdma
))
{
case
0x0002
:
case
0x003d
:
if
(
dmac
->
pushdma
->
limit
-
dmac
->
pushdma
->
start
!=
0xfff
)
return
-
EINVAL
;
switch
(
dmac
->
pushdma
->
target
)
{
case
NV_MEM_TARGET_VRAM
:
dmac
->
push
=
0x00000000
|
dmac
->
pushdma
->
start
>>
8
;
break
;
default:
return
-
EINVAL
;
}
break
;
default:
return
-
EINVAL
;
}
return
0
;
}
void
nv50_disp_dmac_dtor
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_dmac
*
dmac
=
(
void
*
)
object
;
nouveau_object_ref
(
NULL
,
(
struct
nouveau_object
**
)
&
dmac
->
pushdma
);
nv50_disp_chan_destroy
(
&
dmac
->
base
);
}
static
int
nv50_disp_dmac_init
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_dmac
*
dmac
=
(
void
*
)
object
;
int
chid
=
dmac
->
base
.
chid
;
int
ret
;
ret
=
nv50_disp_chan_init
(
&
dmac
->
base
);
if
(
ret
)
return
ret
;
/* enable error reporting */
nv_mask
(
priv
,
0x610028
,
0x00010001
<<
chid
,
0x00010001
<<
chid
);
/* initialise channel for dma command submission */
nv_wr32
(
priv
,
0x610204
+
(
chid
*
0x0010
),
dmac
->
push
);
nv_wr32
(
priv
,
0x610208
+
(
chid
*
0x0010
),
0x00010000
);
nv_wr32
(
priv
,
0x61020c
+
(
chid
*
0x0010
),
chid
);
nv_mask
(
priv
,
0x610200
+
(
chid
*
0x0010
),
0x00000010
,
0x00000010
);
nv_wr32
(
priv
,
0x640000
+
(
chid
*
0x1000
),
0x00000000
);
nv_wr32
(
priv
,
0x610200
+
(
chid
*
0x0010
),
0x00000013
);
/* wait for it to go inactive */
if
(
!
nv_wait
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x80000000
,
0x00000000
))
{
nv_error
(
dmac
,
"init timeout, 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610200
+
(
chid
*
0x10
)));
return
-
EBUSY
;
}
return
0
;
}
static
int
nv50_disp_dmac_fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_dmac
*
dmac
=
(
void
*
)
object
;
int
chid
=
dmac
->
base
.
chid
;
/* deactivate channel */
nv_mask
(
priv
,
0x610200
+
(
chid
*
0x0010
),
0x00001010
,
0x00001000
);
nv_mask
(
priv
,
0x610200
+
(
chid
*
0x0010
),
0x00000003
,
0x00000000
);
if
(
!
nv_wait
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x001e0000
,
0x00000000
))
{
nv_error
(
dmac
,
"fini timeout, 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610200
+
(
chid
*
0x10
)));
if
(
suspend
)
return
-
EBUSY
;
}
/* disable error reporting */
nv_mask
(
priv
,
0x610028
,
0x00010001
<<
chid
,
0x00000000
<<
chid
);
return
nv50_disp_chan_fini
(
&
dmac
->
base
,
suspend
);
}
/*******************************************************************************
...
...
@@ -54,48 +226,86 @@ nv50_disp_mast_ctor(struct nouveau_object *parent,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_chan
*
chan
;
struct
nv50_display_mast_class
*
args
=
data
;
struct
nv50_disp_dmac
*
mast
;
int
ret
;
ret
=
nouveau_object_create
(
parent
,
engine
,
oclass
,
0
,
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
size
<
sizeof
(
*
args
))
return
-
EINVAL
;
ret
=
nv50_disp_dmac_create_
(
parent
,
engine
,
oclass
,
args
->
pushbuf
,
0
,
sizeof
(
*
mast
),
(
void
**
)
&
mast
);
*
pobject
=
nv_object
(
mast
);
if
(
ret
)
return
ret
;
nv_parent
(
mast
)
->
object_attach
=
nv50_disp_dmac_object_attach
;
nv_parent
(
mast
)
->
object_detach
=
nv50_disp_dmac_object_detach
;
return
0
;
}
static
void
nv50_disp_mast_dtor
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
nouveau_object_destroy
(
&
chan
->
base
);
}
static
int
nv50_disp_mast_init
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_dmac
*
mast
=
(
void
*
)
object
;
int
ret
;
ret
=
n
ouveau_object_init
(
&
chan
->
base
);
ret
=
n
v50_disp_chan_init
(
&
mast
->
base
);
if
(
ret
)
return
ret
;
/* enable error reporting */
nv_mask
(
priv
,
0x610028
,
0x00010001
,
0x00010001
);
/* attempt to unstick channel from some unknown state */
if
((
nv_rd32
(
priv
,
0x610200
)
&
0x009f0000
)
==
0x00020000
)
nv_mask
(
priv
,
0x610200
,
0x00800000
,
0x00800000
);
if
((
nv_rd32
(
priv
,
0x610200
)
&
0x003f0000
)
==
0x00030000
)
nv_mask
(
priv
,
0x610200
,
0x00600000
,
0x00600000
);
/* initialise channel for dma command submission */
nv_wr32
(
priv
,
0x610204
,
mast
->
push
);
nv_wr32
(
priv
,
0x610208
,
0x00010000
);
nv_wr32
(
priv
,
0x61020c
,
0x00000000
);
nv_mask
(
priv
,
0x610200
,
0x00000010
,
0x00000010
);
nv_wr32
(
priv
,
0x640000
,
0x00000000
);
nv_wr32
(
priv
,
0x610200
,
0x01000013
);
/* wait for it to go inactive */
if
(
!
nv_wait
(
priv
,
0x610200
,
0x80000000
,
0x00000000
))
{
nv_error
(
mast
,
"init: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610200
));
return
-
EBUSY
;
}
return
0
;
}
static
int
nv50_disp_mast_fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
return
nouveau_object_fini
(
&
chan
->
base
,
suspend
);
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_dmac
*
mast
=
(
void
*
)
object
;
/* deactivate channel */
nv_mask
(
priv
,
0x610200
,
0x00000010
,
0x00000000
);
nv_mask
(
priv
,
0x610200
,
0x00000003
,
0x00000000
);
if
(
!
nv_wait
(
priv
,
0x610200
,
0x001e0000
,
0x00000000
))
{
nv_error
(
mast
,
"fini: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610200
));
if
(
suspend
)
return
-
EBUSY
;
}
/* disable error reporting */
nv_mask
(
priv
,
0x610028
,
0x00010001
,
0x00000000
);
return
nv50_disp_chan_fini
(
&
mast
->
base
,
suspend
);
}
struct
nouveau_ofuncs
nv50_disp_mast_ofuncs
=
{
.
ctor
=
nv50_disp_mast_ctor
,
.
dtor
=
nv50_disp_
mast
_dtor
,
.
dtor
=
nv50_disp_
dmac
_dtor
,
.
init
=
nv50_disp_mast_init
,
.
fini
=
nv50_disp_mast_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
...
...
@@ -103,56 +313,76 @@ nv50_disp_mast_ofuncs = {
};
/*******************************************************************************
* EVO
DMA channel objects (sync, overlay)
* EVO
sync channel objects
******************************************************************************/
static
int
nv50_disp_
dma
c_ctor
(
struct
nouveau_object
*
parent
,
nv50_disp_
syn
c_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_chan
*
chan
;
struct
nv50_display_sync_class
*
args
=
data
;
struct
nv50_disp_dmac
*
dmac
;
int
ret
;
ret
=
nouveau_object_create
(
parent
,
engine
,
oclass
,
0
,
&
chan
);
*
pobject
=
nv_object
(
chan
);
if
(
size
<
sizeof
(
*
data
)
||
args
->
head
>
1
)
return
-
EINVAL
;
ret
=
nv50_disp_dmac_create_
(
parent
,
engine
,
oclass
,
args
->
pushbuf
,
1
+
args
->
head
,
sizeof
(
*
dmac
),
(
void
**
)
&
dmac
);
*
pobject
=
nv_object
(
dmac
);
if
(
ret
)
return
ret
;
nv_parent
(
dmac
)
->
object_attach
=
nv50_disp_dmac_object_attach
;
nv_parent
(
dmac
)
->
object_detach
=
nv50_disp_dmac_object_detach
;
return
0
;
}
static
void
nv50_disp_dmac_dtor
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
nouveau_object_destroy
(
&
chan
->
base
);
}
struct
nouveau_ofuncs
nv50_disp_sync_ofuncs
=
{
.
ctor
=
nv50_disp_sync_ctor
,
.
dtor
=
nv50_disp_dmac_dtor
,
.
init
=
nv50_disp_dmac_init
,
.
fini
=
nv50_disp_dmac_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
.
wr32
=
nv50_disp_chan_wr32
,
};
/*******************************************************************************
* EVO overlay channel objects
******************************************************************************/
static
int
nv50_disp_dmac_init
(
struct
nouveau_object
*
object
)
nv50_disp_ovly_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
struct
nv50_display_ovly_class
*
args
=
data
;
struct
nv50_disp_dmac
*
dmac
;
int
ret
;
ret
=
nouveau_object_init
(
&
chan
->
base
);
if
(
size
<
sizeof
(
*
data
)
||
args
->
head
>
1
)
return
-
EINVAL
;
ret
=
nv50_disp_dmac_create_
(
parent
,
engine
,
oclass
,
args
->
pushbuf
,
3
+
args
->
head
,
sizeof
(
*
dmac
),
(
void
**
)
&
dmac
);
*
pobject
=
nv_object
(
dmac
);
if
(
ret
)
return
ret
;
nv_parent
(
dmac
)
->
object_attach
=
nv50_disp_dmac_object_attach
;
nv_parent
(
dmac
)
->
object_detach
=
nv50_disp_dmac_object_detach
;
return
0
;
}
static
int
nv50_disp_dmac_fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
return
nouveau_object_fini
(
&
chan
->
base
,
suspend
);
}
struct
nouveau_ofuncs
nv50_disp_
dmac
_ofuncs
=
{
.
ctor
=
nv50_disp_
dmac
_ctor
,
nv50_disp_
ovly
_ofuncs
=
{
.
ctor
=
nv50_disp_
ovly
_ctor
,
.
dtor
=
nv50_disp_dmac_dtor
,
.
init
=
nv50_disp_dmac_init
,
.
fini
=
nv50_disp_dmac_fini
,
...
...
@@ -161,56 +391,138 @@ nv50_disp_dmac_ofuncs = {
};
/*******************************************************************************
* EVO PIO channel
objects (cursor, immediate overlay controls)
* EVO PIO channel
base class
******************************************************************************/
static
int
nv50_disp_pioc_c
tor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
nv50_disp_pioc_c
reate_
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
int
chid
,
int
length
,
void
**
pobject
)
{
struct
nv50_disp_chan
*
chan
;
return
nv50_disp_chan_create_
(
parent
,
engine
,
oclass
,
chid
,
length
,
pobject
);
}
static
void
nv50_disp_pioc_dtor
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_pioc
*
pioc
=
(
void
*
)
object
;
nv50_disp_chan_destroy
(
&
pioc
->
base
);
}
static
int
nv50_disp_pioc_init
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_pioc
*
pioc
=
(
void
*
)
object
;
int
chid
=
pioc
->
base
.
chid
;
int
ret
;
ret
=
nouveau_object_create
(
parent
,
engine
,
oclass
,
0
,
&
chan
);
*
pobject
=
nv_object
(
chan
);
ret
=
nv50_disp_chan_init
(
&
pioc
->
base
);
if
(
ret
)
return
ret
;
nv_wr32
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x00002000
);
if
(
!
nv_wait
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x00000000
,
0x00000000
))
{
nv_error
(
pioc
,
"timeout0: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610200
+
(
chid
*
0x10
)));
return
-
EBUSY
;
}
nv_wr32
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x00000001
);
if
(
!
nv_wait
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x00030000
,
0x00010000
))
{
nv_error
(
pioc
,
"timeout1: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610200
+
(
chid
*
0x10
)));
return
-
EBUSY
;
}
return
0
;
}
static
void
nv50_disp_pioc_
dtor
(
struct
nouveau_object
*
object
)
static
int
nv50_disp_pioc_
fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
nouveau_object_destroy
(
&
chan
->
base
);
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_pioc
*
pioc
=
(
void
*
)
object
;
int
chid
=
pioc
->
base
.
chid
;
nv_mask
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x00000001
,
0x00000000
);
if
(
!
nv_wait
(
priv
,
0x610200
+
(
chid
*
0x10
),
0x00030000
,
0x00000000
))
{
nv_error
(
pioc
,
"timeout: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610200
+
(
chid
*
0x10
)));
if
(
suspend
)
return
-
EBUSY
;
}
return
nv50_disp_chan_fini
(
&
pioc
->
base
,
suspend
);
}
/*******************************************************************************
* EVO immediate overlay channel objects
******************************************************************************/
static
int
nv50_disp_pioc_init
(
struct
nouveau_object
*
object
)
nv50_disp_oimm_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
struct
nv50_display_oimm_class
*
args
=
data
;
struct
nv50_disp_pioc
*
pioc
;
int
ret
;
ret
=
nouveau_object_init
(
&
chan
->
base
);
if
(
size
<
sizeof
(
*
args
)
||
args
->
head
>
1
)
return
-
EINVAL
;
ret
=
nv50_disp_pioc_create_
(
parent
,
engine
,
oclass
,
5
+
args
->
head
,
sizeof
(
*
pioc
),
(
void
**
)
&
pioc
);
*
pobject
=
nv_object
(
pioc
);
if
(
ret
)
return
ret
;
return
0
;
}
struct
nouveau_ofuncs
nv50_disp_oimm_ofuncs
=
{
.
ctor
=
nv50_disp_oimm_ctor
,
.
dtor
=
nv50_disp_pioc_dtor
,
.
init
=
nv50_disp_pioc_init
,
.
fini
=
nv50_disp_pioc_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
.
wr32
=
nv50_disp_chan_wr32
,
};
/*******************************************************************************
* EVO cursor channel objects
******************************************************************************/
static
int
nv50_disp_pioc_fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
nv50_disp_curs_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_chan
*
chan
=
(
void
*
)
object
;
return
nouveau_object_fini
(
&
chan
->
base
,
suspend
);
struct
nv50_display_curs_class
*
args
=
data
;
struct
nv50_disp_pioc
*
pioc
;
int
ret
;
if
(
size
<
sizeof
(
*
args
)
||
args
->
head
>
1
)
return
-
EINVAL
;
ret
=
nv50_disp_pioc_create_
(
parent
,
engine
,
oclass
,
7
+
args
->
head
,
sizeof
(
*
pioc
),
(
void
**
)
&
pioc
);
*
pobject
=
nv_object
(
pioc
);
if
(
ret
)
return
ret
;
return
0
;
}
struct
nouveau_ofuncs
nv50_disp_
pioc
_ofuncs
=
{
.
ctor
=
nv50_disp_
pioc
_ctor
,
nv50_disp_
curs
_ofuncs
=
{
.
ctor
=
nv50_disp_
curs
_ctor
,
.
dtor
=
nv50_disp_pioc_dtor
,
.
init
=
nv50_disp_pioc_init
,
.
fini
=
nv50_disp_pioc_fini
,
...
...
@@ -238,13 +550,14 @@ nv50_disp_base_ctor(struct nouveau_object *parent,
if
(
ret
)
return
ret
;
return
0
;
return
nouveau_ramht_new
(
parent
,
parent
,
0x1000
,
0
,
&
base
->
ramht
)
;
}
static
void
nv50_disp_base_dtor
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_base
*
base
=
(
void
*
)
object
;
nouveau_ramht_ref
(
NULL
,
&
base
->
ramht
);
nouveau_parent_destroy
(
&
base
->
base
);
}
...
...
@@ -308,11 +621,11 @@ nv50_disp_base_init(struct nouveau_object *object)
}
/* point at display engine memory area (hash table, objects) */
nv_wr32
(
priv
,
0x610010
,
(
nv_gpuobj
(
object
->
paren
t
)
->
addr
>>
8
)
|
9
);
nv_wr32
(
priv
,
0x610010
,
(
nv_gpuobj
(
base
->
ramh
t
)
->
addr
>>
8
)
|
9
);
/* enable supervisor interrupts, disable everything else */
nv_wr32
(
priv
,
0x61002
4
,
0x00000370
);
nv_wr32
(
priv
,
0x61002
0
,
0x00000000
);
nv_wr32
(
priv
,
0x61002
c
,
0x00000370
);
nv_wr32
(
priv
,
0x61002
8
,
0x00000000
);
return
0
;
}
...
...
@@ -326,10 +639,6 @@ nv50_disp_base_fini(struct nouveau_object *object, bool suspend)
nv_wr32
(
priv
,
0x610024
,
0x00000000
);
nv_wr32
(
priv
,
0x610020
,
0x00000000
);
/* return control of display to vbios */
nv_mask
(
priv
,
0x6194e8
,
0x00000001
,
0x00000001
);
nv_wait
(
priv
,
0x6194e8
,
0x00000002
,
0x00000002
);
return
nouveau_parent_fini
(
&
base
->
base
,
suspend
);
}
...
...
@@ -343,16 +652,17 @@ nv50_disp_base_ofuncs = {
static
struct
nouveau_oclass
nv50_disp_base_oclass
[]
=
{
{
0x5070
,
&
nv50_disp_base_ofuncs
},
{
NV50_DISP_CLASS
,
&
nv50_disp_base_ofuncs
},
{}
};
static
struct
nouveau_oclass
nv50_disp_sclass
[]
=
{
{
0x507d
,
&
nv50_disp_mast_ofuncs
},
/* master */
{
0x507c
,
&
nv50_disp_dmac_ofuncs
},
/* sync */
{
0x507e
,
&
nv50_disp_dmac_ofuncs
},
/* overlay */
{
0x507b
,
&
nv50_disp_pioc_ofuncs
},
/* overlay (pio) */
{
0x507a
,
&
nv50_disp_pioc_ofuncs
},
/* cursor (pio) */
{
NV50_DISP_MAST_CLASS
,
&
nv50_disp_mast_ofuncs
},
{
NV50_DISP_SYNC_CLASS
,
&
nv50_disp_sync_ofuncs
},
{
NV50_DISP_OVLY_CLASS
,
&
nv50_disp_ovly_ofuncs
},
{
NV50_DISP_OIMM_CLASS
,
&
nv50_disp_oimm_ofuncs
},
{
NV50_DISP_CURS_CLASS
,
&
nv50_disp_curs_ofuncs
},
{}
};
...
...
@@ -367,16 +677,27 @@ nv50_disp_data_ctor(struct nouveau_object *parent,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
engine
;
struct
nouveau_engctx
*
ectx
;
int
ret
;
int
ret
=
-
EBUSY
;
ret
=
nouveau_engctx_create
(
parent
,
engine
,
oclass
,
NULL
,
0x10000
,
0x10000
,
NVOBJ_FLAG_ZERO_ALLOC
,
&
ectx
);
*
pobject
=
nv_object
(
ectx
);
if
(
ret
)
return
ret
;
/* no context needed for channel objects... */
if
(
nv_mclass
(
parent
)
!=
NV_DEVICE_CLASS
)
{
atomic_inc
(
&
parent
->
refcount
);
*
pobject
=
parent
;
return
0
;
}
return
0
;
/* allocate display hardware to client */
mutex_lock
(
&
nv_subdev
(
priv
)
->
mutex
);
if
(
list_empty
(
&
nv_engine
(
priv
)
->
contexts
))
{
ret
=
nouveau_engctx_create
(
parent
,
engine
,
oclass
,
NULL
,
0x10000
,
0x10000
,
NVOBJ_FLAG_HEAP
,
&
ectx
);
*
pobject
=
nv_object
(
ectx
);
}
mutex_unlock
(
&
nv_subdev
(
priv
)
->
mutex
);
return
ret
;
}
struct
nouveau_oclass
...
...
@@ -455,8 +776,8 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
static
int
nv50_disp_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_priv
*
priv
;
int
ret
;
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
浏览文件 @
370c00f9
...
...
@@ -2,6 +2,10 @@
#define __NV50_DISP_H__
#include <core/parent.h>
#include <core/namedb.h>
#include <core/ramht.h>
#include <engine/dmaobj.h>
#include <engine/disp.h>
struct
nv50_disp_priv
{
...
...
@@ -20,15 +24,45 @@ struct nv50_disp_priv {
struct
nv50_disp_base
{
struct
nouveau_parent
base
;
struct
nouveau_ramht
*
ramht
;
u32
chan
;
};
struct
nv50_disp_chan
{
struct
nouveau_object
base
;
struct
nouveau_namedb
base
;
int
chid
;
};
int
nv50_disp_chan_create_
(
struct
nouveau_object
*
,
struct
nouveau_object
*
,
struct
nouveau_oclass
*
,
int
,
int
,
void
**
);
void
nv50_disp_chan_destroy
(
struct
nv50_disp_chan
*
);
u32
nv50_disp_chan_rd32
(
struct
nouveau_object
*
,
u64
);
void
nv50_disp_chan_wr32
(
struct
nouveau_object
*
,
u64
,
u32
);
#define nv50_disp_chan_init(a) \
nouveau_namedb_init(&(a)->base)
#define nv50_disp_chan_fini(a,b) \
nouveau_namedb_fini(&(a)->base, (b))
int
nv50_disp_dmac_create_
(
struct
nouveau_object
*
,
struct
nouveau_object
*
,
struct
nouveau_oclass
*
,
u32
,
int
,
int
,
void
**
);
void
nv50_disp_dmac_dtor
(
struct
nouveau_object
*
);
struct
nv50_disp_dmac
{
struct
nv50_disp_chan
base
;
struct
nouveau_dmaobj
*
pushdma
;
u32
push
;
};
struct
nv50_disp_pioc
{
struct
nv50_disp_chan
base
;
};
extern
struct
nouveau_ofuncs
nv50_disp_mast_ofuncs
;
extern
struct
nouveau_ofuncs
nv50_disp_dmac_ofuncs
;
extern
struct
nouveau_ofuncs
nv50_disp_pioc_ofuncs
;
extern
struct
nouveau_ofuncs
nv50_disp_sync_ofuncs
;
extern
struct
nouveau_ofuncs
nv50_disp_ovly_ofuncs
;
extern
struct
nouveau_ofuncs
nv50_disp_oimm_ofuncs
;
extern
struct
nouveau_ofuncs
nv50_disp_curs_ofuncs
;
extern
struct
nouveau_ofuncs
nv50_disp_base_ofuncs
;
extern
struct
nouveau_oclass
nv50_disp_cclass
;
void
nv50_disp_intr
(
struct
nouveau_subdev
*
);
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
浏览文件 @
370c00f9
...
...
@@ -25,21 +25,24 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
static
struct
nouveau_oclass
nv84_disp_sclass
[]
=
{
{
0x827d
,
&
nv50_disp_mast_ofuncs
},
/* master */
{
0x827c
,
&
nv50_disp_dmac_ofuncs
},
/* sync */
{
0x827e
,
&
nv50_disp_dmac_ofuncs
},
/* overlay */
{
0x827b
,
&
nv50_disp_pioc_ofuncs
},
/* overlay (pio) */
{
0x827a
,
&
nv50_disp_pioc_ofuncs
},
/* cursor (pio) */
{
NV84_DISP_MAST_CLASS
,
&
nv50_disp_mast_ofuncs
},
{
NV84_DISP_SYNC_CLASS
,
&
nv50_disp_sync_ofuncs
},
{
NV84_DISP_OVLY_CLASS
,
&
nv50_disp_ovly_ofuncs
},
{
NV84_DISP_OIMM_CLASS
,
&
nv50_disp_oimm_ofuncs
},
{
NV84_DISP_CURS_CLASS
,
&
nv50_disp_curs_ofuncs
},
{}
};
static
struct
nouveau_oclass
nv84_disp_base_oclass
[]
=
{
{
0x8270
,
&
nv50_disp_base_ofuncs
},
{
NV84_DISP_CLASS
,
&
nv50_disp_base_ofuncs
},
{}
};
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
浏览文件 @
370c00f9
...
...
@@ -25,21 +25,24 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
static
struct
nouveau_oclass
nv94_disp_sclass
[]
=
{
{
0x887d
,
&
nv50_disp_mast_ofuncs
},
/* master */
{
0x887c
,
&
nv50_disp_dmac_ofuncs
},
/* sync */
{
0x887e
,
&
nv50_disp_dmac_ofuncs
},
/* overlay */
{
0x887b
,
&
nv50_disp_pioc_ofuncs
},
/* overlay (pio) */
{
0x887a
,
&
nv50_disp_pioc_ofuncs
},
/* cursor (pio) */
{
NV94_DISP_MAST_CLASS
,
&
nv50_disp_mast_ofuncs
},
{
NV94_DISP_SYNC_CLASS
,
&
nv50_disp_sync_ofuncs
},
{
NV94_DISP_OVLY_CLASS
,
&
nv50_disp_ovly_ofuncs
},
{
NV94_DISP_OIMM_CLASS
,
&
nv50_disp_oimm_ofuncs
},
{
NV94_DISP_CURS_CLASS
,
&
nv50_disp_curs_ofuncs
},
{}
};
static
struct
nouveau_oclass
nv94_disp_base_oclass
[]
=
{
{
0x8870
,
&
nv50_disp_base_ofuncs
},
{
NV94_DISP_CLASS
,
&
nv50_disp_base_ofuncs
},
{}
};
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
浏览文件 @
370c00f9
...
...
@@ -25,21 +25,24 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
static
struct
nouveau_oclass
nva0_disp_sclass
[]
=
{
{
0x837d
,
&
nv50_disp_mast_ofuncs
},
/* master */
{
0x837c
,
&
nv50_disp_dmac_ofuncs
},
/* sync */
{
0x837e
,
&
nv50_disp_dmac_ofuncs
},
/* overlay */
{
0x837b
,
&
nv50_disp_pioc_ofuncs
},
/* overlay (pio) */
{
0x837a
,
&
nv50_disp_pioc_ofuncs
},
/* cursor (pio) */
{
NVA0_DISP_MAST_CLASS
,
&
nv50_disp_mast_ofuncs
},
{
NVA0_DISP_SYNC_CLASS
,
&
nv50_disp_sync_ofuncs
},
{
NVA0_DISP_OVLY_CLASS
,
&
nv50_disp_ovly_ofuncs
},
{
NVA0_DISP_OIMM_CLASS
,
&
nv50_disp_oimm_ofuncs
},
{
NVA0_DISP_CURS_CLASS
,
&
nv50_disp_curs_ofuncs
},
{}
};
static
struct
nouveau_oclass
nva0_disp_base_oclass
[]
=
{
{
0x8370
,
&
nv50_disp_base_ofuncs
},
{
NVA0_DISP_CLASS
,
&
nv50_disp_base_ofuncs
},
{}
};
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
浏览文件 @
370c00f9
...
...
@@ -25,21 +25,24 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
static
struct
nouveau_oclass
nva3_disp_sclass
[]
=
{
{
0x857d
,
&
nv50_disp_mast_ofuncs
},
/* master */
{
0x857c
,
&
nv50_disp_dmac_ofuncs
},
/* sync */
{
0x857e
,
&
nv50_disp_dmac_ofuncs
},
/* overlay */
{
0x857b
,
&
nv50_disp_pioc_ofuncs
},
/* overlay (pio) */
{
0x857a
,
&
nv50_disp_pioc_ofuncs
},
/* cursor (pio) */
{
NVA3_DISP_MAST_CLASS
,
&
nv50_disp_mast_ofuncs
},
{
NVA3_DISP_SYNC_CLASS
,
&
nv50_disp_sync_ofuncs
},
{
NVA3_DISP_OVLY_CLASS
,
&
nv50_disp_ovly_ofuncs
},
{
NVA3_DISP_OIMM_CLASS
,
&
nv50_disp_oimm_ofuncs
},
{
NVA3_DISP_CURS_CLASS
,
&
nv50_disp_curs_ofuncs
},
{}
};
static
struct
nouveau_oclass
nva3_disp_base_oclass
[]
=
{
{
0x8570
,
&
nv50_disp_base_ofuncs
},
{
NVA3_DISP_CLASS
,
&
nv50_disp_base_ofuncs
},
{}
};
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
浏览文件 @
370c00f9
...
...
@@ -48,6 +48,21 @@ nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
case
NV84_CHANNEL_DMA_CLASS
:
case
NV50_CHANNEL_IND_CLASS
:
case
NV84_CHANNEL_IND_CLASS
:
case
NV50_DISP_MAST_CLASS
:
case
NV84_DISP_MAST_CLASS
:
case
NV94_DISP_MAST_CLASS
:
case
NVA0_DISP_MAST_CLASS
:
case
NVA3_DISP_MAST_CLASS
:
case
NV50_DISP_SYNC_CLASS
:
case
NV84_DISP_SYNC_CLASS
:
case
NV94_DISP_SYNC_CLASS
:
case
NVA0_DISP_SYNC_CLASS
:
case
NVA3_DISP_SYNC_CLASS
:
case
NV50_DISP_OVLY_CLASS
:
case
NV84_DISP_OVLY_CLASS
:
case
NV94_DISP_OVLY_CLASS
:
case
NVA0_DISP_OVLY_CLASS
:
case
NVA3_DISP_OVLY_CLASS
:
break
;
default:
return
-
EINVAL
;
...
...
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
浏览文件 @
370c00f9
...
...
@@ -45,6 +45,10 @@ nvc0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
if
(
!
nv_iclass
(
parent
,
NV_ENGCTX_CLASS
))
{
switch
(
nv_mclass
(
parent
->
parent
))
{
case
NVA3_DISP_MAST_CLASS
:
case
NVA3_DISP_SYNC_CLASS
:
case
NVA3_DISP_OVLY_CLASS
:
break
;
default:
return
-
EINVAL
;
}
...
...
drivers/gpu/drm/nouveau/core/include/core/class.h
浏览文件 @
370c00f9
...
...
@@ -153,4 +153,107 @@ struct nve0_channel_ind_class {
u32
engine
;
};
/* 5070: NV50_DISP
* 8270: NV84_DISP
* 8370: NVA0_DISP
* 8870: NV94_DISP
* 8570: NVA3_DISP
*/
#define NV50_DISP_CLASS 0x00005070
#define NV84_DISP_CLASS 0x00008270
#define NVA0_DISP_CLASS 0x00008370
#define NV94_DISP_CLASS 0x00008870
#define NVA3_DISP_CLASS 0x00008570
struct
nv50_display_class
{
};
/* 507a: NV50_DISP_CURS
* 827a: NV84_DISP_CURS
* 837a: NVA0_DISP_CURS
* 887a: NV94_DISP_CURS
* 857a: NVA3_DISP_CURS
*/
#define NV50_DISP_CURS_CLASS 0x0000507a
#define NV84_DISP_CURS_CLASS 0x0000827a
#define NVA0_DISP_CURS_CLASS 0x0000837a
#define NV94_DISP_CURS_CLASS 0x0000887a
#define NVA3_DISP_CURS_CLASS 0x0000857a
struct
nv50_display_curs_class
{
u32
head
;
};
/* 507b: NV50_DISP_OIMM
* 827b: NV84_DISP_OIMM
* 837b: NVA0_DISP_OIMM
* 887b: NV94_DISP_OIMM
* 857b: NVA3_DISP_OIMM
*/
#define NV50_DISP_OIMM_CLASS 0x0000507b
#define NV84_DISP_OIMM_CLASS 0x0000827b
#define NVA0_DISP_OIMM_CLASS 0x0000837b
#define NV94_DISP_OIMM_CLASS 0x0000887b
#define NVA3_DISP_OIMM_CLASS 0x0000857b
struct
nv50_display_oimm_class
{
u32
head
;
};
/* 507c: NV50_DISP_SYNC
* 827c: NV84_DISP_SYNC
* 837c: NVA0_DISP_SYNC
* 887c: NV94_DISP_SYNC
* 857c: NVA3_DISP_SYNC
*/
#define NV50_DISP_SYNC_CLASS 0x0000507c
#define NV84_DISP_SYNC_CLASS 0x0000827c
#define NVA0_DISP_SYNC_CLASS 0x0000837c
#define NV94_DISP_SYNC_CLASS 0x0000887c
#define NVA3_DISP_SYNC_CLASS 0x0000857c
struct
nv50_display_sync_class
{
u32
pushbuf
;
u32
head
;
};
/* 507d: NV50_DISP_MAST
* 827d: NV84_DISP_MAST
* 837d: NVA0_DISP_MAST
* 887d: NV94_DISP_MAST
* 857d: NVA3_DISP_MAST
*/
#define NV50_DISP_MAST_CLASS 0x0000507d
#define NV84_DISP_MAST_CLASS 0x0000827d
#define NVA0_DISP_MAST_CLASS 0x0000837d
#define NV94_DISP_MAST_CLASS 0x0000887d
#define NVA3_DISP_MAST_CLASS 0x0000857d
struct
nv50_display_mast_class
{
u32
pushbuf
;
};
/* 507e: NV50_DISP_OVLY
* 827e: NV84_DISP_OVLY
* 837e: NVA0_DISP_OVLY
* 887e: NV94_DISP_OVLY
* 857e: NVA3_DISP_OVLY
*/
#define NV50_DISP_OVLY_CLASS 0x0000507e
#define NV84_DISP_OVLY_CLASS 0x0000827e
#define NVA0_DISP_OVLY_CLASS 0x0000837e
#define NV94_DISP_OVLY_CLASS 0x0000887e
#define NVA3_DISP_OVLY_CLASS 0x0000857e
struct
nv50_display_ovly_class
{
u32
pushbuf
;
u32
head
;
};
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录