Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
46654061
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
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看板
提交
46654061
编写于
8月 28, 2012
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nvd0-nve0/disp: initial implementation of evo channel classes
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
944234d6
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
671 addition
and
14 deletion
+671
-14
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/Makefile
+1
-0
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
+9
-0
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+544
-12
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
+84
-0
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
+6
-0
drivers/gpu/drm/nouveau/core/include/core/class.h
drivers/gpu/drm/nouveau/core/include/core/class.h
+24
-0
drivers/gpu/drm/nouveau/core/include/engine/disp.h
drivers/gpu/drm/nouveau/core/include/engine/disp.h
+1
-0
drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
+2
-2
未找到文件。
drivers/gpu/drm/nouveau/Makefile
浏览文件 @
46654061
...
...
@@ -135,6 +135,7 @@ nouveau-y += core/engine/disp/nv94.o
nouveau-y
+=
core/engine/disp/nva0.o
nouveau-y
+=
core/engine/disp/nva3.o
nouveau-y
+=
core/engine/disp/nvd0.o
nouveau-y
+=
core/engine/disp/nve0.o
nouveau-y
+=
core/engine/disp/vga.o
nouveau-y
+=
core/engine/fifo/base.o
nouveau-y
+=
core/engine/fifo/nv04.o
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
浏览文件 @
46654061
...
...
@@ -67,4 +67,13 @@ extern struct nouveau_ofuncs nv50_disp_base_ofuncs;
extern
struct
nouveau_oclass
nv50_disp_cclass
;
void
nv50_disp_intr
(
struct
nouveau_subdev
*
);
extern
struct
nouveau_ofuncs
nvd0_disp_mast_ofuncs
;
extern
struct
nouveau_ofuncs
nvd0_disp_sync_ofuncs
;
extern
struct
nouveau_ofuncs
nvd0_disp_ovly_ofuncs
;
extern
struct
nouveau_ofuncs
nvd0_disp_oimm_ofuncs
;
extern
struct
nouveau_ofuncs
nvd0_disp_curs_ofuncs
;
extern
struct
nouveau_ofuncs
nvd0_disp_base_ofuncs
;
extern
struct
nouveau_oclass
nvd0_disp_cclass
;
void
nvd0_disp_intr
(
struct
nouveau_subdev
*
);
#endif
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
浏览文件 @
46654061
...
...
@@ -22,22 +22,549 @@
* Authors: Ben Skeggs
*/
#include <subdev/bar.h>
#include <core/object.h>
#include <core/parent.h>
#include <core/handle.h>
#include <core/class.h>
#include <engine/software.h>
#include <engine/disp.h>
struct
nvd0_disp_priv
{
struct
nouveau_disp
base
;
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/bar.h>
#include "nv50.h"
/*******************************************************************************
* EVO DMA channel base class
******************************************************************************/
static
int
nvd0_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
data
=
(
chan
->
chid
<<
27
)
|
(
addr
<<
9
)
|
0x00000001
;
return
nouveau_ramht_insert
(
base
->
ramht
,
chan
->
chid
,
name
,
data
);
}
static
void
nvd0_disp_dmac_object_detach
(
struct
nouveau_object
*
parent
,
int
cookie
)
{
struct
nv50_disp_base
*
base
=
(
void
*
)
parent
->
parent
;
nouveau_ramht_remove
(
base
->
ramht
,
cookie
);
}
static
int
nvd0_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
,
0x610090
,
0x00000001
<<
chid
,
0x00000001
<<
chid
);
nv_mask
(
priv
,
0x6100a0
,
0x00000001
<<
chid
,
0x00000001
<<
chid
);
/* initialise channel for dma command submission */
nv_wr32
(
priv
,
0x610494
+
(
chid
*
0x0010
),
dmac
->
push
);
nv_wr32
(
priv
,
0x610498
+
(
chid
*
0x0010
),
0x00010000
);
nv_wr32
(
priv
,
0x61049c
+
(
chid
*
0x0010
),
0x00000001
);
nv_mask
(
priv
,
0x610490
+
(
chid
*
0x0010
),
0x00000010
,
0x00000010
);
nv_wr32
(
priv
,
0x640000
+
(
chid
*
0x1000
),
0x00000000
);
nv_wr32
(
priv
,
0x610490
+
(
chid
*
0x0010
),
0x00000013
);
/* wait for it to go inactive */
if
(
!
nv_wait
(
priv
,
0x610490
+
(
chid
*
0x10
),
0x80000000
,
0x00000000
))
{
nv_error
(
dmac
,
"init: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610490
+
(
chid
*
0x10
)));
return
-
EBUSY
;
}
return
0
;
}
static
int
nvd0_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
,
0x610490
+
(
chid
*
0x0010
),
0x00001010
,
0x00001000
);
nv_mask
(
priv
,
0x610490
+
(
chid
*
0x0010
),
0x00000003
,
0x00000000
);
if
(
!
nv_wait
(
priv
,
0x610490
+
(
chid
*
0x10
),
0x001e0000
,
0x00000000
))
{
nv_error
(
dmac
,
"fini: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610490
+
(
chid
*
0x10
)));
if
(
suspend
)
return
-
EBUSY
;
}
/* disable error reporting */
nv_mask
(
priv
,
0x610090
,
0x00000001
<<
chid
,
0x00000000
);
nv_mask
(
priv
,
0x6100a0
,
0x00000001
<<
chid
,
0x00000000
);
return
nv50_disp_chan_fini
(
&
dmac
->
base
,
suspend
);
}
/*******************************************************************************
* EVO master channel object
******************************************************************************/
static
int
nvd0_disp_mast_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_display_mast_class
*
args
=
data
;
struct
nv50_disp_dmac
*
mast
;
int
ret
;
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
=
nvd0_disp_dmac_object_attach
;
nv_parent
(
mast
)
->
object_detach
=
nvd0_disp_dmac_object_detach
;
return
0
;
}
static
int
nvd0_disp_mast_init
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_dmac
*
mast
=
(
void
*
)
object
;
int
ret
;
ret
=
nv50_disp_chan_init
(
&
mast
->
base
);
if
(
ret
)
return
ret
;
/* enable error reporting */
nv_mask
(
priv
,
0x610090
,
0x00000001
,
0x00000001
);
nv_mask
(
priv
,
0x6100a0
,
0x00000001
,
0x00000001
);
/* initialise channel for dma command submission */
nv_wr32
(
priv
,
0x610494
,
mast
->
push
);
nv_wr32
(
priv
,
0x610498
,
0x00010000
);
nv_wr32
(
priv
,
0x61049c
,
0x00000001
);
nv_mask
(
priv
,
0x610490
,
0x00000010
,
0x00000010
);
nv_wr32
(
priv
,
0x640000
,
0x00000000
);
nv_wr32
(
priv
,
0x610490
,
0x01000013
);
/* wait for it to go inactive */
if
(
!
nv_wait
(
priv
,
0x610490
,
0x80000000
,
0x00000000
))
{
nv_error
(
mast
,
"init: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610490
));
return
-
EBUSY
;
}
return
0
;
}
static
int
nvd0_disp_mast_fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_dmac
*
mast
=
(
void
*
)
object
;
/* deactivate channel */
nv_mask
(
priv
,
0x610490
,
0x00000010
,
0x00000000
);
nv_mask
(
priv
,
0x610490
,
0x00000003
,
0x00000000
);
if
(
!
nv_wait
(
priv
,
0x610490
,
0x001e0000
,
0x00000000
))
{
nv_error
(
mast
,
"fini: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610490
));
if
(
suspend
)
return
-
EBUSY
;
}
/* disable error reporting */
nv_mask
(
priv
,
0x610090
,
0x00000001
,
0x00000000
);
nv_mask
(
priv
,
0x6100a0
,
0x00000001
,
0x00000000
);
return
nv50_disp_chan_fini
(
&
mast
->
base
,
suspend
);
}
struct
nouveau_ofuncs
nvd0_disp_mast_ofuncs
=
{
.
ctor
=
nvd0_disp_mast_ctor
,
.
dtor
=
nv50_disp_dmac_dtor
,
.
init
=
nvd0_disp_mast_init
,
.
fini
=
nvd0_disp_mast_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
.
wr32
=
nv50_disp_chan_wr32
,
};
/*******************************************************************************
* EVO sync channel objects
******************************************************************************/
static
int
nvd0_disp_sync_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_display_sync_class
*
args
=
data
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
engine
;
struct
nv50_disp_dmac
*
dmac
;
int
ret
;
if
(
size
<
sizeof
(
*
data
)
||
args
->
head
>=
priv
->
head
.
nr
)
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
=
nvd0_disp_dmac_object_attach
;
nv_parent
(
dmac
)
->
object_detach
=
nvd0_disp_dmac_object_detach
;
return
0
;
}
struct
nouveau_ofuncs
nvd0_disp_sync_ofuncs
=
{
.
ctor
=
nvd0_disp_sync_ctor
,
.
dtor
=
nv50_disp_dmac_dtor
,
.
init
=
nvd0_disp_dmac_init
,
.
fini
=
nvd0_disp_dmac_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
.
wr32
=
nv50_disp_chan_wr32
,
};
/*******************************************************************************
* EVO overlay channel objects
******************************************************************************/
static
int
nvd0_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_display_ovly_class
*
args
=
data
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
engine
;
struct
nv50_disp_dmac
*
dmac
;
int
ret
;
if
(
size
<
sizeof
(
*
data
)
||
args
->
head
>=
priv
->
head
.
nr
)
return
-
EINVAL
;
ret
=
nv50_disp_dmac_create_
(
parent
,
engine
,
oclass
,
args
->
pushbuf
,
5
+
args
->
head
,
sizeof
(
*
dmac
),
(
void
**
)
&
dmac
);
*
pobject
=
nv_object
(
dmac
);
if
(
ret
)
return
ret
;
nv_parent
(
dmac
)
->
object_attach
=
nvd0_disp_dmac_object_attach
;
nv_parent
(
dmac
)
->
object_detach
=
nvd0_disp_dmac_object_detach
;
return
0
;
}
struct
nouveau_ofuncs
nvd0_disp_ovly_ofuncs
=
{
.
ctor
=
nvd0_disp_ovly_ctor
,
.
dtor
=
nv50_disp_dmac_dtor
,
.
init
=
nvd0_disp_dmac_init
,
.
fini
=
nvd0_disp_dmac_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
.
wr32
=
nv50_disp_chan_wr32
,
};
/*******************************************************************************
* EVO PIO channel base class
******************************************************************************/
static
int
nvd0_disp_pioc_create_
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
int
chid
,
int
length
,
void
**
pobject
)
{
return
nv50_disp_chan_create_
(
parent
,
engine
,
oclass
,
chid
,
length
,
pobject
);
}
static
void
nvd0_disp_pioc_dtor
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_pioc
*
pioc
=
(
void
*
)
object
;
nv50_disp_chan_destroy
(
&
pioc
->
base
);
}
static
int
nvd0_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
=
nv50_disp_chan_init
(
&
pioc
->
base
);
if
(
ret
)
return
ret
;
/* enable error reporting */
nv_mask
(
priv
,
0x610090
,
0x00000001
<<
chid
,
0x00000001
<<
chid
);
nv_mask
(
priv
,
0x6100a0
,
0x00000001
<<
chid
,
0x00000001
<<
chid
);
/* activate channel */
nv_wr32
(
priv
,
0x610490
+
(
chid
*
0x10
),
0x00000001
);
if
(
!
nv_wait
(
priv
,
0x610490
+
(
chid
*
0x10
),
0x00030000
,
0x00010000
))
{
nv_error
(
pioc
,
"init: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610490
+
(
chid
*
0x10
)));
return
-
EBUSY
;
}
return
0
;
}
static
int
nvd0_disp_pioc_fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_pioc
*
pioc
=
(
void
*
)
object
;
int
chid
=
pioc
->
base
.
chid
;
nv_mask
(
priv
,
0x610490
+
(
chid
*
0x10
),
0x00000001
,
0x00000000
);
if
(
!
nv_wait
(
priv
,
0x610490
+
(
chid
*
0x10
),
0x00030000
,
0x00000000
))
{
nv_error
(
pioc
,
"timeout: 0x%08x
\n
"
,
nv_rd32
(
priv
,
0x610490
+
(
chid
*
0x10
)));
if
(
suspend
)
return
-
EBUSY
;
}
/* disable error reporting */
nv_mask
(
priv
,
0x610090
,
0x00000001
<<
chid
,
0x00000000
);
nv_mask
(
priv
,
0x6100a0
,
0x00000001
<<
chid
,
0x00000000
);
return
nv50_disp_chan_fini
(
&
pioc
->
base
,
suspend
);
}
/*******************************************************************************
* EVO immediate overlay channel objects
******************************************************************************/
static
int
nvd0_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_display_oimm_class
*
args
=
data
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
engine
;
struct
nv50_disp_pioc
*
pioc
;
int
ret
;
if
(
size
<
sizeof
(
*
args
)
||
args
->
head
>=
priv
->
head
.
nr
)
return
-
EINVAL
;
ret
=
nvd0_disp_pioc_create_
(
parent
,
engine
,
oclass
,
9
+
args
->
head
,
sizeof
(
*
pioc
),
(
void
**
)
&
pioc
);
*
pobject
=
nv_object
(
pioc
);
if
(
ret
)
return
ret
;
return
0
;
}
struct
nouveau_ofuncs
nvd0_disp_oimm_ofuncs
=
{
.
ctor
=
nvd0_disp_oimm_ctor
,
.
dtor
=
nvd0_disp_pioc_dtor
,
.
init
=
nvd0_disp_pioc_init
,
.
fini
=
nvd0_disp_pioc_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
.
wr32
=
nv50_disp_chan_wr32
,
};
/*******************************************************************************
* EVO cursor channel objects
******************************************************************************/
static
int
nvd0_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_display_curs_class
*
args
=
data
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
engine
;
struct
nv50_disp_pioc
*
pioc
;
int
ret
;
if
(
size
<
sizeof
(
*
args
)
||
args
->
head
>=
priv
->
head
.
nr
)
return
-
EINVAL
;
ret
=
nvd0_disp_pioc_create_
(
parent
,
engine
,
oclass
,
13
+
args
->
head
,
sizeof
(
*
pioc
),
(
void
**
)
&
pioc
);
*
pobject
=
nv_object
(
pioc
);
if
(
ret
)
return
ret
;
return
0
;
}
struct
nouveau_ofuncs
nvd0_disp_curs_ofuncs
=
{
.
ctor
=
nvd0_disp_curs_ctor
,
.
dtor
=
nvd0_disp_pioc_dtor
,
.
init
=
nvd0_disp_pioc_init
,
.
fini
=
nvd0_disp_pioc_fini
,
.
rd32
=
nv50_disp_chan_rd32
,
.
wr32
=
nv50_disp_chan_wr32
,
};
/*******************************************************************************
* Base display object
******************************************************************************/
static
int
nvd0_disp_base_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
engine
;
struct
nv50_disp_base
*
base
;
int
ret
;
ret
=
nouveau_parent_create
(
parent
,
engine
,
oclass
,
0
,
priv
->
sclass
,
0
,
&
base
);
*
pobject
=
nv_object
(
base
);
if
(
ret
)
return
ret
;
return
nouveau_ramht_new
(
parent
,
parent
,
0x1000
,
0
,
&
base
->
ramht
);
}
static
void
nvd0_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
);
}
static
int
nvd0_disp_base_init
(
struct
nouveau_object
*
object
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_base
*
base
=
(
void
*
)
object
;
int
ret
,
i
;
u32
tmp
;
ret
=
nouveau_parent_init
(
&
base
->
base
);
if
(
ret
)
return
ret
;
/* The below segments of code copying values from one register to
* another appear to inform EVO of the display capabilities or
* something similar.
*/
/* ... CRTC caps */
for
(
i
=
0
;
i
<
priv
->
head
.
nr
;
i
++
)
{
tmp
=
nv_rd32
(
priv
,
0x616104
+
(
i
*
0x800
));
nv_wr32
(
priv
,
0x6101b4
+
(
i
*
0x800
),
tmp
);
tmp
=
nv_rd32
(
priv
,
0x616108
+
(
i
*
0x800
));
nv_wr32
(
priv
,
0x6101b8
+
(
i
*
0x800
),
tmp
);
tmp
=
nv_rd32
(
priv
,
0x61610c
+
(
i
*
0x800
));
nv_wr32
(
priv
,
0x6101bc
+
(
i
*
0x800
),
tmp
);
}
/* ... DAC caps */
for
(
i
=
0
;
i
<
priv
->
dac
.
nr
;
i
++
)
{
tmp
=
nv_rd32
(
priv
,
0x61a000
+
(
i
*
0x800
));
nv_wr32
(
priv
,
0x6101c0
+
(
i
*
0x800
),
tmp
);
}
/* ... SOR caps */
for
(
i
=
0
;
i
<
priv
->
sor
.
nr
;
i
++
)
{
tmp
=
nv_rd32
(
priv
,
0x61c000
+
(
i
*
0x800
));
nv_wr32
(
priv
,
0x6301c4
+
(
i
*
0x800
),
tmp
);
}
/* steal display away from vbios, or something like that */
if
(
nv_rd32
(
priv
,
0x6100ac
)
&
0x00000100
)
{
nv_wr32
(
priv
,
0x6100ac
,
0x00000100
);
nv_mask
(
priv
,
0x6194e8
,
0x00000001
,
0x00000000
);
if
(
!
nv_wait
(
priv
,
0x6194e8
,
0x00000002
,
0x00000000
))
{
nv_error
(
priv
,
"timeout acquiring display
\n
"
);
return
-
EBUSY
;
}
}
/* point at display engine memory area (hash table, objects) */
nv_wr32
(
priv
,
0x610010
,
(
nv_gpuobj
(
object
->
parent
)
->
addr
>>
8
)
|
9
);
/* enable supervisor interrupts, disable everything else */
nv_wr32
(
priv
,
0x610090
,
0x00000000
);
nv_wr32
(
priv
,
0x6100a0
,
0x00000000
);
nv_wr32
(
priv
,
0x6100b0
,
0x00000307
);
return
0
;
}
static
int
nvd0_disp_base_fini
(
struct
nouveau_object
*
object
,
bool
suspend
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nv50_disp_base
*
base
=
(
void
*
)
object
;
/* disable all interrupts */
nv_wr32
(
priv
,
0x6100b0
,
0x00000000
);
return
nouveau_parent_fini
(
&
base
->
base
,
suspend
);
}
struct
nouveau_ofuncs
nvd0_disp_base_ofuncs
=
{
.
ctor
=
nvd0_disp_base_ctor
,
.
dtor
=
nvd0_disp_base_dtor
,
.
init
=
nvd0_disp_base_init
,
.
fini
=
nvd0_disp_base_fini
,
};
static
struct
nouveau_oclass
nvd0_disp_base_oclass
[]
=
{
{
NVD0_DISP_CLASS
,
&
nvd0_disp_base_ofuncs
},
{}
};
static
struct
nouveau_oclass
nvd0_disp_sclass
[]
=
{
{},
{
NVD0_DISP_MAST_CLASS
,
&
nvd0_disp_mast_ofuncs
},
{
NVD0_DISP_SYNC_CLASS
,
&
nvd0_disp_sync_ofuncs
},
{
NVD0_DISP_OVLY_CLASS
,
&
nvd0_disp_ovly_ofuncs
},
{
NVD0_DISP_OIMM_CLASS
,
&
nvd0_disp_oimm_ofuncs
},
{
NVD0_DISP_CURS_CLASS
,
&
nvd0_disp_curs_ofuncs
},
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static
void
nvd0_disp_intr_vblank
(
struct
nv
d
0_disp_priv
*
priv
,
int
crtc
)
nvd0_disp_intr_vblank
(
struct
nv
5
0_disp_priv
*
priv
,
int
crtc
)
{
struct
nouveau_bar
*
bar
=
nouveau_bar
(
priv
);
struct
nouveau_disp
*
disp
=
&
priv
->
base
;
...
...
@@ -65,10 +592,10 @@ nvd0_disp_intr_vblank(struct nvd0_disp_priv *priv, int crtc)
disp
->
vblank
.
notify
(
disp
->
vblank
.
data
,
crtc
);
}
static
void
void
nvd0_disp_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
nv
d
0_disp_priv
*
priv
=
(
void
*
)
subdev
;
struct
nv
5
0_disp_priv
*
priv
=
(
void
*
)
subdev
;
u32
intr
=
nv_rd32
(
priv
,
0x610088
);
int
i
;
...
...
@@ -86,10 +613,10 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
static
int
nvd0_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
nv
d
0_disp_priv
*
priv
;
struct
nv
5
0_disp_priv
*
priv
;
int
ret
;
ret
=
nouveau_disp_create
(
parent
,
engine
,
oclass
,
"PDISP"
,
...
...
@@ -98,8 +625,13 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if
(
ret
)
return
ret
;
nv_engine
(
priv
)
->
sclass
=
nvd0_disp_sclass
;
nv_engine
(
priv
)
->
sclass
=
nvd0_disp_base_oclass
;
nv_engine
(
priv
)
->
cclass
=
&
nv50_disp_cclass
;
nv_subdev
(
priv
)
->
intr
=
nvd0_disp_intr
;
priv
->
sclass
=
nvd0_disp_sclass
;
priv
->
head
.
nr
=
nv_rd32
(
priv
,
0x022448
);
priv
->
dac
.
nr
=
3
;
priv
->
sor
.
nr
=
4
;
INIT_LIST_HEAD
(
&
priv
->
base
.
vblank
.
list
);
spin_lock_init
(
&
priv
->
base
.
vblank
.
lock
);
...
...
@@ -108,7 +640,7 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct
nouveau_oclass
nvd0_disp_oclass
=
{
.
handle
=
NV_ENGINE
(
DISP
,
0x
d
0
),
.
handle
=
NV_ENGINE
(
DISP
,
0x
9
0
),
.
ofuncs
=
&
(
struct
nouveau_ofuncs
)
{
.
ctor
=
nvd0_disp_ctor
,
.
dtor
=
_nouveau_disp_dtor
,
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
0 → 100644
浏览文件 @
46654061
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
static
struct
nouveau_oclass
nve0_disp_sclass
[]
=
{
{
NVE0_DISP_MAST_CLASS
,
&
nvd0_disp_mast_ofuncs
},
{
NVE0_DISP_SYNC_CLASS
,
&
nvd0_disp_sync_ofuncs
},
{
NVE0_DISP_OVLY_CLASS
,
&
nvd0_disp_ovly_ofuncs
},
{
NVE0_DISP_OIMM_CLASS
,
&
nvd0_disp_oimm_ofuncs
},
{
NVE0_DISP_CURS_CLASS
,
&
nvd0_disp_curs_ofuncs
},
{}
};
static
struct
nouveau_oclass
nve0_disp_base_oclass
[]
=
{
{
NVE0_DISP_CLASS
,
&
nvd0_disp_base_ofuncs
},
{}
};
static
int
nve0_disp_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nv50_disp_priv
*
priv
;
int
ret
;
ret
=
nouveau_disp_create
(
parent
,
engine
,
oclass
,
"PDISP"
,
"display"
,
&
priv
);
*
pobject
=
nv_object
(
priv
);
if
(
ret
)
return
ret
;
nv_engine
(
priv
)
->
sclass
=
nve0_disp_base_oclass
;
nv_engine
(
priv
)
->
cclass
=
&
nv50_disp_cclass
;
nv_subdev
(
priv
)
->
intr
=
nvd0_disp_intr
;
priv
->
sclass
=
nve0_disp_sclass
;
priv
->
head
.
nr
=
nv_rd32
(
priv
,
0x022448
);
priv
->
dac
.
nr
=
3
;
priv
->
sor
.
nr
=
4
;
INIT_LIST_HEAD
(
&
priv
->
base
.
vblank
.
list
);
spin_lock_init
(
&
priv
->
base
.
vblank
.
lock
);
return
0
;
}
struct
nouveau_oclass
nve0_disp_oclass
=
{
.
handle
=
NV_ENGINE
(
DISP
,
0x91
),
.
ofuncs
=
&
(
struct
nouveau_ofuncs
)
{
.
ctor
=
nve0_disp_ctor
,
.
dtor
=
_nouveau_disp_dtor
,
.
init
=
_nouveau_disp_init
,
.
fini
=
_nouveau_disp_fini
,
},
};
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
浏览文件 @
46654061
...
...
@@ -44,6 +44,12 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
if
(
!
nv_iclass
(
parent
,
NV_ENGCTX_CLASS
))
{
switch
(
nv_mclass
(
parent
->
parent
))
{
case
NVD0_DISP_MAST_CLASS
:
case
NVD0_DISP_SYNC_CLASS
:
case
NVD0_DISP_OVLY_CLASS
:
case
NVE0_DISP_MAST_CLASS
:
case
NVE0_DISP_SYNC_CLASS
:
case
NVE0_DISP_OVLY_CLASS
:
break
;
default:
return
-
EINVAL
;
...
...
drivers/gpu/drm/nouveau/core/include/core/class.h
浏览文件 @
46654061
...
...
@@ -158,6 +158,8 @@ struct nve0_channel_ind_class {
* 8370: NVA0_DISP
* 8870: NV94_DISP
* 8570: NVA3_DISP
* 9070: NVD0_DISP
* 9170: NVE0_DISP
*/
#define NV50_DISP_CLASS 0x00005070
...
...
@@ -165,6 +167,8 @@ struct nve0_channel_ind_class {
#define NVA0_DISP_CLASS 0x00008370
#define NV94_DISP_CLASS 0x00008870
#define NVA3_DISP_CLASS 0x00008570
#define NVD0_DISP_CLASS 0x00009070
#define NVE0_DISP_CLASS 0x00009170
struct
nv50_display_class
{
};
...
...
@@ -174,6 +178,8 @@ struct nv50_display_class {
* 837a: NVA0_DISP_CURS
* 887a: NV94_DISP_CURS
* 857a: NVA3_DISP_CURS
* 907a: NVD0_DISP_CURS
* 917a: NVE0_DISP_CURS
*/
#define NV50_DISP_CURS_CLASS 0x0000507a
...
...
@@ -181,6 +187,8 @@ struct nv50_display_class {
#define NVA0_DISP_CURS_CLASS 0x0000837a
#define NV94_DISP_CURS_CLASS 0x0000887a
#define NVA3_DISP_CURS_CLASS 0x0000857a
#define NVD0_DISP_CURS_CLASS 0x0000907a
#define NVE0_DISP_CURS_CLASS 0x0000917a
struct
nv50_display_curs_class
{
u32
head
;
...
...
@@ -191,6 +199,8 @@ struct nv50_display_curs_class {
* 837b: NVA0_DISP_OIMM
* 887b: NV94_DISP_OIMM
* 857b: NVA3_DISP_OIMM
* 907b: NVD0_DISP_OIMM
* 917b: NVE0_DISP_OIMM
*/
#define NV50_DISP_OIMM_CLASS 0x0000507b
...
...
@@ -198,6 +208,8 @@ struct nv50_display_curs_class {
#define NVA0_DISP_OIMM_CLASS 0x0000837b
#define NV94_DISP_OIMM_CLASS 0x0000887b
#define NVA3_DISP_OIMM_CLASS 0x0000857b
#define NVD0_DISP_OIMM_CLASS 0x0000907b
#define NVE0_DISP_OIMM_CLASS 0x0000917b
struct
nv50_display_oimm_class
{
u32
head
;
...
...
@@ -208,6 +220,8 @@ struct nv50_display_oimm_class {
* 837c: NVA0_DISP_SYNC
* 887c: NV94_DISP_SYNC
* 857c: NVA3_DISP_SYNC
* 907c: NVD0_DISP_SYNC
* 917c: NVE0_DISP_SYNC
*/
#define NV50_DISP_SYNC_CLASS 0x0000507c
...
...
@@ -215,6 +229,8 @@ struct nv50_display_oimm_class {
#define NVA0_DISP_SYNC_CLASS 0x0000837c
#define NV94_DISP_SYNC_CLASS 0x0000887c
#define NVA3_DISP_SYNC_CLASS 0x0000857c
#define NVD0_DISP_SYNC_CLASS 0x0000907c
#define NVE0_DISP_SYNC_CLASS 0x0000917c
struct
nv50_display_sync_class
{
u32
pushbuf
;
...
...
@@ -226,6 +242,8 @@ struct nv50_display_sync_class {
* 837d: NVA0_DISP_MAST
* 887d: NV94_DISP_MAST
* 857d: NVA3_DISP_MAST
* 907d: NVD0_DISP_MAST
* 917d: NVE0_DISP_MAST
*/
#define NV50_DISP_MAST_CLASS 0x0000507d
...
...
@@ -233,6 +251,8 @@ struct nv50_display_sync_class {
#define NVA0_DISP_MAST_CLASS 0x0000837d
#define NV94_DISP_MAST_CLASS 0x0000887d
#define NVA3_DISP_MAST_CLASS 0x0000857d
#define NVD0_DISP_MAST_CLASS 0x0000907d
#define NVE0_DISP_MAST_CLASS 0x0000917d
struct
nv50_display_mast_class
{
u32
pushbuf
;
...
...
@@ -243,6 +263,8 @@ struct nv50_display_mast_class {
* 837e: NVA0_DISP_OVLY
* 887e: NV94_DISP_OVLY
* 857e: NVA3_DISP_OVLY
* 907e: NVD0_DISP_OVLY
* 917e: NVE0_DISP_OVLY
*/
#define NV50_DISP_OVLY_CLASS 0x0000507e
...
...
@@ -250,6 +272,8 @@ struct nv50_display_mast_class {
#define NVA0_DISP_OVLY_CLASS 0x0000837e
#define NV94_DISP_OVLY_CLASS 0x0000887e
#define NVA3_DISP_OVLY_CLASS 0x0000857e
#define NVD0_DISP_OVLY_CLASS 0x0000907e
#define NVE0_DISP_OVLY_CLASS 0x0000917e
struct
nv50_display_ovly_class
{
u32
pushbuf
;
...
...
drivers/gpu/drm/nouveau/core/include/engine/disp.h
浏览文件 @
46654061
...
...
@@ -44,5 +44,6 @@ extern struct nouveau_oclass nva0_disp_oclass;
extern
struct
nouveau_oclass
nv94_disp_oclass
;
extern
struct
nouveau_oclass
nva3_disp_oclass
;
extern
struct
nouveau_oclass
nvd0_disp_oclass
;
extern
struct
nouveau_oclass
nve0_disp_oclass
;
#endif
drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
浏览文件 @
46654061
...
...
@@ -71,7 +71,7 @@ nve0_identify(struct nouveau_device *device)
device
->
oclass
[
NVDEV_ENGINE_FIFO
]
=
&
nve0_fifo_oclass
;
device
->
oclass
[
NVDEV_ENGINE_SW
]
=
&
nvc0_software_oclass
;
device
->
oclass
[
NVDEV_ENGINE_GR
]
=
&
nve0_graph_oclass
;
device
->
oclass
[
NVDEV_ENGINE_DISP
]
=
&
nv
d
0_disp_oclass
;
device
->
oclass
[
NVDEV_ENGINE_DISP
]
=
&
nv
e
0_disp_oclass
;
device
->
oclass
[
NVDEV_ENGINE_COPY0
]
=
&
nve0_copy0_oclass
;
device
->
oclass
[
NVDEV_ENGINE_COPY1
]
=
&
nve0_copy1_oclass
;
break
;
...
...
@@ -96,7 +96,7 @@ nve0_identify(struct nouveau_device *device)
device
->
oclass
[
NVDEV_ENGINE_FIFO
]
=
&
nve0_fifo_oclass
;
device
->
oclass
[
NVDEV_ENGINE_SW
]
=
&
nvc0_software_oclass
;
device
->
oclass
[
NVDEV_ENGINE_GR
]
=
&
nve0_graph_oclass
;
device
->
oclass
[
NVDEV_ENGINE_DISP
]
=
&
nv
d
0_disp_oclass
;
device
->
oclass
[
NVDEV_ENGINE_DISP
]
=
&
nv
e
0_disp_oclass
;
device
->
oclass
[
NVDEV_ENGINE_COPY0
]
=
&
nve0_copy0_oclass
;
device
->
oclass
[
NVDEV_ENGINE_COPY1
]
=
&
nve0_copy1_oclass
;
break
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录