Skip to content

Commit 8134437

Browse files
author
Ben Skeggs
committed
drm/nouveau/disp: move DP link config into acquire
Aside from fixing MST->SST switching (KMS never turned off MST link config), this should preserve existing behaviour for the moment, but provide a path for the KMS driver to have more explicit control of the DP link, which has been requested by Lyude. More research into modeset/supervisor interactions is needed before we can have fully explicit control from the KMS driver. Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
1 parent a9f5d77 commit 8134437

File tree

9 files changed

+65
-60
lines changed

9 files changed

+65
-60
lines changed

drivers/gpu/drm/nouveau/dispnv50/disp.c

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ nv50_msto_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *st
10141014

10151015
if (!mstm->links++) {
10161016
/*XXX: MST audio. */
1017-
nvif_outp_acquire_dp(&mstm->outp->outp, false);
1017+
nvif_outp_acquire_dp(&mstm->outp->outp, mstm->outp->dp.dpcd, 0, 0, false, true);
10181018
}
10191019

10201020
if (mstm->outp->outp.or.link & 1)
@@ -1380,26 +1380,6 @@ nv50_mstm_remove(struct nv50_mstm *mstm)
13801380
drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, false);
13811381
}
13821382

1383-
static int
1384-
nv50_mstm_enable(struct nv50_mstm *mstm, int state)
1385-
{
1386-
struct nouveau_encoder *outp = mstm->outp;
1387-
struct {
1388-
struct nv50_disp_mthd_v1 base;
1389-
struct nv50_disp_sor_dp_mst_link_v0 mst;
1390-
} args = {
1391-
.base.version = 1,
1392-
.base.method = NV50_DISP_MTHD_V1_SOR_DP_MST_LINK,
1393-
.base.hasht = outp->dcb->hasht,
1394-
.base.hashm = outp->dcb->hashm,
1395-
.mst.state = state,
1396-
};
1397-
struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev);
1398-
struct nvif_object *disp = &drm->display->disp.object;
1399-
1400-
return nvif_mthd(disp, 0, &args, sizeof(args));
1401-
}
1402-
14031383
int
14041384
nv50_mstm_detect(struct nouveau_encoder *outp)
14051385
{
@@ -1420,15 +1400,9 @@ nv50_mstm_detect(struct nouveau_encoder *outp)
14201400
return ret;
14211401

14221402
/* And start enabling */
1423-
ret = nv50_mstm_enable(mstm, true);
1424-
if (ret)
1425-
return ret;
1426-
14271403
ret = drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, true);
1428-
if (ret) {
1429-
nv50_mstm_enable(mstm, false);
1404+
if (ret)
14301405
return ret;
1431-
}
14321406

14331407
mstm->is_mst = true;
14341408
return 1;
@@ -1660,7 +1634,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
16601634
nvif_outp_acquire_lvds(&nv_encoder->outp, lvds_dual, lvds_8bpc);
16611635
break;
16621636
case DCB_OUTPUT_DP:
1663-
nvif_outp_acquire_dp(&nv_encoder->outp, hda);
1637+
nvif_outp_acquire_dp(&nv_encoder->outp, nv_encoder->dp.dpcd, 0, 0, hda, false);
16641638
depth = nv50_dp_bpc_to_depth(asyh->or.bpc);
16651639

16661640
if (nv_encoder->outp.or.link & 1)
@@ -1858,7 +1832,7 @@ nv50_pior_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *st
18581832
break;
18591833
case DCB_OUTPUT_DP:
18601834
ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, PROTOCOL, EXT_TMDS_ENC);
1861-
nvif_outp_acquire_dp(&nv_encoder->outp, false);
1835+
nvif_outp_acquire_dp(&nv_encoder->outp, nv_encoder->dp.dpcd, 0, 0, false, false);
18621836
break;
18631837
default:
18641838
BUG();

