summaryrefslogtreecommitdiff
path: root/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2016-11-04 17:20:35 +1000
committerBen Skeggs <bskeggs@redhat.com>2016-11-07 10:06:20 +1000
commit764694885c2ec383a9bb96d33984d687090f25a0 (patch)
treefe7f41c2c3180b2c481f22f575d716d94d3e42b8 /drm
parent87f93eb1a9e54a278415cff6f750b231de4d9952 (diff)
downloadnouveau-764694885c2ec383a9bb96d33984d687090f25a0.tar.gz
disp/sor/gf119-: add method to control mst enable
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drm')
-rw-r--r--drm/nouveau/include/nvif/cl5070.h7
-rw-r--r--drm/nouveau/nvkm/engine/disp/gf119.c22
-rw-r--r--drm/nouveau/nvkm/engine/disp/outpdp.h1
-rw-r--r--drm/nouveau/nvkm/engine/disp/rootnv50.c20
-rw-r--r--drm/nouveau/nvkm/engine/disp/sorgf119.c4
5 files changed, 43 insertions, 11 deletions
diff --git a/drm/nouveau/include/nvif/cl5070.h b/drm/nouveau/include/nvif/cl5070.h
index d15c296b5..ed999fc38 100644
--- a/drm/nouveau/include/nvif/cl5070.h
+++ b/drm/nouveau/include/nvif/cl5070.h
@@ -34,6 +34,7 @@ struct nv50_disp_mthd_v1 {
#define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22
#define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23
#define NV50_DISP_MTHD_V1_SOR_DP_PWR 0x24
+#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25
#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
__u8 method;
__u16 hasht;
@@ -90,6 +91,12 @@ struct nv50_disp_sor_dp_pwr_v0 {
__u8 pad02[6];
};
+struct nv50_disp_sor_dp_mst_link_v0 {
+ __u8 version;
+ __u8 state;
+ __u8 pad02[6];
+};
+
struct nv50_disp_pior_pwr_v0 {
__u8 version;
__u8 state;
diff --git a/drm/nouveau/nvkm/engine/disp/gf119.c b/drm/nouveau/nvkm/engine/disp/gf119.c
index 0face69d6..fd9424101 100644
--- a/drm/nouveau/nvkm/engine/disp/gf119.c
+++ b/drm/nouveau/nvkm/engine/disp/gf119.c
@@ -203,17 +203,19 @@ gf119_disp_intr_unk2_0(struct nv50_disp *disp, int head)
/* see note in nv50_disp_intr_unk20_0() */
if (outp && outp->info.type == DCB_OUTPUT_DP) {
struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
- struct nvbios_init init = {
- .subdev = subdev,
- .bios = subdev->device->bios,
- .outp = &outp->info,
- .crtc = head,
- .offset = outpdp->info.script[4],
- .execute = 1,
- };
+ if (!outpdp->lt.mst) {
+ struct nvbios_init init = {
+ .subdev = subdev,
+ .bios = subdev->device->bios,
+ .outp = &outp->info,
+ .crtc = head,
+ .offset = outpdp->info.script[4],
+ .execute = 1,
+ };
- nvbios_exec(&init);
- atomic_set(&outpdp->lt.done, 0);
+ nvbios_exec(&init);
+ atomic_set(&outpdp->lt.done, 0);
+ }
}
}
diff --git a/drm/nouveau/nvkm/engine/disp/outpdp.h b/drm/nouveau/nvkm/engine/disp/outpdp.h
index 7b63d9737..ef9ee0b77 100644
--- a/drm/nouveau/nvkm/engine/disp/outpdp.h
+++ b/drm/nouveau/nvkm/engine/disp/outpdp.h
@@ -32,6 +32,7 @@ struct nvkm_output_dp {
struct mutex mutex;
struct {
atomic_t done;
+ bool mst;
} lt;
};
diff --git a/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drm/nouveau/nvkm/engine/disp/rootnv50.c
index e9548e4fb..1a2506767 100644
--- a/drm/nouveau/nvkm/engine/disp/rootnv50.c
+++ b/drm/nouveau/nvkm/engine/disp/rootnv50.c
@@ -180,6 +180,26 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
return ret;
}
break;
+ case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: {
+ struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
+ union {
+ struct nv50_disp_sor_dp_mst_link_v0 v0;
+ } *args = data;
+ int ret = -ENOSYS;
+ nvif_ioctl(object, "disp sor dp mst link size %d\n", size);
+ if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+ nvif_ioctl(object, "disp sor dp mst link vers %d state %d\n",
+ args->v0.version, args->v0.state);
+ if (outpdp->lt.mst != !!args->v0.state) {
+ outpdp->lt.mst = !!args->v0.state;
+ atomic_set(&outpdp->lt.done, 0);
+ nvkm_output_dp_train(&outpdp->base, 0);
+ }
+ return 0;
+ } else
+ return ret;
+ }
+ break;
case NV50_DISP_MTHD_V1_PIOR_PWR:
if (!func->pior.power)
return -ENODEV;
diff --git a/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drm/nouveau/nvkm/engine/disp/sorgf119.c
index 49bd5da19..520bf693d 100644
--- a/drm/nouveau/nvkm/engine/disp/sorgf119.c
+++ b/drm/nouveau/nvkm/engine/disp/sorgf119.c
@@ -56,11 +56,13 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
clksor |= bw << 18;
dpctrl |= ((1 << nr) - 1) << 16;
+ if (outp->lt.mst)
+ dpctrl |= 0x40000000;
if (ef)
dpctrl |= 0x00004000;
nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
- nvkm_mask(device, 0x61c10c + loff, 0x001f4000, dpctrl);
+ nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
return 0;
}