Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
2bd651ea
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
2bd651ea
编写于
5月 21, 2014
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/gf119/disp: start removing direct vbios parsing from supervisor
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
415f12ef
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
83 addition
and
75 deletion
+83
-75
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+83
-75
未找到文件。
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
浏览文件 @
2bd651ea
...
@@ -915,19 +915,20 @@ nvd0_disp_sclass[] = {
...
@@ -915,19 +915,20 @@ nvd0_disp_sclass[] = {
* Display engine implementation
* Display engine implementation
******************************************************************************/
******************************************************************************/
static
u16
static
struct
nvkm_output
*
exec_lookup
(
struct
nv50_disp_priv
*
priv
,
int
head
,
int
o
utp
,
u32
ctrl
,
exec_lookup
(
struct
nv50_disp_priv
*
priv
,
int
head
,
int
o
r
,
u32
ctrl
,
struct
dcb_output
*
dcb
,
u8
*
ver
,
u8
*
hdr
,
u8
*
cnt
,
u8
*
len
,
u32
*
data
,
u8
*
ver
,
u8
*
hdr
,
u8
*
cnt
,
u8
*
len
,
struct
nvbios_outp
*
info
)
struct
nvbios_outp
*
info
)
{
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
u16
mask
,
type
,
data
;
struct
nvkm_output
*
outp
;
u16
mask
,
type
;
if
(
o
utp
<
4
)
{
if
(
o
r
<
4
)
{
type
=
DCB_OUTPUT_ANALOG
;
type
=
DCB_OUTPUT_ANALOG
;
mask
=
0
;
mask
=
0
;
}
else
{
}
else
{
o
utp
-=
4
;
o
r
-=
4
;
switch
(
ctrl
&
0x00000f00
)
{
switch
(
ctrl
&
0x00000f00
)
{
case
0x00000000
:
type
=
DCB_OUTPUT_LVDS
;
mask
=
1
;
break
;
case
0x00000000
:
type
=
DCB_OUTPUT_LVDS
;
mask
=
1
;
break
;
case
0x00000100
:
type
=
DCB_OUTPUT_TMDS
;
mask
=
1
;
break
;
case
0x00000100
:
type
=
DCB_OUTPUT_TMDS
;
mask
=
1
;
break
;
...
@@ -939,47 +940,53 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl,
...
@@ -939,47 +940,53 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl,
nv_error
(
priv
,
"unknown SOR mc 0x%08x
\n
"
,
ctrl
);
nv_error
(
priv
,
"unknown SOR mc 0x%08x
\n
"
,
ctrl
);
return
0x0000
;
return
0x0000
;
}
}
dcb
->
sorconf
.
link
=
mask
;
}
}
mask
=
0x00c0
&
(
mask
<<
6
);
mask
=
0x00c0
&
(
mask
<<
6
);
mask
|=
0x0001
<<
o
utp
;
mask
|=
0x0001
<<
o
r
;
mask
|=
0x0100
<<
head
;
mask
|=
0x0100
<<
head
;
data
=
dcb_outp_match
(
bios
,
type
,
mask
,
ver
,
hdr
,
dcb
);
list_for_each_entry
(
outp
,
&
priv
->
base
.
outp
,
head
)
{
if
(
!
data
)
if
((
outp
->
info
.
hasht
&
0xff
)
==
type
&&
return
0x0000
;
(
outp
->
info
.
hashm
&
mask
)
==
mask
)
{
*
data
=
nvbios_outp_match
(
bios
,
outp
->
info
.
hasht
,
outp
->
info
.
hashm
,
ver
,
hdr
,
cnt
,
len
,
info
);
if
(
!*
data
)
return
NULL
;
return
outp
;
}
}
return
nvbios_outp_match
(
bios
,
type
,
mask
,
ver
,
hdr
,
cnt
,
len
,
info
)
;
return
NULL
;
}
}
static
bool
static
bool
exec_script
(
struct
nv50_disp_priv
*
priv
,
int
head
,
int
id
)
exec_script
(
struct
nv50_disp_priv
*
priv
,
int
head
,
int
id
)
{
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
struct
nvkm_output
*
outp
;
struct
nvbios_outp
info
;
struct
nvbios_outp
info
;
struct
dcb_output
dcb
;
u8
ver
,
hdr
,
cnt
,
len
;
u8
ver
,
hdr
,
cnt
,
len
;
u32
ctrl
=
0x00000000
;
u32
data
,
ctrl
=
0
;
u16
data
;
int
or
;
int
outp
;
for
(
o
utp
=
0
;
!
(
ctrl
&
(
1
<<
head
))
&&
outp
<
8
;
outp
++
)
{
for
(
o
r
=
0
;
!
(
ctrl
&
(
1
<<
head
))
&&
or
<
8
;
or
++
)
{
ctrl
=
nv_rd32
(
priv
,
0x640180
+
(
o
utp
*
0x20
));
ctrl
=
nv_rd32
(
priv
,
0x640180
+
(
o
r
*
0x20
));
if
(
ctrl
&
(
1
<<
head
))
if
(
ctrl
&
(
1
<<
head
))
break
;
break
;
}
}
if
(
o
utp
==
8
)
if
(
o
r
==
8
)
return
false
;
return
false
;
data
=
exec_lookup
(
priv
,
head
,
outp
,
ctrl
,
&
dcb
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info
);
outp
=
exec_lookup
(
priv
,
head
,
or
,
ctrl
,
&
data
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info
);
if
(
data
)
{
if
(
outp
)
{
struct
nvbios_init
init
=
{
struct
nvbios_init
init
=
{
.
subdev
=
nv_subdev
(
priv
),
.
subdev
=
nv_subdev
(
priv
),
.
bios
=
bios
,
.
bios
=
bios
,
.
offset
=
info
.
script
[
id
],
.
offset
=
info
.
script
[
id
],
.
outp
=
&
dcb
,
.
outp
=
&
outp
->
info
,
.
crtc
=
head
,
.
crtc
=
head
,
.
execute
=
1
,
.
execute
=
1
,
};
};
...
@@ -990,50 +997,49 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
...
@@ -990,50 +997,49 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
return
false
;
return
false
;
}
}
static
u32
static
struct
nvkm_output
*
exec_clkcmp
(
struct
nv50_disp_priv
*
priv
,
int
head
,
int
id
,
exec_clkcmp
(
struct
nv50_disp_priv
*
priv
,
int
head
,
int
id
,
u32
pclk
,
u32
*
conf
)
u32
pclk
,
struct
dcb_output
*
dcb
)
{
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
struct
nvkm_output
*
outp
;
struct
nvbios_outp
info1
;
struct
nvbios_outp
info1
;
struct
nvbios_ocfg
info2
;
struct
nvbios_ocfg
info2
;
u8
ver
,
hdr
,
cnt
,
len
;
u8
ver
,
hdr
,
cnt
,
len
;
u32
ctrl
=
0x00000000
;
u32
data
,
ctrl
=
0
;
u32
data
,
conf
=
~
0
;
int
or
;
int
outp
;
for
(
o
utp
=
0
;
!
(
ctrl
&
(
1
<<
head
))
&&
outp
<
8
;
outp
++
)
{
for
(
o
r
=
0
;
!
(
ctrl
&
(
1
<<
head
))
&&
or
<
8
;
or
++
)
{
ctrl
=
nv_rd32
(
priv
,
0x660180
+
(
o
utp
*
0x20
));
ctrl
=
nv_rd32
(
priv
,
0x660180
+
(
o
r
*
0x20
));
if
(
ctrl
&
(
1
<<
head
))
if
(
ctrl
&
(
1
<<
head
))
break
;
break
;
}
}
if
(
o
utp
==
8
)
if
(
o
r
==
8
)
return
conf
;
return
NULL
;
data
=
exec_lookup
(
priv
,
head
,
outp
,
ctrl
,
dcb
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info1
);
outp
=
exec_lookup
(
priv
,
head
,
or
,
ctrl
,
&
data
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info1
);
if
(
data
==
0x0000
)
if
(
!
outp
)
return
conf
;
return
NULL
;
switch
(
dcb
->
type
)
{
switch
(
outp
->
info
.
type
)
{
case
DCB_OUTPUT_TMDS
:
case
DCB_OUTPUT_TMDS
:
conf
=
(
ctrl
&
0x00000f00
)
>>
8
;
*
conf
=
(
ctrl
&
0x00000f00
)
>>
8
;
if
(
pclk
>=
165000
)
if
(
pclk
>=
165000
)
conf
|=
0x0100
;
*
conf
|=
0x0100
;
break
;
break
;
case
DCB_OUTPUT_LVDS
:
case
DCB_OUTPUT_LVDS
:
conf
=
priv
->
sor
.
lvdsconf
;
*
conf
=
priv
->
sor
.
lvdsconf
;
break
;
break
;
case
DCB_OUTPUT_DP
:
case
DCB_OUTPUT_DP
:
conf
=
(
ctrl
&
0x00000f00
)
>>
8
;
*
conf
=
(
ctrl
&
0x00000f00
)
>>
8
;
break
;
break
;
case
DCB_OUTPUT_ANALOG
:
case
DCB_OUTPUT_ANALOG
:
default:
default:
conf
=
0x00ff
;
*
conf
=
0x00ff
;
break
;
break
;
}
}
data
=
nvbios_ocfg_match
(
bios
,
data
,
conf
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info2
);
data
=
nvbios_ocfg_match
(
bios
,
data
,
*
conf
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info2
);
if
(
data
&&
id
<
0xff
)
{
if
(
data
&&
id
<
0xff
)
{
data
=
nvbios_oclk_match
(
bios
,
info2
.
clkcmp
[
id
],
pclk
);
data
=
nvbios_oclk_match
(
bios
,
info2
.
clkcmp
[
id
],
pclk
);
if
(
data
)
{
if
(
data
)
{
...
@@ -1041,7 +1047,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id,
...
@@ -1041,7 +1047,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id,
.
subdev
=
nv_subdev
(
priv
),
.
subdev
=
nv_subdev
(
priv
),
.
bios
=
bios
,
.
bios
=
bios
,
.
offset
=
data
,
.
offset
=
data
,
.
outp
=
dcb
,
.
outp
=
&
outp
->
info
,
.
crtc
=
head
,
.
crtc
=
head
,
.
execute
=
1
,
.
execute
=
1
,
};
};
...
@@ -1050,7 +1056,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id,
...
@@ -1050,7 +1056,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id,
}
}
}
}
return
conf
;
return
outp
;
}
}
static
void
static
void
...
@@ -1124,13 +1130,15 @@ nvd0_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head,
...
@@ -1124,13 +1130,15 @@ nvd0_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head,
static
void
static
void
nvd0_disp_intr_unk2_2
(
struct
nv50_disp_priv
*
priv
,
int
head
)
nvd0_disp_intr_unk2_2
(
struct
nv50_disp_priv
*
priv
,
int
head
)
{
{
struct
dcb_output
outp
;
struct
nvkm_output
*
outp
;
u32
pclk
=
nv_rd32
(
priv
,
0x660450
+
(
head
*
0x300
))
/
1000
;
u32
pclk
=
nv_rd32
(
priv
,
0x660450
+
(
head
*
0x300
))
/
1000
;
u32
conf
=
exec_clkcmp
(
priv
,
head
,
0xff
,
pclk
,
&
outp
);
u32
conf
,
addr
,
data
;
if
(
conf
!=
~
0
)
{
u32
addr
,
data
;
if
(
outp
.
type
==
DCB_OUTPUT_DP
)
{
outp
=
exec_clkcmp
(
priv
,
head
,
0xff
,
pclk
,
&
conf
);
if
(
!
outp
)
return
;
if
(
outp
->
info
.
type
==
DCB_OUTPUT_DP
)
{
u32
sync
=
nv_rd32
(
priv
,
0x660404
+
(
head
*
0x300
));
u32
sync
=
nv_rd32
(
priv
,
0x660404
+
(
head
*
0x300
));
switch
((
sync
&
0x000003c0
)
>>
6
)
{
switch
((
sync
&
0x000003c0
)
>>
6
)
{
case
6
:
pclk
=
pclk
*
30
/
8
;
break
;
case
6
:
pclk
=
pclk
*
30
/
8
;
break
;
...
@@ -1142,31 +1150,31 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
...
@@ -1142,31 +1150,31 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
}
}
nouveau_dp_train
(
&
priv
->
base
,
priv
->
sor
.
dp
,
nouveau_dp_train
(
&
priv
->
base
,
priv
->
sor
.
dp
,
&
outp
,
head
,
pclk
);
&
outp
->
info
,
head
,
pclk
);
}
}
exec_clkcmp
(
priv
,
head
,
0
,
pclk
,
&
outp
);
exec_clkcmp
(
priv
,
head
,
0
,
pclk
,
&
conf
);
if
(
outp
.
type
==
DCB_OUTPUT_ANALOG
)
{
if
(
outp
->
info
.
type
==
DCB_OUTPUT_ANALOG
)
{
addr
=
0x612280
+
(
ffs
(
outp
.
or
)
-
1
)
*
0x800
;
addr
=
0x612280
+
(
ffs
(
outp
->
info
.
or
)
-
1
)
*
0x800
;
data
=
0x00000000
;
data
=
0x00000000
;
}
else
{
}
else
{
if
(
outp
.
type
==
DCB_OUTPUT_DP
)
if
(
outp
->
info
.
type
==
DCB_OUTPUT_DP
)
nvd0_disp_intr_unk2_2_tu
(
priv
,
head
,
&
outp
);
nvd0_disp_intr_unk2_2_tu
(
priv
,
head
,
&
outp
->
info
);
addr
=
0x612300
+
(
ffs
(
outp
.
or
)
-
1
)
*
0x800
;
addr
=
0x612300
+
(
ffs
(
outp
->
info
.
or
)
-
1
)
*
0x800
;
data
=
(
conf
&
0x0100
)
?
0x00000101
:
0x00000000
;
data
=
(
conf
&
0x0100
)
?
0x00000101
:
0x00000000
;
}
}
nv_mask
(
priv
,
addr
,
0x00000707
,
data
);
nv_mask
(
priv
,
addr
,
0x00000707
,
data
);
}
}
}
static
void
static
void
nvd0_disp_intr_unk4_0
(
struct
nv50_disp_priv
*
priv
,
int
head
)
nvd0_disp_intr_unk4_0
(
struct
nv50_disp_priv
*
priv
,
int
head
)
{
{
struct
dcb_output
outp
;
u32
pclk
=
nv_rd32
(
priv
,
0x660450
+
(
head
*
0x300
))
/
1000
;
u32
pclk
=
nv_rd32
(
priv
,
0x660450
+
(
head
*
0x300
))
/
1000
;
exec_clkcmp
(
priv
,
head
,
1
,
pclk
,
&
outp
);
u32
conf
;
exec_clkcmp
(
priv
,
head
,
1
,
pclk
,
&
conf
);
}
}
void
void
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录