drivers/gpu/drm/nouveau/include/nvif/cl5070.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,13 @@ struct nv50_disp_scanoutpos_v0 {
2828

2929
struct nv50_disp_mthd_v1 {
3030
__u8 version;
31-
#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25
3231
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
3332
__u8 method;
3433
__u16 hasht;
3534
__u16 hashm;
3635
__u8 pad06[2];
3736
};
3837

39-
struct nv50_disp_sor_dp_mst_link_v0 {
40-
__u8 version;
41-
__u8 state;
42-
__u8 pad02[6];
43-
};
44-
4538
struct nv50_disp_sor_dp_mst_vcpi_v0 {
4639
__u8 version;
4740
__u8 pad01[1];

drivers/gpu/drm/nouveau/include/nvif/if0012.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,12 @@ union nvif_outp_acquire_args {
5555
__u8 pad02[6];
5656
} lvds;
5757
struct {
58+
__u8 link_nr; /* 0 = highest possible. */
59+
__u8 link_bw; /* 0 = highest possible, DP BW code otherwise. */
5860
__u8 hda;
59-
__u8 pad01[7];
61+
__u8 mst;
62+
__u8 pad04[4];
63+
__u8 dpcd[16];
6064
} dp;
6165
};
6266
} v0;

drivers/gpu/drm/nouveau/include/nvif/outp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
2121
int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
2222
bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool hda);
2323
int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
24-
int nvif_outp_acquire_dp(struct nvif_outp *, bool hda);
24+
int nvif_outp_acquire_dp(struct nvif_outp *, u8 dpcd[16],
25+
int link_nr, int link_bw, bool hda, bool mst);
2526
void nvif_outp_release(struct nvif_outp *);
2627
int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct nvif_outp_infoframe_v0 *, u32 size);
2728
int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);

drivers/gpu/drm/nouveau/nvif/outp.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,22 @@ nvif_outp_acquire(struct nvif_outp *outp, u8 proto, struct nvif_outp_acquire_v0
8484
}
8585

8686
int
87-
nvif_outp_acquire_dp(struct nvif_outp *outp, bool hda)
87+
nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[16],
88+
int link_nr, int link_bw, bool hda, bool mst)
8889
{
8990
struct nvif_outp_acquire_v0 args;
9091
int ret;
9192

93+
args.dp.link_nr = link_nr;
94+
args.dp.link_bw = link_bw;
9295
args.dp.hda = hda;
96+
args.dp.mst = mst;
97+
memcpy(args.dp.dpcd, dpcd, sizeof(args.dp.dpcd));
9398

9499
ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_DP, &args);
95100
NVIF_ERRON(ret, &outp->object,
96-
"[ACQUIRE proto:DP hda:%d] or:%d link:%d", args.dp.hda, args.or, args.link);
101+
"[ACQUIRE proto:DP link_nr:%d link_bw:%02x hda:%d mst:%d] or:%d link:%d",
102+
args.dp.link_nr, args.dp.link_bw, args.dp.hda, args.dp.mst, args.or, args.link);
97103
return ret;
98104
}
99105

drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ nvkm_dp_train_links(struct nvkm_outp *outp, int rate)
287287
u8 sink[2], data;
288288
int ret;
289289

290-
OUTP_DBG(outp, "training %d x %d MB/s", ior->dp.nr, ior->dp.bw * 27);
290+
OUTP_DBG(outp, "training %dx%02x", ior->dp.nr, ior->dp.bw);
291291

292292
/* Intersect misc. capabilities of the OR and sink. */
293293
if (disp->engine.subdev.device->chipset < 0x110)
@@ -455,6 +455,21 @@ nvkm_dp_train(struct nvkm_outp *outp, u32 dataKBps)
455455
/* Link training. */
456456
OUTP_DBG(outp, "training");
457457
nvkm_dp_train_init(outp);
458+
459+
/* Validate and train at configuration requested (if any) on ACQUIRE. */
460+
if (outp->dp.lt.nr) {
461+
for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) {
462+
for (rate = 0; nr == outp->dp.lt.nr && rate < outp->dp.rates; rate++) {
463+
if (outp->dp.rate[rate].rate / 27000 == outp->dp.lt.bw) {
464+
ior->dp.bw = outp->dp.rate[rate].rate / 27000;
465+
ior->dp.nr = nr;
466+
ret = nvkm_dp_train_links(outp, rate);
467+
}
468+
}
469+
}
470+
}
471+
472+
/* Otherwise, loop through all valid link configurations that support the data rate. */
458473
for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) {
459474
for (rate = 0; ret < 0 && rate < outp->dp.rates; rate++) {
460475
if (outp->dp.rate[rate].rate * nr >= dataKBps || WARN_ON(!ior->dp.nr)) {
@@ -465,6 +480,8 @@ nvkm_dp_train(struct nvkm_outp *outp, u32 dataKBps)
465480
}
466481
}
467482
}
483+
484+
/* Finish up. */
468485
nvkm_dp_train_fini(outp);
469486
if (ret < 0)
470487
OUTP_ERR(outp, "training failed");

drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct nvkm_outp {
5454
struct mutex mutex;
5555
struct {
5656
atomic_t done;
57+
u8 nr;
58+
u8 bw;
5759
bool mst;
5860
} lt;
5961
} dp;

drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
9191
}
9292

9393
switch (mthd * !!outp) {
94-
case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: {
95-
union {
96-
struct nv50_disp_sor_dp_mst_link_v0 v0;
97-
} *args = data;
98-
int ret = -ENOSYS;
99-
nvif_ioctl(object, "disp sor dp mst link size %d\n", size);
100-
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
101-
nvif_ioctl(object, "disp sor dp mst link vers %d state %d\n",
102-
args->v0.version, args->v0.state);
103-
outp->dp.lt.mst = !!args->v0.state;
104-
return 0;
105-
} else
106-
return ret;
107-
}
108-
break;
10994
case NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI: {
11095
union {
11196
struct nv50_disp_sor_dp_mst_vcpi_v0 v0;

drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,23 @@ nvkm_uoutp_mthd_release(struct nvkm_outp *outp, void *argv, u32 argc)
100100
return 0;
101101
}
102102

103+
static int
104+
nvkm_uoutp_mthd_acquire_dp(struct nvkm_outp *outp, u8 dpcd[16],
105+
u8 link_nr, u8 link_bw, bool hda, bool mst)
106+
{
107+
int ret;
108+
109+
ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, hda);
110+
if (ret)
111+
return ret;
112+
113+
memcpy(outp->dp.dpcd, dpcd, sizeof(outp->dp.dpcd));
114+
outp->dp.lt.nr = link_nr;
115+
outp->dp.lt.bw = link_bw;
116+
outp->dp.lt.mst = mst;
117+
return 0;
118+
}
119+
103120
static int
104121
nvkm_uoutp_mthd_acquire_tmds(struct nvkm_outp *outp, u8 head, u8 hdmi, u8 hdmi_max_ac_packet,
105122
u8 hdmi_rekey, u8 hdmi_scdc, u8 hdmi_hda)
@@ -152,6 +169,8 @@ nvkm_uoutp_mthd_acquire(struct nvkm_outp *outp, void *argv, u32 argc)
152169

153170
if (argc != sizeof(args->v0) || args->v0.version != 0)
154171
return -ENOSYS;
172+
if (outp->ior)
173+
return -EBUSY;
155174

156175
switch (args->v0.proto) {
157176
case NVIF_OUTP_ACQUIRE_V0_RGB_CRT:
@@ -165,12 +184,16 @@ nvkm_uoutp_mthd_acquire(struct nvkm_outp *outp, void *argv, u32 argc)
165184
args->v0.tmds.hdmi_scdc,
166185
args->v0.tmds.hdmi_hda);
167186
break;
168-
case NVIF_OUTP_ACQUIRE_V0_DP:
169-
ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, args->v0.dp.hda);
170-
break;
171187
case NVIF_OUTP_ACQUIRE_V0_LVDS:
172188
ret = nvkm_uoutp_mthd_acquire_lvds(outp, args->v0.lvds.dual, args->v0.lvds.bpc8);
173189
break;
190+
case NVIF_OUTP_ACQUIRE_V0_DP:
191+
ret = nvkm_uoutp_mthd_acquire_dp(outp, args->v0.dp.dpcd,
192+
args->v0.dp.link_nr,
193+
args->v0.dp.link_bw,
194+
args->v0.dp.hda != 0,
195+
args->v0.dp.mst != 0);
196+
break;
174197
default:
175198
ret = -EINVAL;
176199
break;

0 commit comments

Comments
 (0)