Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
6c5a0424
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看板
提交
6c5a0424
编写于
11月 07, 2012
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nvd0/disp: move link training helpers into core as display methods
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
fb445b3c
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
295 addition
and
84 deletion
+295
-84
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/Makefile
+2
-0
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
+24
-0
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
+11
-0
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+4
-1
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
+4
-1
drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
+93
-0
drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
+126
-0
drivers/gpu/drm/nouveau/core/include/core/class.h
drivers/gpu/drm/nouveau/core/include/core/class.h
+19
-0
drivers/gpu/drm/nouveau/nvd0_display.c
drivers/gpu/drm/nouveau/nvd0_display.c
+12
-82
未找到文件。
drivers/gpu/drm/nouveau/Makefile
浏览文件 @
6c5a0424
...
...
@@ -137,6 +137,8 @@ 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/sornv50.o
nouveau-y
+=
core/engine/disp/sornvd0.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
浏览文件 @
6c5a0424
...
...
@@ -8,6 +8,8 @@
#include <engine/dmaobj.h>
#include <engine/disp.h>
struct
dcb_output
;
struct
nv50_disp_priv
{
struct
nouveau_disp
base
;
struct
nouveau_oclass
*
sclass
;
...
...
@@ -19,9 +21,31 @@ struct nv50_disp_priv {
}
dac
;
struct
{
int
nr
;
int
(
*
dp_train
)(
struct
nv50_disp_priv
*
,
int
sor
,
int
link
,
u16
type
,
u16
mask
,
u32
data
,
struct
dcb_output
*
);
int
(
*
dp_lnkctl
)(
struct
nv50_disp_priv
*
,
int
sor
,
int
link
,
int
head
,
u16
type
,
u16
mask
,
u32
data
,
struct
dcb_output
*
);
int
(
*
dp_drvctl
)(
struct
nv50_disp_priv
*
,
int
sor
,
int
link
,
int
lane
,
u16
type
,
u16
mask
,
u32
data
,
struct
dcb_output
*
);
}
sor
;
};
extern
struct
nouveau_omthds
nva3_disp_base_omthds
[];
#define SOR_MTHD(n) (n), (n) + 0x3f
int
nv50_sor_mthd
(
struct
nouveau_object
*
,
u32
,
void
*
,
u32
);
int
nvd0_sor_dp_train
(
struct
nv50_disp_priv
*
,
int
,
int
,
u16
,
u16
,
u32
,
struct
dcb_output
*
);
int
nvd0_sor_dp_lnkctl
(
struct
nv50_disp_priv
*
,
int
,
int
,
int
,
u16
,
u16
,
u32
,
struct
dcb_output
*
);
int
nvd0_sor_dp_drvctl
(
struct
nv50_disp_priv
*
,
int
,
int
,
int
,
u16
,
u16
,
u32
,
struct
dcb_output
*
);
struct
nv50_disp_base
{
struct
nouveau_parent
base
;
struct
nouveau_ramht
*
ramht
;
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
浏览文件 @
6c5a0424
...
...
@@ -39,6 +39,17 @@ nva3_disp_sclass[] = {
{}
};
struct
nouveau_omthds
nva3_disp_base_omthds
[]
=
{
{
SOR_MTHD
(
NV94_DISP_SOR_DP_TRAIN
)
,
nv50_sor_mthd
},
{
SOR_MTHD
(
NV94_DISP_SOR_DP_LNKCTL
)
,
nv50_sor_mthd
},
{
SOR_MTHD
(
NV94_DISP_SOR_DP_DRVCTL
(
0
)),
nv50_sor_mthd
},
{
SOR_MTHD
(
NV94_DISP_SOR_DP_DRVCTL
(
1
)),
nv50_sor_mthd
},
{
SOR_MTHD
(
NV94_DISP_SOR_DP_DRVCTL
(
2
)),
nv50_sor_mthd
},
{
SOR_MTHD
(
NV94_DISP_SOR_DP_DRVCTL
(
3
)),
nv50_sor_mthd
},
{},
};
static
struct
nouveau_oclass
nva3_disp_base_oclass
[]
=
{
{
NVA3_DISP_CLASS
,
&
nv50_disp_base_ofuncs
},
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
浏览文件 @
6c5a0424
...
...
@@ -552,7 +552,7 @@ nvd0_disp_base_ofuncs = {
static
struct
nouveau_oclass
nvd0_disp_base_oclass
[]
=
{
{
NVD0_DISP_CLASS
,
&
nvd0_disp_base_ofuncs
},
{
NVD0_DISP_CLASS
,
&
nvd0_disp_base_ofuncs
,
nva3_disp_base_omthds
},
{}
};
...
...
@@ -896,6 +896,9 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
head
.
nr
=
nv_rd32
(
priv
,
0x022448
);
priv
->
dac
.
nr
=
3
;
priv
->
sor
.
nr
=
4
;
priv
->
sor
.
dp_train
=
nvd0_sor_dp_train
;
priv
->
sor
.
dp_lnkctl
=
nvd0_sor_dp_lnkctl
;
priv
->
sor
.
dp_drvctl
=
nvd0_sor_dp_drvctl
;
INIT_LIST_HEAD
(
&
priv
->
base
.
vblank
.
list
);
spin_lock_init
(
&
priv
->
base
.
vblank
.
lock
);
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
浏览文件 @
6c5a0424
...
...
@@ -41,7 +41,7 @@ nve0_disp_sclass[] = {
static
struct
nouveau_oclass
nve0_disp_base_oclass
[]
=
{
{
NVE0_DISP_CLASS
,
&
nvd0_disp_base_ofuncs
},
{
NVE0_DISP_CLASS
,
&
nvd0_disp_base_ofuncs
,
nva3_disp_base_omthds
},
{}
};
...
...
@@ -66,6 +66,9 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
head
.
nr
=
nv_rd32
(
priv
,
0x022448
);
priv
->
dac
.
nr
=
3
;
priv
->
sor
.
nr
=
4
;
priv
->
sor
.
dp_train
=
nvd0_sor_dp_train
;
priv
->
sor
.
dp_lnkctl
=
nvd0_sor_dp_lnkctl
;
priv
->
sor
.
dp_drvctl
=
nvd0_sor_dp_drvctl
;
INIT_LIST_HEAD
(
&
priv
->
base
.
vblank
.
list
);
spin_lock_init
(
&
priv
->
base
.
vblank
.
lock
);
...
...
drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
0 → 100644
浏览文件 @
6c5a0424
/*
* 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 <core/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include "nv50.h"
int
nv50_sor_mthd
(
struct
nouveau_object
*
object
,
u32
mthd
,
void
*
args
,
u32
size
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
object
->
engine
;
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
const
u16
type
=
(
mthd
&
NV50_DISP_SOR_MTHD_TYPE
)
>>
12
;
const
u8
head
=
(
mthd
&
NV50_DISP_SOR_MTHD_HEAD
)
>>
3
;
const
u8
link
=
(
mthd
&
NV50_DISP_SOR_MTHD_LINK
)
>>
2
;
const
u8
or
=
(
mthd
&
NV50_DISP_SOR_MTHD_OR
);
const
u16
mask
=
(
0x0100
<<
head
)
|
(
0x0040
<<
link
)
|
(
0x0001
<<
or
);
struct
dcb_output
outp
=
{
.
type
=
type
,
.
or
=
(
1
<<
or
),
.
sorconf
.
link
=
(
1
<<
link
),
};
u8
ver
,
hdr
,
idx
=
0
;
u32
data
;
int
ret
=
-
EINVAL
;
if
(
size
<
sizeof
(
u32
))
return
-
EINVAL
;
while
(
type
&&
(
data
=
dcb_outp
(
bios
,
idx
++
,
&
ver
,
&
hdr
)))
{
u32
conn
=
nv_ro32
(
bios
,
data
+
0
);
u32
conf
=
nv_ro32
(
bios
,
data
+
4
);
if
((
conn
&
0x00300000
)
||
(
conn
&
0x0000000f
)
!=
type
||
(
conn
&
0x0f000000
)
!=
(
0x01000000
<<
or
))
continue
;
if
(
(
mask
&
0x00c0
)
&&
(
mask
&
0x00c0
)
!=
((
mask
&
0x00c0
)
&
((
conf
&
0x00000030
)
<<
2
)))
continue
;
outp
.
connector
=
(
conn
&
0x0000f000
)
>>
12
;
}
if
(
data
==
0x0000
)
return
-
ENODEV
;
data
=
*
(
u32
*
)
args
;
switch
(
mthd
&
~
0x3f
)
{
case
NV94_DISP_SOR_DP_TRAIN
:
ret
=
priv
->
sor
.
dp_train
(
priv
,
or
,
link
,
type
,
mask
,
data
,
&
outp
);
break
;
case
NV94_DISP_SOR_DP_LNKCTL
:
ret
=
priv
->
sor
.
dp_lnkctl
(
priv
,
or
,
link
,
head
,
type
,
mask
,
data
,
&
outp
);
break
;
case
NV94_DISP_SOR_DP_DRVCTL
(
0
):
case
NV94_DISP_SOR_DP_DRVCTL
(
1
):
case
NV94_DISP_SOR_DP_DRVCTL
(
2
):
case
NV94_DISP_SOR_DP_DRVCTL
(
3
):
ret
=
priv
->
sor
.
dp_drvctl
(
priv
,
or
,
link
,
(
mthd
&
0xc0
)
>>
6
,
type
,
mask
,
data
,
&
outp
);
break
;
default:
BUG_ON
(
1
);
}
return
ret
;
}
drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
0 → 100644
浏览文件 @
6c5a0424
/*
* 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 <core/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
#include <subdev/bios/init.h>
#include "nv50.h"
static
inline
u32
nvd0_sor_dp_lane_map
(
struct
nv50_disp_priv
*
priv
,
u8
lane
)
{
static
const
u8
nvd0
[]
=
{
16
,
8
,
0
,
24
};
return
nvd0
[
lane
];
}
int
nvd0_sor_dp_train
(
struct
nv50_disp_priv
*
priv
,
int
or
,
int
link
,
u16
type
,
u16
mask
,
u32
data
,
struct
dcb_output
*
info
)
{
const
u32
loff
=
(
or
*
0x800
)
+
(
link
*
0x80
);
const
u32
patt
=
(
data
&
NV94_DISP_SOR_DP_TRAIN_PATTERN
);
nv_mask
(
priv
,
0x61c110
+
loff
,
0x0f0f0f0f
,
0x01010101
*
patt
);
return
0
;
}
int
nvd0_sor_dp_lnkctl
(
struct
nv50_disp_priv
*
priv
,
int
or
,
int
link
,
int
head
,
u16
type
,
u16
mask
,
u32
data
,
struct
dcb_output
*
dcbo
)
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
const
u32
loff
=
(
or
*
0x800
)
+
(
link
*
0x80
);
const
u32
soff
=
(
or
*
0x800
);
const
u8
link_bw
=
(
data
&
NV94_DISP_SOR_DP_LNKCTL_WIDTH
)
>>
8
;
const
u8
link_nr
=
(
data
&
NV94_DISP_SOR_DP_LNKCTL_COUNT
);
u32
dpctrl
=
0x00000000
;
u32
clksor
=
0x00000000
;
u32
outp
,
lane
=
0
;
u8
ver
,
hdr
,
cnt
,
len
;
struct
nvbios_dpout
info
;
int
i
;
outp
=
nvbios_dpout_match
(
bios
,
type
,
mask
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info
);
if
(
outp
&&
info
.
lnkcmp
)
{
struct
nvbios_init
init
=
{
.
subdev
=
nv_subdev
(
priv
),
.
bios
=
bios
,
.
offset
=
0x0000
,
.
outp
=
dcbo
,
.
crtc
=
head
,
.
execute
=
1
,
};
while
(
nv_ro08
(
bios
,
info
.
lnkcmp
)
<
link_bw
)
info
.
lnkcmp
+=
3
;
init
.
offset
=
nv_ro16
(
bios
,
info
.
lnkcmp
+
1
);
nvbios_exec
(
&
init
);
}
clksor
|=
link_bw
<<
18
;
dpctrl
|=
((
1
<<
link_nr
)
-
1
)
<<
16
;
if
(
data
&
NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH
)
dpctrl
|=
0x00004000
;
for
(
i
=
0
;
i
<
link_nr
;
i
++
)
lane
|=
1
<<
(
nvd0_sor_dp_lane_map
(
priv
,
i
)
>>
3
);
nv_mask
(
priv
,
0x612300
+
soff
,
0x007c0000
,
clksor
);
nv_mask
(
priv
,
0x61c10c
+
loff
,
0x001f4000
,
dpctrl
);
nv_mask
(
priv
,
0x61c130
+
loff
,
0x0000000f
,
lane
);
return
0
;
}
int
nvd0_sor_dp_drvctl
(
struct
nv50_disp_priv
*
priv
,
int
or
,
int
link
,
int
lane
,
u16
type
,
u16
mask
,
u32
data
,
struct
dcb_output
*
dcbo
)
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
const
u32
loff
=
(
or
*
0x800
)
+
(
link
*
0x80
);
const
u8
swing
=
(
data
&
NV94_DISP_SOR_DP_DRVCTL_VS
)
>>
8
;
const
u8
preem
=
(
data
&
NV94_DISP_SOR_DP_DRVCTL_PE
);
u32
addr
,
shift
=
nvd0_sor_dp_lane_map
(
priv
,
lane
);
u8
ver
,
hdr
,
cnt
,
len
;
struct
nvbios_dpout
outp
;
struct
nvbios_dpcfg
ocfg
;
addr
=
nvbios_dpout_match
(
bios
,
type
,
mask
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
outp
);
if
(
!
addr
)
return
-
ENODEV
;
addr
=
nvbios_dpcfg_match
(
bios
,
addr
,
0
,
swing
,
preem
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
ocfg
);
if
(
!
addr
)
return
-
EINVAL
;
nv_mask
(
priv
,
0x61c118
+
loff
,
0x000000ff
<<
shift
,
ocfg
.
drv
<<
shift
);
nv_mask
(
priv
,
0x61c120
+
loff
,
0x000000ff
<<
shift
,
ocfg
.
pre
<<
shift
);
nv_mask
(
priv
,
0x61c130
+
loff
,
0x0000ff00
,
ocfg
.
unk
<<
8
);
nv_mask
(
priv
,
0x61c13c
+
loff
,
0x00000000
,
0x00000000
);
return
0
;
}
drivers/gpu/drm/nouveau/core/include/core/class.h
浏览文件 @
6c5a0424
...
...
@@ -171,6 +171,25 @@ struct nve0_channel_ind_class {
#define NVD0_DISP_CLASS 0x00009070
#define NVE0_DISP_CLASS 0x00009170
#define NV50_DISP_SOR_MTHD 0x00010000
#define NV50_DISP_SOR_MTHD_TYPE 0x0000f000
#define NV50_DISP_SOR_MTHD_HEAD 0x00000018
#define NV50_DISP_SOR_MTHD_LINK 0x00000004
#define NV50_DISP_SOR_MTHD_OR 0x00000003
#define NV94_DISP_SOR_DP_TRAIN 0x00016000
#define NV94_DISP_SOR_DP_TRAIN_PATTERN 0x00000003
#define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED 0x00000000
#define NV94_DISP_SOR_DP_LNKCTL 0x00016040
#define NV94_DISP_SOR_DP_LNKCTL_FRAME 0x80000000
#define NV94_DISP_SOR_DP_LNKCTL_FRAME_STD 0x00000000
#define NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH 0x80000000
#define NV94_DISP_SOR_DP_LNKCTL_WIDTH 0x00001f00
#define NV94_DISP_SOR_DP_LNKCTL_COUNT 0x00000007
#define NV94_DISP_SOR_DP_DRVCTL(l) ((l) * 0x40 + 0x00016100)
#define NV94_DISP_SOR_DP_DRVCTL_VS 0x00000300
#define NV94_DISP_SOR_DP_DRVCTL_PE 0x00000003
struct
nv50_display_class
{
};
...
...
drivers/gpu/drm/nouveau/nvd0_display.c
浏览文件 @
6c5a0424
...
...
@@ -1350,107 +1350,37 @@ nvd0_hdmi_disconnect(struct drm_encoder *encoder)
/******************************************************************************
* SOR
*****************************************************************************/
static
inline
u32
nvd0_sor_dp_lane_map
(
struct
drm_device
*
dev
,
struct
dcb_output
*
dcb
,
u8
lane
)
{
static
const
u8
nvd0
[]
=
{
16
,
8
,
0
,
24
};
return
nvd0
[
lane
];
}
static
void
nvd0_sor_dp_train_set
(
struct
drm_device
*
dev
,
struct
dcb_output
*
dcb
,
u8
pattern
)
{
struct
n
ouveau_device
*
device
=
nouveau_dev
(
dev
);
struct
n
vd0_disp
*
disp
=
nvd0_disp
(
dev
);
const
u32
or
=
ffs
(
dcb
->
or
)
-
1
,
link
=
!
(
dcb
->
sorconf
.
link
&
1
);
const
u32
loff
=
(
or
*
0x800
)
+
(
link
*
0x80
)
;
nv_
mask
(
device
,
0x61c110
+
loff
,
0x0f0f0f0f
,
0x01010101
*
pattern
);
const
u32
moff
=
(
link
<<
2
)
|
or
;
nv_
call
(
disp
->
core
,
NV94_DISP_SOR_DP_TRAIN
+
moff
,
pattern
);
}
static
void
nvd0_sor_dp_train_adj
(
struct
drm_device
*
dev
,
struct
dcb_output
*
dcb
,
u8
lane
,
u8
swing
,
u8
preem
)
{
struct
nouveau_device
*
device
=
nouveau_dev
(
dev
);
struct
nouveau_drm
*
drm
=
nouveau_drm
(
dev
);
struct
nvd0_disp
*
disp
=
nvd0_disp
(
dev
);
const
u32
or
=
ffs
(
dcb
->
or
)
-
1
,
link
=
!
(
dcb
->
sorconf
.
link
&
1
);
const
u32
loff
=
(
or
*
0x800
)
+
(
link
*
0x80
);
u32
shift
=
nvd0_sor_dp_lane_map
(
dev
,
dcb
,
lane
);
u32
mask
=
0x000000ff
<<
shift
;
u8
*
table
,
*
entry
,
*
config
=
NULL
;
switch
(
swing
)
{
case
0
:
preem
+=
0
;
break
;
case
1
:
preem
+=
4
;
break
;
case
2
:
preem
+=
7
;
break
;
case
3
:
preem
+=
9
;
break
;
}
table
=
nouveau_dp_bios_data
(
dev
,
dcb
,
&
entry
);
if
(
table
)
{
if
(
table
[
0
]
==
0x30
)
{
config
=
entry
+
table
[
4
];
config
+=
table
[
5
]
*
preem
;
}
else
if
(
table
[
0
]
==
0x40
)
{
config
=
table
+
table
[
1
];
config
+=
table
[
2
]
*
table
[
3
];
config
+=
table
[
6
]
*
preem
;
}
}
if
(
!
config
)
{
NV_ERROR
(
drm
,
"PDISP: unsupported DP table for chipset
\n
"
);
return
;
}
nv_mask
(
device
,
0x61c118
+
loff
,
mask
,
config
[
1
]
<<
shift
);
nv_mask
(
device
,
0x61c120
+
loff
,
mask
,
config
[
2
]
<<
shift
);
nv_mask
(
device
,
0x61c130
+
loff
,
0x0000ff00
,
config
[
3
]
<<
8
);
nv_mask
(
device
,
0x61c13c
+
loff
,
0x00000000
,
0x00000000
);
const
u32
moff
=
(
link
<<
2
)
|
or
;
const
u32
data
=
(
swing
<<
8
)
|
preem
;
nv_call
(
disp
->
core
,
NV94_DISP_SOR_DP_DRVCTL
(
lane
)
+
moff
,
data
);
}
static
void
nvd0_sor_dp_link_set
(
struct
drm_device
*
dev
,
struct
dcb_output
*
dcb
,
int
crtc
,
int
link_nr
,
u32
link_bw
,
bool
enhframe
)
{
struct
n
ouveau_device
*
device
=
nouveau_dev
(
dev
);
struct
n
vd0_disp
*
disp
=
nvd0_disp
(
dev
);
const
u32
or
=
ffs
(
dcb
->
or
)
-
1
,
link
=
!
(
dcb
->
sorconf
.
link
&
1
);
const
u32
loff
=
(
or
*
0x800
)
+
(
link
*
0x80
);
const
u32
soff
=
(
or
*
0x800
);
u32
dpctrl
=
nv_rd32
(
device
,
0x61c10c
+
loff
)
&
~
0x001f4000
;
u32
clksor
=
nv_rd32
(
device
,
0x612300
+
soff
)
&
~
0x007c0000
;
u32
script
=
0x0000
,
lane_mask
=
0
;
u8
*
table
,
*
entry
;
int
i
;
link_bw
/=
27000
;
table
=
nouveau_dp_bios_data
(
dev
,
dcb
,
&
entry
);
if
(
table
)
{
if
(
table
[
0
]
==
0x30
)
entry
=
ROMPTR
(
dev
,
entry
[
10
]);
else
if
(
table
[
0
]
==
0x40
)
entry
=
ROMPTR
(
dev
,
entry
[
9
]);
else
entry
=
NULL
;
while
(
entry
)
{
if
(
entry
[
0
]
>=
link_bw
)
break
;
entry
+=
3
;
}
nouveau_bios_run_init_table
(
dev
,
script
,
dcb
,
crtc
);
}
clksor
|=
link_bw
<<
18
;
dpctrl
|=
((
1
<<
link_nr
)
-
1
)
<<
16
;
const
u32
moff
=
(
crtc
<<
3
)
|
(
link
<<
2
)
|
or
;
u32
data
=
((
link_bw
/
27000
)
<<
8
)
|
link_nr
;
if
(
enhframe
)
dpctrl
|=
0x00004000
;
for
(
i
=
0
;
i
<
link_nr
;
i
++
)
lane_mask
|=
1
<<
(
nvd0_sor_dp_lane_map
(
dev
,
dcb
,
i
)
>>
3
);
nv_wr32
(
device
,
0x612300
+
soff
,
clksor
);
nv_wr32
(
device
,
0x61c10c
+
loff
,
dpctrl
);
nv_mask
(
device
,
0x61c130
+
loff
,
0x0000000f
,
lane_mask
);
data
|=
NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH
;
nv_call
(
disp
->
core
,
NV94_DISP_SOR_DP_LNKCTL
+
moff
,
data
);
}
static
void
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录