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
3b52a1f9
Commit
3b52a1f9
authored
May 19, 2014
by
Ben Skeggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm/nouveau/disp/dp: make use of existing output data for link training
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
2bd651ea
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
133 additions
and
248 deletions
+133
-248
drivers/gpu/drm/nouveau/core/engine/disp/dport.c
drivers/gpu/drm/nouveau/core/engine/disp/dport.c
+64
-103
drivers/gpu/drm/nouveau/core/engine/disp/dport.h
drivers/gpu/drm/nouveau/core/engine/disp/dport.h
+0
-19
drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
+0
-1
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+2
-5
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
+0
-2
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
+0
-1
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
+0
-2
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
+0
-1
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
+0
-2
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+1
-3
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
+0
-1
drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
+0
-1
drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h
drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h
+5
-0
drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c
drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c
+17
-51
drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
+22
-28
drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
+22
-28
No files found.
drivers/gpu/drm/nouveau/core/engine/disp/dport.c
View file @
3b52a1f9
...
...
@@ -33,24 +33,13 @@
#include <core/class.h>
#include "dport.h"
#define DBG(fmt, args...) nv_debug(dp->disp, "DP:%04x:%04x: " fmt, \
dp->outp->hasht, dp->outp->hashm, ##args)
#define ERR(fmt, args...) nv_error(dp->disp, "DP:%04x:%04x: " fmt, \
dp->outp->hasht, dp->outp->hashm, ##args)
#include "outpdp.h"
/******************************************************************************
* link training
*****************************************************************************/
struct
dp_state
{
const
struct
nouveau_dp_func
*
func
;
struct
nouveau_disp
*
disp
;
struct
dcb_output
*
outp
;
struct
nvbios_dpout
info
;
u8
version
;
struct
nouveau_i2c_port
*
aux
;
int
head
;
u8
dpcd
[
16
];
struct
nvkm_output_dp
*
outp
;
int
link_nr
;
u32
link_bw
;
u8
stat
[
6
];
...
...
@@ -63,14 +52,16 @@ struct dp_state {
static
int
dp_set_link_config
(
struct
dp_state
*
dp
)
{
struct
nouveau_disp
*
disp
=
dp
->
disp
;
struct
nvkm_output_dp_impl
*
impl
=
(
void
*
)
nv_oclass
(
dp
->
outp
);
struct
nvkm_output_dp
*
outp
=
dp
->
outp
;
struct
nouveau_disp
*
disp
=
nouveau_disp
(
outp
);
struct
nouveau_bios
*
bios
=
nouveau_bios
(
disp
);
struct
nvbios_init
init
=
{
.
subdev
=
nv_subdev
(
d
p
->
d
isp
),
.
subdev
=
nv_subdev
(
disp
),
.
bios
=
bios
,
.
offset
=
0x0000
,
.
outp
=
dp
->
outp
,
.
crtc
=
dp
->
head
,
.
outp
=
&
outp
->
base
.
info
,
.
crtc
=
-
1
,
.
execute
=
1
,
};
u32
lnkcmp
;
...
...
@@ -80,8 +71,8 @@ dp_set_link_config(struct dp_state *dp)
DBG
(
"%d lanes at %d KB/s
\n
"
,
dp
->
link_nr
,
dp
->
link_bw
);
/* set desired link configuration on the source */
if
((
lnkcmp
=
dp
->
info
.
lnkcmp
))
{
if
(
d
p
->
version
<
0x30
)
{
if
((
lnkcmp
=
dp
->
outp
->
info
.
lnkcmp
))
{
if
(
out
p
->
version
<
0x30
)
{
while
((
dp
->
link_bw
/
10
)
<
nv_ro16
(
bios
,
lnkcmp
))
lnkcmp
+=
4
;
init
.
offset
=
nv_ro16
(
bios
,
lnkcmp
+
2
);
...
...
@@ -94,43 +85,45 @@ dp_set_link_config(struct dp_state *dp)
nvbios_exec
(
&
init
);
}
ret
=
dp
->
func
->
lnk_ctl
(
dp
->
disp
,
dp
->
outp
,
dp
->
head
,
dp
->
link_nr
,
dp
->
link_bw
/
27000
,
dp
->
dpcd
[
DPCD_RC02
]
&
DPCD_RC02_ENHANCED_FRAME_CAP
);
ret
=
impl
->
lnk_ctl
(
outp
,
dp
->
link_nr
,
dp
->
link_bw
/
27000
,
outp
->
dpcd
[
DPCD_RC02
]
&
DPCD_RC02_ENHANCED_FRAME_CAP
);
if
(
ret
)
{
ERR
(
"lnk_ctl failed with %d
\n
"
,
ret
);
if
(
ret
<
0
)
ERR
(
"lnk_ctl failed with %d
\n
"
,
ret
);
return
ret
;
}
/* set desired link configuration on the sink */
sink
[
0
]
=
dp
->
link_bw
/
27000
;
sink
[
1
]
=
dp
->
link_nr
;
if
(
d
p
->
dpcd
[
DPCD_RC02
]
&
DPCD_RC02_ENHANCED_FRAME_CAP
)
if
(
out
p
->
dpcd
[
DPCD_RC02
]
&
DPCD_RC02_ENHANCED_FRAME_CAP
)
sink
[
1
]
|=
DPCD_LC01_ENHANCED_FRAME_EN
;
return
nv_wraux
(
dp
->
aux
,
DPCD_LC00
,
sink
,
2
);
return
nv_wraux
(
outp
->
base
.
edid
,
DPCD_LC00
,
sink
,
2
);
}
static
void
dp_set_training_pattern
(
struct
dp_state
*
dp
,
u8
pattern
)
{
struct
nvkm_output_dp_impl
*
impl
=
(
void
*
)
nv_oclass
(
dp
->
outp
);
struct
nvkm_output_dp
*
outp
=
dp
->
outp
;
u8
sink_tp
;
DBG
(
"training pattern %d
\n
"
,
pattern
);
dp
->
func
->
pattern
(
dp
->
disp
,
dp
->
outp
,
dp
->
head
,
pattern
);
impl
->
pattern
(
outp
,
pattern
);
nv_rdaux
(
dp
->
aux
,
DPCD_LC02
,
&
sink_tp
,
1
);
nv_rdaux
(
outp
->
base
.
edid
,
DPCD_LC02
,
&
sink_tp
,
1
);
sink_tp
&=
~
DPCD_LC02_TRAINING_PATTERN_SET
;
sink_tp
|=
pattern
;
nv_wraux
(
dp
->
aux
,
DPCD_LC02
,
&
sink_tp
,
1
);
nv_wraux
(
outp
->
base
.
edid
,
DPCD_LC02
,
&
sink_tp
,
1
);
}
static
int
dp_link_train_commit
(
struct
dp_state
*
dp
,
bool
pc
)
{
const
struct
nouveau_dp_func
*
func
=
dp
->
func
;
struct
n
ouveau_disp
*
disp
=
dp
->
dis
p
;
struct
nvkm_output_dp_impl
*
impl
=
(
void
*
)
nv_oclass
(
dp
->
outp
)
;
struct
n
vkm_output_dp
*
outp
=
dp
->
out
p
;
int
ret
,
i
;
for
(
i
=
0
;
i
<
dp
->
link_nr
;
i
++
)
{
...
...
@@ -146,15 +139,15 @@ dp_link_train_commit(struct dp_state *dp, bool pc)
dp
->
pc2conf
[
i
>>
1
]
|=
4
<<
((
i
&
1
)
*
4
);
DBG
(
"config lane %d %02x
\n
"
,
i
,
dp
->
conf
[
i
]);
func
->
drv_ctl
(
disp
,
dp
->
outp
,
dp
->
head
,
i
,
lvsw
,
lpre
);
impl
->
drv_ctl
(
outp
,
i
,
lvsw
,
lpre
,
0
);
}
ret
=
nv_wraux
(
dp
->
aux
,
DPCD_LC03
(
0
),
dp
->
conf
,
4
);
ret
=
nv_wraux
(
outp
->
base
.
edid
,
DPCD_LC03
(
0
),
dp
->
conf
,
4
);
if
(
ret
)
return
ret
;
if
(
pc
)
{
ret
=
nv_wraux
(
dp
->
aux
,
DPCD_LC0F
,
dp
->
pc2conf
,
2
);
ret
=
nv_wraux
(
outp
->
base
.
edid
,
DPCD_LC0F
,
dp
->
pc2conf
,
2
);
if
(
ret
)
return
ret
;
}
...
...
@@ -165,19 +158,20 @@ dp_link_train_commit(struct dp_state *dp, bool pc)
static
int
dp_link_train_update
(
struct
dp_state
*
dp
,
bool
pc
,
u32
delay
)
{
struct
nvkm_output_dp
*
outp
=
dp
->
outp
;
int
ret
;
if
(
d
p
->
dpcd
[
DPCD_RC0E_AUX_RD_INTERVAL
])
mdelay
(
d
p
->
dpcd
[
DPCD_RC0E_AUX_RD_INTERVAL
]
*
4
);
if
(
out
p
->
dpcd
[
DPCD_RC0E_AUX_RD_INTERVAL
])
mdelay
(
out
p
->
dpcd
[
DPCD_RC0E_AUX_RD_INTERVAL
]
*
4
);
else
udelay
(
delay
);
ret
=
nv_rdaux
(
dp
->
aux
,
DPCD_LS02
,
dp
->
stat
,
6
);
ret
=
nv_rdaux
(
outp
->
base
.
edid
,
DPCD_LS02
,
dp
->
stat
,
6
);
if
(
ret
)
return
ret
;
if
(
pc
)
{
ret
=
nv_rdaux
(
dp
->
aux
,
DPCD_LS0C
,
&
dp
->
pc2stat
,
1
);
ret
=
nv_rdaux
(
outp
->
base
.
edid
,
DPCD_LS0C
,
&
dp
->
pc2stat
,
1
);
if
(
ret
)
dp
->
pc2stat
=
0x00
;
DBG
(
"status %6ph pc2 %02x
\n
"
,
dp
->
stat
,
dp
->
pc2stat
);
...
...
@@ -225,10 +219,11 @@ dp_link_train_cr(struct dp_state *dp)
static
int
dp_link_train_eq
(
struct
dp_state
*
dp
)
{
struct
nvkm_output_dp
*
outp
=
dp
->
outp
;
bool
eq_done
=
false
,
cr_done
=
true
;
int
tries
=
0
,
i
;
if
(
d
p
->
dpcd
[
2
]
&
DPCD_RC02_TPS3_SUPPORTED
)
if
(
out
p
->
dpcd
[
2
]
&
DPCD_RC02_TPS3_SUPPORTED
)
dp_set_training_pattern
(
dp
,
3
);
else
dp_set_training_pattern
(
dp
,
2
);
...
...
@@ -257,39 +252,45 @@ dp_link_train_eq(struct dp_state *dp)
static
void
dp_link_train_init
(
struct
dp_state
*
dp
,
bool
spread
)
{
struct
nvkm_output_dp
*
outp
=
dp
->
outp
;
struct
nouveau_disp
*
disp
=
nouveau_disp
(
outp
);
struct
nouveau_bios
*
bios
=
nouveau_bios
(
disp
);
struct
nvbios_init
init
=
{
.
subdev
=
nv_subdev
(
d
p
->
d
isp
),
.
bios
=
nouveau_bios
(
dp
->
disp
)
,
.
outp
=
dp
->
outp
,
.
crtc
=
dp
->
head
,
.
subdev
=
nv_subdev
(
disp
),
.
bios
=
bios
,
.
outp
=
&
outp
->
base
.
info
,
.
crtc
=
-
1
,
.
execute
=
1
,
};
/* set desired spread */
if
(
spread
)
init
.
offset
=
d
p
->
info
.
script
[
2
];
init
.
offset
=
out
p
->
info
.
script
[
2
];
else
init
.
offset
=
d
p
->
info
.
script
[
3
];
init
.
offset
=
out
p
->
info
.
script
[
3
];
nvbios_exec
(
&
init
);
/* pre-train script */
init
.
offset
=
d
p
->
info
.
script
[
0
];
init
.
offset
=
out
p
->
info
.
script
[
0
];
nvbios_exec
(
&
init
);
}
static
void
dp_link_train_fini
(
struct
dp_state
*
dp
)
{
struct
nvkm_output_dp
*
outp
=
dp
->
outp
;
struct
nouveau_disp
*
disp
=
nouveau_disp
(
outp
);
struct
nouveau_bios
*
bios
=
nouveau_bios
(
disp
);
struct
nvbios_init
init
=
{
.
subdev
=
nv_subdev
(
d
p
->
d
isp
),
.
bios
=
nouveau_bios
(
dp
->
disp
)
,
.
outp
=
dp
->
outp
,
.
crtc
=
dp
->
head
,
.
subdev
=
nv_subdev
(
disp
),
.
bios
=
bios
,
.
outp
=
&
outp
->
base
.
info
,
.
crtc
=
-
1
,
.
execute
=
1
,
};
/* post-train script */
init
.
offset
=
d
p
->
info
.
script
[
1
],
init
.
offset
=
out
p
->
info
.
script
[
1
],
nvbios_exec
(
&
init
);
}
...
...
@@ -311,65 +312,25 @@ static const struct dp_rates {
};
int
nouveau_dp_train
(
struct
nouveau_disp
*
disp
,
const
struct
nouveau_dp_func
*
func
,
struct
dcb_output
*
outp
,
int
head
,
u32
datarate
)
nouveau_dp_train
(
struct
nvkm_output_dp
*
outp
,
u32
datarate
)
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
disp
);
struct
nouveau_i2c
*
i2c
=
nouveau_i2c
(
disp
);
struct
nouveau_disp
*
disp
=
nouveau_disp
(
outp
);
const
struct
dp_rates
*
cfg
=
nouveau_dp_rates
;
struct
dp_state
_dp
=
{
.
disp
=
disp
,
.
func
=
func
,
.
outp
=
outp
,
.
head
=
head
,
},
*
dp
=
&
_dp
;
u8
hdr
,
cnt
,
len
;
u32
data
;
int
ret
;
/* find the bios displayport data relevant to this output */
data
=
nvbios_dpout_match
(
bios
,
outp
->
hasht
,
outp
->
hashm
,
&
dp
->
version
,
&
hdr
,
&
cnt
,
&
len
,
&
dp
->
info
);
if
(
!
data
)
{
ERR
(
"bios data not found
\n
"
);
return
-
EINVAL
;
}
/* acquire the aux channel and fetch some info about the display */
if
(
outp
->
location
)
dp
->
aux
=
i2c
->
find_type
(
i2c
,
NV_I2C_TYPE_EXTAUX
(
outp
->
extdev
));
else
dp
->
aux
=
i2c
->
find
(
i2c
,
NV_I2C_TYPE_DCBI2C
(
outp
->
i2c_index
));
if
(
!
dp
->
aux
)
{
ERR
(
"no aux channel?!
\n
"
);
return
-
ENODEV
;
}
ret
=
nv_rdaux
(
dp
->
aux
,
0x00000
,
dp
->
dpcd
,
sizeof
(
dp
->
dpcd
));
if
(
ret
)
{
/* it's possible the display has been unplugged before we
* get here. we still need to execute the full set of
* vbios scripts, and program the OR at a high enough
* frequency to satisfy the target mode. failure to do
* so results at best in an UPDATE hanging, and at worst
* with PDISP running away to join the circus.
*/
dp
->
dpcd
[
1
]
=
dp
->
outp
->
dpconf
.
link_bw
;
dp
->
dpcd
[
2
]
=
dp
->
outp
->
dpconf
.
link_nr
;
dp
->
dpcd
[
3
]
=
0x00
;
ERR
(
"failed to read DPCD
\n
"
);
}
/* bring capabilities within encoder limits */
if
(
nv_mclass
(
disp
)
<
NVD0_DISP_CLASS
)
d
p
->
dpcd
[
2
]
&=
~
DPCD_RC02_TPS3_SUPPORTED
;
if
((
dp
->
dpcd
[
2
]
&
0x1f
)
>
dp
->
outp
->
dpconf
.
link_nr
)
{
d
p
->
dpcd
[
2
]
&=
~
DPCD_RC02_MAX_LANE_COUNT
;
dp
->
dpcd
[
2
]
|=
dp
->
outp
->
dpconf
.
link_nr
;
out
p
->
dpcd
[
2
]
&=
~
DPCD_RC02_TPS3_SUPPORTED
;
if
((
outp
->
dpcd
[
2
]
&
0x1f
)
>
outp
->
base
.
info
.
dpconf
.
link_nr
)
{
out
p
->
dpcd
[
2
]
&=
~
DPCD_RC02_MAX_LANE_COUNT
;
outp
->
dpcd
[
2
]
|=
outp
->
base
.
info
.
dpconf
.
link_nr
;
}
if
(
dp
->
dpcd
[
1
]
>
dp
->
outp
->
dpconf
.
link_bw
)
dp
->
dpcd
[
1
]
=
dp
->
outp
->
dpconf
.
link_bw
;
dp
->
pc2
=
d
p
->
dpcd
[
2
]
&
DPCD_RC02_TPS3_SUPPORTED
;
if
(
outp
->
dpcd
[
1
]
>
outp
->
base
.
info
.
dpconf
.
link_bw
)
outp
->
dpcd
[
1
]
=
outp
->
base
.
info
.
dpconf
.
link_bw
;
dp
->
pc2
=
out
p
->
dpcd
[
2
]
&
DPCD_RC02_TPS3_SUPPORTED
;
/* restrict link config to the lowest required rate, if requested */
if
(
datarate
)
{
...
...
@@ -380,12 +341,12 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
cfg
--
;
/* enable down-spreading and execute pre-train script from vbios */
dp_link_train_init
(
dp
,
d
p
->
dpcd
[
3
]
&
0x01
);
dp_link_train_init
(
dp
,
out
p
->
dpcd
[
3
]
&
0x01
);
while
(
ret
=
-
EIO
,
(
++
cfg
)
->
rate
)
{
/* select next configuration supported by encoder and sink */
while
(
cfg
->
nr
>
(
d
p
->
dpcd
[
2
]
&
DPCD_RC02_MAX_LANE_COUNT
)
||
cfg
->
bw
>
(
d
p
->
dpcd
[
DPCD_RC01_MAX_LINK_RATE
]))
while
(
cfg
->
nr
>
(
out
p
->
dpcd
[
2
]
&
DPCD_RC02_MAX_LANE_COUNT
)
||
cfg
->
bw
>
(
out
p
->
dpcd
[
DPCD_RC01_MAX_LINK_RATE
]))
cfg
++
;
dp
->
link_bw
=
cfg
->
bw
*
27000
;
dp
->
link_nr
=
cfg
->
nr
;
...
...
drivers/gpu/drm/nouveau/core/engine/disp/dport.h
View file @
3b52a1f9
...
...
@@ -71,23 +71,4 @@
#define DPCD_LS0C_LANE1_POST_CURSOR2 0x0c
#define DPCD_LS0C_LANE0_POST_CURSOR2 0x03
struct
nouveau_disp
;
struct
dcb_output
;
struct
nouveau_dp_func
{
int
(
*
pattern
)(
struct
nouveau_disp
*
,
struct
dcb_output
*
,
int
head
,
int
pattern
);
int
(
*
lnk_ctl
)(
struct
nouveau_disp
*
,
struct
dcb_output
*
,
int
head
,
int
link_nr
,
int
link_bw
,
bool
enh_frame
);
int
(
*
drv_ctl
)(
struct
nouveau_disp
*
,
struct
dcb_output
*
,
int
head
,
int
lane
,
int
swing
,
int
preem
);
};
extern
const
struct
nouveau_dp_func
nv94_sor_dp_func
;
extern
const
struct
nouveau_dp_func
nvd0_sor_dp_func
;
extern
const
struct
nouveau_dp_func
nv50_pior_dp_func
;
int
nouveau_dp_train
(
struct
nouveau_disp
*
,
const
struct
nouveau_dp_func
*
,
struct
dcb_output
*
,
int
,
u32
);
#endif
drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
View file @
3b52a1f9
...
...
@@ -81,7 +81,6 @@ gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hda_eld
=
nvd0_hda_eld
;
priv
->
sor
.
hdmi
=
nvd0_hdmi_ctrl
;
priv
->
sor
.
dp
=
&
nvd0_sor_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
View file @
3b52a1f9
...
...
@@ -1471,8 +1471,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head)
break
;
}
nouveau_dp_train
(
&
priv
->
base
,
priv
->
sor
.
dp
,
&
outp
->
info
,
head
,
datarate
);
nouveau_dp_train
((
void
*
)
outp
,
datarate
);
}
exec_clkcmp
(
priv
,
head
,
0
,
pclk
,
&
conf
);
...
...
@@ -1551,8 +1550,7 @@ nv50_disp_intr_unk40_0(struct nv50_disp_priv *priv, int head)
break
;
}
nouveau_dp_train
(
&
priv
->
base
,
priv
->
pior
.
dp
,
&
outp
->
info
,
head
,
datarate
);
nouveau_dp_train
((
void
*
)
outp
,
datarate
);
}
}
...
...
@@ -1665,7 +1663,6 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
dac
.
sense
=
nv50_dac_sense
;
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
pior
.
power
=
nv50_pior_power
;
priv
->
pior
.
dp
=
&
nv50_pior_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
View file @
3b52a1f9
...
...
@@ -45,13 +45,11 @@ struct nv50_disp_priv {
int
(
*
hda_eld
)(
struct
nv50_disp_priv
*
,
int
sor
,
u8
*
,
u32
);
int
(
*
hdmi
)(
struct
nv50_disp_priv
*
,
int
head
,
int
sor
,
u32
);
u32
lvdsconf
;
const
struct
nouveau_dp_func
*
dp
;
}
sor
;
struct
{
int
nr
;
int
(
*
power
)(
struct
nv50_disp_priv
*
,
int
ext
,
u32
data
);
u8
type
[
3
];
const
struct
nouveau_dp_func
*
dp
;
}
pior
;
};
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
View file @
3b52a1f9
...
...
@@ -264,7 +264,6 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hdmi
=
nv84_hdmi_ctrl
;
priv
->
pior
.
power
=
nv50_pior_power
;
priv
->
pior
.
dp
=
&
nv50_pior_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
View file @
3b52a1f9
...
...
@@ -122,9 +122,7 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
dac
.
sense
=
nv50_dac_sense
;
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hdmi
=
nv84_hdmi_ctrl
;
priv
->
sor
.
dp
=
&
nv94_sor_dp_func
;
priv
->
pior
.
power
=
nv50_pior_power
;
priv
->
pior
.
dp
=
&
nv50_pior_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
View file @
3b52a1f9
...
...
@@ -126,7 +126,6 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hdmi
=
nv84_hdmi_ctrl
;
priv
->
pior
.
power
=
nv50_pior_power
;
priv
->
pior
.
dp
=
&
nv50_pior_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
View file @
3b52a1f9
...
...
@@ -96,9 +96,7 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hda_eld
=
nva3_hda_eld
;
priv
->
sor
.
hdmi
=
nva3_hdmi_ctrl
;
priv
->
sor
.
dp
=
&
nv94_sor_dp_func
;
priv
->
pior
.
power
=
nv50_pior_power
;
priv
->
pior
.
dp
=
&
nv50_pior_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
View file @
3b52a1f9
...
...
@@ -1149,8 +1149,7 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
break
;
}
nouveau_dp_train
(
&
priv
->
base
,
priv
->
sor
.
dp
,
&
outp
->
info
,
head
,
pclk
);
nouveau_dp_train
((
void
*
)
outp
,
pclk
);
}
exec_clkcmp
(
priv
,
head
,
0
,
pclk
,
&
conf
);
...
...
@@ -1360,7 +1359,6 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hda_eld
=
nvd0_hda_eld
;
priv
->
sor
.
hdmi
=
nvd0_hdmi_ctrl
;
priv
->
sor
.
dp
=
&
nvd0_sor_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
View file @
3b52a1f9
...
...
@@ -246,7 +246,6 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hda_eld
=
nvd0_hda_eld
;
priv
->
sor
.
hdmi
=
nvd0_hdmi_ctrl
;
priv
->
sor
.
dp
=
&
nvd0_sor_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
View file @
3b52a1f9
...
...
@@ -81,7 +81,6 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
sor
.
power
=
nv50_sor_power
;
priv
->
sor
.
hda_eld
=
nvd0_hda_eld
;
priv
->
sor
.
hdmi
=
nvd0_hdmi_ctrl
;
priv
->
sor
.
dp
=
&
nvd0_sor_dp_func
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h
View file @
3b52a1f9
...
...
@@ -48,6 +48,11 @@ int _nvkm_output_dp_fini(struct nouveau_object *, bool);
struct
nvkm_output_dp_impl
{
struct
nvkm_output_impl
base
;
int
(
*
pattern
)(
struct
nvkm_output_dp
*
,
int
);
int
(
*
lnk_ctl
)(
struct
nvkm_output_dp
*
,
int
nr
,
int
bw
,
bool
ef
);
int
(
*
drv_ctl
)(
struct
nvkm_output_dp
*
,
int
ln
,
int
vs
,
int
pe
,
int
pc
);
};
int
nouveau_dp_train
(
struct
nvkm_output_dp
*
,
u32
rate
);
#endif
drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c
View file @
3b52a1f9
...
...
@@ -70,70 +70,33 @@ nv50_pior_tmds_impl = {
* DisplayPort
*****************************************************************************/
static
struct
nouveau_i2c_port
*
nv50_pior_dp_find
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
)
{
struct
nouveau_i2c
*
i2c
=
nouveau_i2c
(
disp
);
return
i2c
->
find_type
(
i2c
,
NV_I2C_TYPE_EXTAUX
(
outp
->
extdev
));
}
static
int
nv50_pior_dp_pattern
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
pattern
)
nv50_pior_dp_pattern
(
struct
nvkm_output_dp
*
outp
,
int
pattern
)
{
struct
nouveau_i2c_port
*
port
;
int
ret
=
-
EINVAL
;
port
=
nv50_pior_dp_find
(
disp
,
outp
);
if
(
port
)
{
if
(
port
->
func
->
pattern
)
ret
=
port
->
func
->
pattern
(
port
,
pattern
);
else
ret
=
0
;
}
return
ret
;
struct
nouveau_i2c_port
*
port
=
outp
->
base
.
edid
;
if
(
port
&&
port
->
func
->
pattern
)
return
port
->
func
->
pattern
(
port
,
pattern
);
return
port
?
0
:
-
ENODEV
;
}
static
int
nv50_pior_dp_lnk_ctl
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
lane_nr
,
int
link_bw
,
bool
enh
)
nv50_pior_dp_lnk_ctl
(
struct
nvkm_output_dp
*
outp
,
int
nr
,
int
bw
,
bool
ef
)
{
struct
nouveau_i2c_port
*
port
;
int
ret
=
-
EINVAL
;
port
=
nv50_pior_dp_find
(
disp
,
outp
);
struct
nouveau_i2c_port
*
port
=
outp
->
base
.
edid
;
if
(
port
&&
port
->
func
->
lnk_ctl
)
ret
=
port
->
func
->
lnk_ctl
(
port
,
lane_nr
,
link_bw
,
enh
);
return
ret
;
return
port
->
func
->
lnk_ctl
(
port
,
nr
,
bw
,
ef
);
return
port
?
0
:
-
ENODEV
;
}
static
int
nv50_pior_dp_drv_ctl
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
lane
,
int
vsw
,
int
pre
)
nv50_pior_dp_drv_ctl
(
struct
nvkm_output_dp
*
outp
,
int
ln
,
int
vs
,
int
pe
,
int
pc
)
{
struct
nouveau_i2c_port
*
port
;
int
ret
=
-
EINVAL
;
port
=
nv50_pior_dp_find
(
disp
,
outp
);
if
(
port
)
{
if
(
port
->
func
->
drv_ctl
)
ret
=
port
->
func
->
drv_ctl
(
port
,
lane
,
vsw
,
pre
);
else
ret
=
0
;
}
return
ret
;
struct
nouveau_i2c_port
*
port
=
outp
->
base
.
edid
;
if
(
port
&&
port
->
func
->
drv_ctl
)
return
port
->
func
->
drv_ctl
(
port
,
ln
,
vs
,
pe
);
return
port
?
0
:
-
ENODEV
;
}
const
struct
nouveau_dp_func
nv50_pior_dp_func
=
{
.
pattern
=
nv50_pior_dp_pattern
,
.
lnk_ctl
=
nv50_pior_dp_lnk_ctl
,
.
drv_ctl
=
nv50_pior_dp_drv_ctl
,
};
static
int
nv50_pior_dp_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
...
...
@@ -163,6 +126,9 @@ nv50_pior_dp_impl = {
.
init
=
_nvkm_output_dp_init
,
.
fini
=
_nvkm_output_dp_fini
,
},
.
pattern
=
nv50_pior_dp_pattern
,
.
lnk_ctl
=
nv50_pior_dp_lnk_ctl
,
.
drv_ctl
=
nv50_pior_dp_drv_ctl
,
};
/******************************************************************************
...
...
drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
View file @
3b52a1f9
...
...
@@ -34,15 +34,15 @@
#include "outpdp.h"
static
inline
u32
nv94_sor_soff
(
struct
dcb_output
*
outp
)
nv94_sor_soff
(
struct
nvkm_output_dp
*
outp
)
{
return
(
ffs
(
outp
->
or
)
-
1
)
*
0x800
;
return
(
ffs
(
outp
->
base
.
info
.
or
)
-
1
)
*
0x800
;
}
static
inline
u32
nv94_sor_loff
(
struct
dcb_output
*
outp
)
nv94_sor_loff
(
struct
nvkm_output_dp
*
outp
)
{
return
nv94_sor_soff
(
outp
)
+
!
(
outp
->
sorconf
.
link
&
1
)
*
0x80
;
return
nv94_sor_soff
(
outp
)
+
!
(
outp
->
base
.
info
.
sorconf
.
link
&
1
)
*
0x80
;
}
static
inline
u32
...
...
@@ -56,20 +56,18 @@ nv94_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
}
static
int
nv94_sor_dp_pattern
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
pattern
)
nv94_sor_dp_pattern
(
struct
nvkm_output_dp
*
outp
,
int
pattern
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
disp
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
nouveau_disp
(
outp
)
;
const
u32
loff
=
nv94_sor_loff
(
outp
);
nv_mask
(
priv
,
0x61c10c
+
loff
,
0x0f000000
,
pattern
<<
24
);
return
0
;
}
static
int
nv94_sor_dp_lnk_ctl
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
link_nr
,
int
link_bw
,
bool
enh_frame
)
nv94_sor_dp_lnk_ctl
(
struct
nvkm_output_dp
*
outp
,
int
nr
,
int
bw
,
bool
ef
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
disp
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
nouveau_disp
(
outp
)
;
const
u32
soff
=
nv94_sor_soff
(
outp
);
const
u32
loff
=
nv94_sor_loff
(
outp
);
u32
dpctrl
=
0x00000000
;
...
...
@@ -77,13 +75,13 @@ nv94_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
u32
lane
=
0
;
int
i
;
dpctrl
|=
((
1
<<
link_
nr
)
-
1
)
<<
16
;
if
(
e
nh_frame
)
dpctrl
|=
((
1
<<
nr
)
-
1
)
<<
16
;
if
(
e
f
)
dpctrl
|=
0x00004000
;
if
(
link_
bw
>
0x06
)
if
(
bw
>
0x06
)
clksor
|=
0x00040000
;
for
(
i
=
0
;
i
<
link_
nr
;
i
++
)
for
(
i
=
0
;
i
<
nr
;
i
++
)
lane
|=
1
<<
(
nv94_sor_dp_lane_map
(
priv
,
i
)
>>
3
);
nv_mask
(
priv
,
0x614300
+
soff
,
0x000c0000
,
clksor
);
...
...
@@ -93,24 +91,24 @@ nv94_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
}
static
int
nv94_sor_dp_drv_ctl
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
lane
,
int
swing
,
int
preem
)
nv94_sor_dp_drv_ctl
(
struct
nvkm_output_dp
*
outp
,
int
ln
,
int
vs
,
int
pe
,
int
pc
)
{
struct
n
ouveau_bios
*
bios
=
nouveau_bios
(
dis
p
);
struct
n
v50_disp_priv
*
priv
=
(
void
*
)
disp
;
const
u32
shift
=
nv94_sor_dp_lane_map
(
priv
,
l
ane
);
struct
n
v50_disp_priv
*
priv
=
(
void
*
)
nouveau_disp
(
out
p
);
struct
n
ouveau_bios
*
bios
=
nouveau_bios
(
priv
)
;
const
u32
shift
=
nv94_sor_dp_lane_map
(
priv
,
l
n
);
const
u32
loff
=
nv94_sor_loff
(
outp
);
u32
addr
,
data
[
3
];
u8
ver
,
hdr
,
cnt
,
len
;
struct
nvbios_dpout
info
;
struct
nvbios_dpcfg
ocfg
;
addr
=
nvbios_dpout_match
(
bios
,
outp
->
hasht
,
outp
->
hashm
,
addr
=
nvbios_dpout_match
(
bios
,
outp
->
base
.
info
.
hasht
,
outp
->
base
.
info
.
hashm
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info
);
if
(
!
addr
)
return
-
ENODEV
;
addr
=
nvbios_dpcfg_match
(
bios
,
addr
,
0
,
swing
,
preem
,
addr
=
nvbios_dpcfg_match
(
bios
,
addr
,
0
,
vs
,
pe
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
ocfg
);
if
(
!
addr
)
return
-
EINVAL
;
...
...
@@ -124,13 +122,6 @@ nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
return
0
;
}
const
struct
nouveau_dp_func
nv94_sor_dp_func
=
{
.
pattern
=
nv94_sor_dp_pattern
,
.
lnk_ctl
=
nv94_sor_dp_lnk_ctl
,
.
drv_ctl
=
nv94_sor_dp_drv_ctl
,
};
struct
nvkm_output_dp_impl
nv94_sor_dp_impl
=
{
.
base
.
base
.
handle
=
DCB_OUTPUT_DP
,
...
...
@@ -140,4 +131,7 @@ nv94_sor_dp_impl = {
.
init
=
_nvkm_output_dp_init
,
.
fini
=
_nvkm_output_dp_fini
,
},
.
pattern
=
nv94_sor_dp_pattern
,
.
lnk_ctl
=
nv94_sor_dp_lnk_ctl
,
.
drv_ctl
=
nv94_sor_dp_drv_ctl
,
};
drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
View file @
3b52a1f9
...
...
@@ -33,15 +33,15 @@
#include "nv50.h"
static
inline
u32
nvd0_sor_soff
(
struct
dcb_output
*
outp
)
nvd0_sor_soff
(
struct
nvkm_output_dp
*
outp
)
{
return
(
ffs
(
outp
->
or
)
-
1
)
*
0x800
;
return
(
ffs
(
outp
->
base
.
info
.
or
)
-
1
)
*
0x800
;
}
static
inline
u32
nvd0_sor_loff
(
struct
dcb_output
*
outp
)
nvd0_sor_loff
(
struct
nvkm_output_dp
*
outp
)
{
return
nvd0_sor_soff
(
outp
)
+
!
(
outp
->
sorconf
.
link
&
1
)
*
0x80
;
return
nvd0_sor_soff
(
outp
)
+
!
(
outp
->
base
.
info
.
sorconf
.
link
&
1
)
*
0x80
;
}
static
inline
u32
...
...
@@ -52,20 +52,18 @@ nvd0_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
}
static
int
nvd0_sor_dp_pattern
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
pattern
)
nvd0_sor_dp_pattern
(
struct
nvkm_output_dp
*
outp
,
int
pattern
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
disp
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
nouveau_disp
(
outp
)
;
const
u32
loff
=
nvd0_sor_loff
(
outp
);
nv_mask
(
priv
,
0x61c110
+
loff
,
0x0f0f0f0f
,
0x01010101
*
pattern
);
return
0
;
}
static
int
nvd0_sor_dp_lnk_ctl
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
link_nr
,
int
link_bw
,
bool
enh_frame
)
nvd0_sor_dp_lnk_ctl
(
struct
nvkm_output_dp
*
outp
,
int
nr
,
int
bw
,
bool
ef
)
{
struct
nv50_disp_priv
*
priv
=
(
void
*
)
disp
;
struct
nv50_disp_priv
*
priv
=
(
void
*
)
nouveau_disp
(
outp
)
;
const
u32
soff
=
nvd0_sor_soff
(
outp
);
const
u32
loff
=
nvd0_sor_loff
(
outp
);
u32
dpctrl
=
0x00000000
;
...
...
@@ -73,12 +71,12 @@ nvd0_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
u32
lane
=
0
;
int
i
;
clksor
|=
link_
bw
<<
18
;
dpctrl
|=
((
1
<<
link_
nr
)
-
1
)
<<
16
;
if
(
e
nh_frame
)
clksor
|=
bw
<<
18
;
dpctrl
|=
((
1
<<
nr
)
-
1
)
<<
16
;
if
(
e
f
)
dpctrl
|=
0x00004000
;
for
(
i
=
0
;
i
<
link_
nr
;
i
++
)
for
(
i
=
0
;
i
<
nr
;
i
++
)
lane
|=
1
<<
(
nvd0_sor_dp_lane_map
(
priv
,
i
)
>>
3
);
nv_mask
(
priv
,
0x612300
+
soff
,
0x007c0000
,
clksor
);
...
...
@@ -88,24 +86,24 @@ nvd0_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
}
static
int
nvd0_sor_dp_drv_ctl
(
struct
nouveau_disp
*
disp
,
struct
dcb_output
*
outp
,
int
head
,
int
lane
,
int
swing
,
int
preem
)
nvd0_sor_dp_drv_ctl
(
struct
nvkm_output_dp
*
outp
,
int
ln
,
int
vs
,
int
pe
,
int
pc
)
{
struct
n
ouveau_bios
*
bios
=
nouveau_bios
(
dis
p
);
struct
n
v50_disp_priv
*
priv
=
(
void
*
)
disp
;
const
u32
shift
=
nvd0_sor_dp_lane_map
(
priv
,
l
ane
);
struct
n
v50_disp_priv
*
priv
=
(
void
*
)
nouveau_disp
(
out
p
);
struct
n
ouveau_bios
*
bios
=
nouveau_bios
(
priv
)
;
const
u32
shift
=
nvd0_sor_dp_lane_map
(
priv
,
l
n
);
const
u32
loff
=
nvd0_sor_loff
(
outp
);
u32
addr
,
data
[
3
];
u8
ver
,
hdr
,
cnt
,
len
;
struct
nvbios_dpout
info
;
struct
nvbios_dpcfg
ocfg
;
addr
=
nvbios_dpout_match
(
bios
,
outp
->
hasht
,
outp
->
hashm
,
addr
=
nvbios_dpout_match
(
bios
,
outp
->
base
.
info
.
hasht
,
outp
->
base
.
info
.
hashm
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
info
);
if
(
!
addr
)
return
-
ENODEV
;
addr
=
nvbios_dpcfg_match
(
bios
,
addr
,
0
,
swing
,
preem
,
addr
=
nvbios_dpcfg_match
(
bios
,
addr
,
0
,
vs
,
pe
,
&
ver
,
&
hdr
,
&
cnt
,
&
len
,
&
ocfg
);
if
(
!
addr
)
return
-
EINVAL
;
...
...
@@ -120,13 +118,6 @@ nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
return
0
;
}
const
struct
nouveau_dp_func
nvd0_sor_dp_func
=
{
.
pattern
=
nvd0_sor_dp_pattern
,
.
lnk_ctl
=
nvd0_sor_dp_lnk_ctl
,
.
drv_ctl
=
nvd0_sor_dp_drv_ctl
,
};
struct
nvkm_output_dp_impl
nvd0_sor_dp_impl
=
{
.
base
.
base
.
handle
=
DCB_OUTPUT_DP
,
...
...
@@ -136,4 +127,7 @@ nvd0_sor_dp_impl = {
.
init
=
_nvkm_output_dp_init
,
.
fini
=
_nvkm_output_dp_fini
,
},
.
pattern
=
nvd0_sor_dp_pattern
,
.
lnk_ctl
=
nvd0_sor_dp_lnk_ctl
,
.
drv_ctl
=
nvd0_sor_dp_drv_ctl
,
};
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