Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
6b07c6cf
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看板
提交
6b07c6cf
编写于
9月 03, 2014
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/gk104/fb/ram: make use of training data provided by vbios
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
43b6b202
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
138 addition
and
43 deletion
+138
-43
drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
+138
-43
未找到文件。
drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
浏览文件 @
6b07c6cf
...
...
@@ -29,6 +29,8 @@
#include <subdev/bios/init.h>
#include <subdev/bios/rammap.h>
#include <subdev/bios/timing.h>
#include <subdev/bios/M0205.h>
#include <subdev/bios/M0209.h>
#include <subdev/clock.h>
#include <subdev/clock/pll.h>
...
...
@@ -1130,24 +1132,147 @@ nve0_ram_tidy(struct nouveau_fb *pfb)
ram_exec
(
fuc
,
false
);
}
struct
nve0_ram_train
{
u16
mask
;
struct
nvbios_M0209S
remap
;
struct
nvbios_M0209S
type00
;
struct
nvbios_M0209S
type01
;
struct
nvbios_M0209S
type04
;
struct
nvbios_M0209S
type06
;
struct
nvbios_M0209S
type07
;
struct
nvbios_M0209S
type08
;
struct
nvbios_M0209S
type09
;
};
static
int
nve0_ram_train_type
(
struct
nouveau_fb
*
pfb
,
int
i
,
u8
ramcfg
,
struct
nve0_ram_train
*
train
)
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
pfb
);
struct
nvbios_M0205E
M0205E
;
struct
nvbios_M0205S
M0205S
;
struct
nvbios_M0209E
M0209E
;
struct
nvbios_M0209S
*
remap
=
&
train
->
remap
;
struct
nvbios_M0209S
*
value
;
u8
ver
,
hdr
,
cnt
,
len
;
u32
data
;
/* determine type of data for this index */
if
(
!
(
data
=
nvbios_M0205Ep
(
bios
,
i
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
M0205E
)))
return
-
ENOENT
;
switch
(
M0205E
.
type
)
{
case
0x00
:
value
=
&
train
->
type00
;
break
;
case
0x01
:
value
=
&
train
->
type01
;
break
;
case
0x04
:
value
=
&
train
->
type04
;
break
;
case
0x06
:
value
=
&
train
->
type06
;
break
;
case
0x07
:
value
=
&
train
->
type07
;
break
;
case
0x08
:
value
=
&
train
->
type08
;
break
;
case
0x09
:
value
=
&
train
->
type09
;
break
;
default:
return
0
;
}
/* training data index determined by ramcfg strap */
if
(
!
(
data
=
nvbios_M0205Sp
(
bios
,
i
,
ramcfg
,
&
ver
,
&
hdr
,
&
M0205S
)))
return
-
EINVAL
;
i
=
M0205S
.
data
;
/* training data format information */
if
(
!
(
data
=
nvbios_M0209Ep
(
bios
,
i
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
M0209E
)))
return
-
EINVAL
;
/* ... and the raw data */
if
(
!
(
data
=
nvbios_M0209Sp
(
bios
,
i
,
0
,
&
ver
,
&
hdr
,
value
)))
return
-
EINVAL
;
if
(
M0209E
.
v02_07
==
2
)
{
/* of course! why wouldn't we have a pointer to another entry
* in the same table, and use the first one as an array of
* remap indices...
*/
if
(
!
(
data
=
nvbios_M0209Sp
(
bios
,
M0209E
.
v03
,
0
,
&
ver
,
&
hdr
,
remap
)))
return
-
EINVAL
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
value
->
data
);
i
++
)
value
->
data
[
i
]
=
remap
->
data
[
value
->
data
[
i
]];
}
else
if
(
M0209E
.
v02_07
!=
1
)
return
-
EINVAL
;
train
->
mask
|=
1
<<
M0205E
.
type
;
return
0
;
}
static
int
nve0_ram_train_init_0
(
struct
nouveau_fb
*
pfb
,
struct
nve0_ram_train
*
train
)
{
int
i
,
j
;
if
((
train
->
mask
&
0x03d3
)
!=
0x03d3
)
{
nv_warn
(
pfb
,
"missing link training data
\n
"
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
0x30
;
i
++
)
{
for
(
j
=
0
;
j
<
8
;
j
+=
4
)
{
nv_wr32
(
pfb
,
0x10f968
+
j
,
0x00000000
|
(
i
<<
8
));
nv_wr32
(
pfb
,
0x10f920
+
j
,
0x00000000
|
train
->
type08
.
data
[
i
]
<<
4
|
train
->
type06
.
data
[
i
]);
nv_wr32
(
pfb
,
0x10f918
+
j
,
train
->
type00
.
data
[
i
]);
nv_wr32
(
pfb
,
0x10f920
+
j
,
0x00000100
|
train
->
type09
.
data
[
i
]
<<
4
|
train
->
type07
.
data
[
i
]);
nv_wr32
(
pfb
,
0x10f918
+
j
,
train
->
type01
.
data
[
i
]);
}
}
for
(
j
=
0
;
j
<
8
;
j
+=
4
)
{
for
(
i
=
0
;
i
<
0x100
;
i
++
)
{
nv_wr32
(
pfb
,
0x10f968
+
j
,
i
);
nv_wr32
(
pfb
,
0x10f900
+
j
,
train
->
type04
.
data
[
i
]);
}
}
return
0
;
}
static
int
nve0_ram_train_init
(
struct
nouveau_fb
*
pfb
)
{
u8
ramcfg
=
nvbios_ramcfg_index
(
nv_subdev
(
pfb
));
struct
nve0_ram_train
*
train
;
int
ret
=
-
ENOMEM
,
i
;
if
((
train
=
kzalloc
(
sizeof
(
*
train
),
GFP_KERNEL
)))
{
for
(
i
=
0
;
i
<
0x100
;
i
++
)
{
ret
=
nve0_ram_train_type
(
pfb
,
i
,
ramcfg
,
train
);
if
(
ret
&&
ret
!=
-
ENOENT
)
break
;
}
}
switch
(
pfb
->
ram
->
type
)
{
case
NV_MEM_TYPE_GDDR5
:
ret
=
nve0_ram_train_init_0
(
pfb
,
train
);
break
;
default:
ret
=
0
;
break
;
}
kfree
(
train
);
return
ret
;
}
int
nve0_ram_init
(
struct
nouveau_object
*
object
)
{
struct
nouveau_fb
*
pfb
=
(
void
*
)
object
->
parent
;
struct
nve0_ram
*
ram
=
(
void
*
)
object
;
struct
nouveau_bios
*
bios
=
nouveau_bios
(
pfb
);
static
const
u8
train0
[]
=
{
0x00
,
0xff
,
0xff
,
0x00
,
0xff
,
0x00
,
0x00
,
0xff
,
0xff
,
0x00
,
0xff
,
0x00
,
};
static
const
u32
train1
[]
=
{
0x00000000
,
0xffffffff
,
0x55555555
,
0xaaaaaaaa
,
0x33333333
,
0xcccccccc
,
0xf0f0f0f0
,
0x0f0f0f0f
,
0x00ff00ff
,
0xff00ff00
,
0x0000ffff
,
0xffff0000
,
};
u8
ver
,
hdr
,
cnt
,
len
,
snr
,
ssz
;
u32
data
,
save
;
int
ret
,
i
;
...
...
@@ -1190,37 +1315,7 @@ nve0_ram_init(struct nouveau_object *object)
nv_wr32
(
pfb
,
0x10ecc0
,
0xffffffff
);
nv_mask
(
pfb
,
0x10f160
,
0x00000010
,
0x00000010
);
switch
(
ram
->
base
.
type
)
{
case
NV_MEM_TYPE_GDDR5
:
for
(
i
=
0
;
i
<
0x30
;
i
++
)
{
nv_wr32
(
pfb
,
0x10f968
,
0x00000000
|
(
i
<<
8
));
nv_wr32
(
pfb
,
0x10f920
,
0x00000000
|
train0
[
i
%
12
]);
nv_wr32
(
pfb
,
0x10f918
,
train1
[
i
%
12
]);
nv_wr32
(
pfb
,
0x10f920
,
0x00000100
|
train0
[
i
%
12
]);
nv_wr32
(
pfb
,
0x10f918
,
train1
[
i
%
12
]);
nv_wr32
(
pfb
,
0x10f96c
,
0x00000000
|
(
i
<<
8
));
nv_wr32
(
pfb
,
0x10f924
,
0x00000000
|
train0
[
i
%
12
]);
nv_wr32
(
pfb
,
0x10f91c
,
train1
[
i
%
12
]);
nv_wr32
(
pfb
,
0x10f924
,
0x00000100
|
train0
[
i
%
12
]);
nv_wr32
(
pfb
,
0x10f91c
,
train1
[
i
%
12
]);
}
for
(
i
=
0
;
i
<
0x100
;
i
++
)
{
nv_wr32
(
pfb
,
0x10f968
,
i
);
nv_wr32
(
pfb
,
0x10f900
,
train1
[
2
+
(
i
&
1
)]);
}
for
(
i
=
0
;
i
<
0x100
;
i
++
)
{
nv_wr32
(
pfb
,
0x10f96c
,
i
);
nv_wr32
(
pfb
,
0x10f904
,
train1
[
2
+
(
i
&
1
)]);
}
break
;
default:
break
;
}
return
0
;
return
nve0_ram_train_init
(
pfb
);
}
static
int
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录