Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
46959b77
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
46959b77
编写于
7月 01, 2011
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nouveau/dp: remove reliance on vbios for native displayport
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
43720133
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
126 addition
and
63 deletion
+126
-63
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_dp.c
+110
-1
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_drv.h
+1
-0
drivers/gpu/drm/nouveau/nouveau_encoder.h
drivers/gpu/drm/nouveau/nouveau_encoder.h
+0
-3
drivers/gpu/drm/nouveau/nouveau_reg.h
drivers/gpu/drm/nouveau/nouveau_reg.h
+1
-1
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_display.c
+7
-32
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/nouveau/nv50_sor.c
+7
-26
未找到文件。
drivers/gpu/drm/nouveau/nouveau_dp.c
浏览文件 @
46959b77
...
...
@@ -194,6 +194,116 @@ auxch_wr(struct drm_encoder *encoder, int address, uint8_t *buf, int size)
return
ret
;
}
static
u32
dp_link_bw_get
(
struct
drm_device
*
dev
,
int
or
,
int
link
)
{
u32
ctrl
=
nv_rd32
(
dev
,
0x614300
+
(
or
*
0x800
));
if
(
!
(
ctrl
&
0x000c0000
))
return
162000
;
return
270000
;
}
static
int
dp_lane_count_get
(
struct
drm_device
*
dev
,
int
or
,
int
link
)
{
u32
ctrl
=
nv_rd32
(
dev
,
NV50_SOR_DP_CTRL
(
or
,
link
));
switch
(
ctrl
&
0x000f0000
)
{
case
0x00010000
:
return
1
;
case
0x00030000
:
return
2
;
default:
return
4
;
}
}
void
nouveau_dp_tu_update
(
struct
drm_device
*
dev
,
int
or
,
int
link
,
u32
clk
,
u32
bpp
)
{
const
u32
symbol
=
100000
;
int
bestTU
=
0
,
bestVTUi
=
0
,
bestVTUf
=
0
,
bestVTUa
=
0
;
int
TU
,
VTUi
,
VTUf
,
VTUa
;
u64
link_data_rate
,
link_ratio
,
unk
;
u32
best_diff
=
64
*
symbol
;
u32
link_nr
,
link_bw
,
r
;
/* calculate packed data rate for each lane */
link_nr
=
dp_lane_count_get
(
dev
,
or
,
link
);
link_data_rate
=
(
clk
*
bpp
/
8
)
/
link_nr
;
/* calculate ratio of packed data rate to link symbol rate */
link_bw
=
dp_link_bw_get
(
dev
,
or
,
link
);
link_ratio
=
link_data_rate
*
symbol
;
r
=
do_div
(
link_ratio
,
link_bw
);
for
(
TU
=
64
;
TU
>=
32
;
TU
--
)
{
/* calculate average number of valid symbols in each TU */
u32
tu_valid
=
link_ratio
*
TU
;
u32
calc
,
diff
;
/* find a hw representation for the fraction.. */
VTUi
=
tu_valid
/
symbol
;
calc
=
VTUi
*
symbol
;
diff
=
tu_valid
-
calc
;
if
(
diff
)
{
if
(
diff
>=
(
symbol
/
2
))
{
VTUf
=
symbol
/
(
symbol
-
diff
);
if
(
symbol
-
(
VTUf
*
diff
))
VTUf
++
;
if
(
VTUf
<=
15
)
{
VTUa
=
1
;
calc
+=
symbol
-
(
symbol
/
VTUf
);
}
else
{
VTUa
=
0
;
VTUf
=
1
;
calc
+=
symbol
;
}
}
else
{
VTUa
=
0
;
VTUf
=
min
((
int
)(
symbol
/
diff
),
15
);
calc
+=
symbol
/
VTUf
;
}
diff
=
calc
-
tu_valid
;
}
else
{
/* no remainder, but the hw doesn't like the fractional
* part to be zero. decrement the integer part and
* have the fraction add a whole symbol back
*/
VTUa
=
0
;
VTUf
=
1
;
VTUi
--
;
}
if
(
diff
<
best_diff
)
{
best_diff
=
diff
;
bestTU
=
TU
;
bestVTUa
=
VTUa
;
bestVTUf
=
VTUf
;
bestVTUi
=
VTUi
;
if
(
diff
==
0
)
break
;
}
}
if
(
!
bestTU
)
{
NV_ERROR
(
dev
,
"DP: unable to find suitable config
\n
"
);
return
;
}
/* XXX close to vbios numbers, but not right */
unk
=
(
symbol
-
link_ratio
)
*
bestTU
;
unk
*=
link_ratio
;
r
=
do_div
(
unk
,
symbol
);
r
=
do_div
(
unk
,
symbol
);
unk
+=
6
;
nv_mask
(
dev
,
NV50_SOR_DP_CTRL
(
or
,
link
),
0x000001fc
,
bestTU
<<
2
);
nv_mask
(
dev
,
NV50_SOR_DP_SCFG
(
or
,
link
),
0x010f7f3f
,
bestVTUa
<<
24
|
bestVTUf
<<
16
|
bestVTUi
<<
8
|
unk
);
}
static
int
nouveau_dp_lane_count_set
(
struct
drm_encoder
*
encoder
,
uint8_t
cmd
)
{
...
...
@@ -617,7 +727,6 @@ static int
nouveau_dp_i2c_xfer
(
struct
i2c_adapter
*
adap
,
struct
i2c_msg
*
msgs
,
int
num
)
{
struct
nouveau_i2c_chan
*
auxch
=
(
struct
nouveau_i2c_chan
*
)
adap
;
struct
drm_device
*
dev
=
auxch
->
dev
;
struct
i2c_msg
*
msg
=
msgs
;
int
ret
,
mcnt
=
num
;
...
...
drivers/gpu/drm/nouveau/nouveau_drv.h
浏览文件 @
46959b77
...
...
@@ -1101,6 +1101,7 @@ int nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
uint8_t
*
data
,
int
data_nr
);
bool
nouveau_dp_detect
(
struct
drm_encoder
*
);
bool
nouveau_dp_link_train
(
struct
drm_encoder
*
);
void
nouveau_dp_tu_update
(
struct
drm_device
*
,
int
,
int
,
u32
,
u32
);
/* nv04_fb.c */
extern
int
nv04_fb_init
(
struct
drm_device
*
);
...
...
drivers/gpu/drm/nouveau/nouveau_encoder.h
浏览文件 @
46959b77
...
...
@@ -49,9 +49,6 @@ struct nouveau_encoder {
union
{
struct
{
int
mc_unknown
;
uint32_t
unk0
;
uint32_t
unk1
;
int
dpcd_version
;
int
link_nr
;
int
link_bw
;
...
...
drivers/gpu/drm/nouveau/nouveau_reg.h
浏览文件 @
46959b77
...
...
@@ -843,7 +843,7 @@
#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2 0x02000000
#define NV50_SOR_DP_UNK118(i, l) (0x0061c118 + (i) * 0x800 + (l) * 0x80)
#define NV50_SOR_DP_UNK120(i, l) (0x0061c120 + (i) * 0x800 + (l) * 0x80)
#define NV50_SOR_DP_
UNK128(i, l)
(0x0061c128 + (i) * 0x800 + (l) * 0x80)
#define NV50_SOR_DP_
SCFG(i, l)
(0x0061c128 + (i) * 0x800 + (l) * 0x80)
#define NV50_SOR_DP_UNK130(i, l) (0x0061c130 + (i) * 0x800 + (l) * 0x80)
#define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000)
...
...
drivers/gpu/drm/nouveau/nv50_display.c
浏览文件 @
46959b77
...
...
@@ -701,37 +701,6 @@ nv50_display_unk10_handler(struct drm_device *dev)
nv_wr32
(
dev
,
0x610030
,
0x80000000
);
}
static
void
nv50_display_unk20_dp_hack
(
struct
drm_device
*
dev
,
struct
dcb_entry
*
dcb
)
{
int
or
=
ffs
(
dcb
->
or
)
-
1
,
link
=
!
(
dcb
->
dpconf
.
sor
.
link
&
1
);
struct
drm_encoder
*
encoder
;
uint32_t
tmp
,
unk0
=
0
,
unk1
=
0
;
if
(
dcb
->
type
!=
OUTPUT_DP
)
return
;
list_for_each_entry
(
encoder
,
&
dev
->
mode_config
.
encoder_list
,
head
)
{
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
if
(
nv_encoder
->
dcb
==
dcb
)
{
unk0
=
nv_encoder
->
dp
.
unk0
;
unk1
=
nv_encoder
->
dp
.
unk1
;
break
;
}
}
if
(
unk0
||
unk1
)
{
tmp
=
nv_rd32
(
dev
,
NV50_SOR_DP_CTRL
(
or
,
link
));
tmp
&=
0xfffffe03
;
nv_wr32
(
dev
,
NV50_SOR_DP_CTRL
(
or
,
link
),
tmp
|
unk0
);
tmp
=
nv_rd32
(
dev
,
NV50_SOR_DP_UNK128
(
or
,
link
));
tmp
&=
0xfef080c0
;
nv_wr32
(
dev
,
NV50_SOR_DP_UNK128
(
or
,
link
),
tmp
|
unk1
);
}
}
static
void
nv50_display_unk20_handler
(
struct
drm_device
*
dev
)
{
...
...
@@ -830,7 +799,13 @@ nv50_display_unk20_handler(struct drm_device *dev)
script
=
nv50_display_script_select
(
dev
,
dcb
,
mc
,
pclk
);
nouveau_bios_run_display_table
(
dev
,
script
,
pclk
,
dcb
,
-
1
);
nv50_display_unk20_dp_hack
(
dev
,
dcb
);
if
(
type
==
OUTPUT_DP
)
{
int
link
=
!
(
dcb
->
dpconf
.
sor
.
link
&
1
);
if
((
mc
&
0x000f0000
)
==
0x00020000
)
nouveau_dp_tu_update
(
dev
,
or
,
link
,
pclk
,
18
);
else
nouveau_dp_tu_update
(
dev
,
or
,
link
,
pclk
,
24
);
}
if
(
dcb
->
type
!=
OUTPUT_ANALOG
)
{
tmp
=
nv_rd32
(
dev
,
NV50_PDISPLAY_SOR_CLK_CTRL2
(
or
));
...
...
drivers/gpu/drm/nouveau/nv50_sor.c
浏览文件 @
46959b77
...
...
@@ -187,6 +187,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct
nouveau_encoder
*
nv_encoder
=
nouveau_encoder
(
encoder
);
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
nouveau_crtc
*
crtc
=
nouveau_crtc
(
encoder
->
crtc
);
struct
nouveau_connector
*
nv_connector
;
uint32_t
mode_ctl
=
0
;
int
ret
;
...
...
@@ -206,7 +207,12 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode_ctl
=
0x0200
;
break
;
case
OUTPUT_DP
:
mode_ctl
|=
(
nv_encoder
->
dp
.
mc_unknown
<<
16
);
nv_connector
=
nouveau_encoder_connector_get
(
nv_encoder
);
if
(
nv_connector
&&
nv_connector
->
base
.
display_info
.
bpc
==
6
)
mode_ctl
|=
0x00020000
;
else
mode_ctl
|=
0x00050000
;
if
(
nv_encoder
->
dcb
->
sorconf
.
link
&
1
)
mode_ctl
|=
0x00000800
;
else
...
...
@@ -313,31 +319,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
encoder
->
possible_crtcs
=
entry
->
heads
;
encoder
->
possible_clones
=
0
;
if
(
nv_encoder
->
dcb
->
type
==
OUTPUT_DP
)
{
int
or
=
nv_encoder
->
or
,
link
=
!
(
entry
->
dpconf
.
sor
.
link
&
1
);
uint32_t
tmp
;
tmp
=
nv_rd32
(
dev
,
0x61c700
+
(
or
*
0x800
));
if
(
!
tmp
)
tmp
=
nv_rd32
(
dev
,
0x610798
+
(
or
*
8
));
switch
((
tmp
&
0x00000f00
)
>>
8
)
{
case
8
:
case
9
:
nv_encoder
->
dp
.
mc_unknown
=
(
tmp
&
0x000f0000
)
>>
16
;
tmp
=
nv_rd32
(
dev
,
NV50_SOR_DP_CTRL
(
or
,
link
));
nv_encoder
->
dp
.
unk0
=
tmp
&
0x000001fc
;
tmp
=
nv_rd32
(
dev
,
NV50_SOR_DP_UNK128
(
or
,
link
));
nv_encoder
->
dp
.
unk1
=
tmp
&
0x010f7f3f
;
break
;
default:
break
;
}
if
(
!
nv_encoder
->
dp
.
mc_unknown
)
nv_encoder
->
dp
.
mc_unknown
=
5
;
}
drm_mode_connector_attach_encoder
(
connector
,
encoder
);
return
0
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录