Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
46959b77
Commit
46959b77
authored
Jul 01, 2011
by
Ben Skeggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm/nouveau/dp: remove reliance on vbios for native displayport
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
43720133
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
126 additions
and
63 deletions
+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
No files found.
drivers/gpu/drm/nouveau/nouveau_dp.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment