summaryrefslogtreecommitdiff
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
commitcda6dbc15f04ca0810802efa5aa652ace7d2776a (patch)
tree89bd2883e0791250aba47b3df660d9eb684a7662
parent764694885c2ec383a9bb96d33984d687090f25a0 (diff)
downloadnouveau-cda6dbc15f04ca0810802efa5aa652ace7d2776a.tar.gz
disp/sor/gf119-: add method to program mst payload information
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drm/nouveau/include/nvif/cl5070.h10
-rw-r--r--drm/nouveau/nvkm/engine/disp/outpdp.h3
-rw-r--r--drm/nouveau/nvkm/engine/disp/rootnv50.c23
-rw-r--r--drm/nouveau/nvkm/engine/disp/sorgf119.c12
-rw-r--r--drm/nouveau/nvkm/engine/disp/sorgm107.c1
-rw-r--r--drm/nouveau/nvkm/engine/disp/sorgm200.c1
6 files changed, 50 insertions, 0 deletions
diff --git a/drm/nouveau/include/nvif/cl5070.h b/drm/nouveau/include/nvif/cl5070.h
index ed999fc38..ae49dfd1f 100644
--- a/drm/nouveau/include/nvif/cl5070.h
+++ b/drm/nouveau/include/nvif/cl5070.h
@@ -35,6 +35,7 @@ struct nv50_disp_mthd_v1 {
#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_SOR_DP_MST_VCPI 0x26
#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
__u8 method;
__u16 hasht;
@@ -97,6 +98,15 @@ struct nv50_disp_sor_dp_mst_link_v0 {
__u8 pad02[6];
};
+struct nv50_disp_sor_dp_mst_vcpi_v0 {
+ __u8 version;
+ __u8 pad01[1];
+ __u8 start_slot;
+ __u8 num_slots;
+ __u16 pbn;
+ __u16 aligned_pbn;
+};
+
struct nv50_disp_pior_pwr_v0 {
__u8 version;
__u8 state;
diff --git a/drm/nouveau/nvkm/engine/disp/outpdp.h b/drm/nouveau/nvkm/engine/disp/outpdp.h
index ef9ee0b77..3c83a561c 100644
--- a/drm/nouveau/nvkm/engine/disp/outpdp.h
+++ b/drm/nouveau/nvkm/engine/disp/outpdp.h
@@ -41,6 +41,8 @@ struct nvkm_output_dp_func {
int (*lnk_pwr)(struct nvkm_output_dp *, int nr);
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);
+ void (*vcpi)(struct nvkm_output_dp *, int head, u8 start_slot,
+ u8 num_slots, u16 pbn, u16 aligned_pbn);
};
int nvkm_output_dp_train(struct nvkm_output *, u32 rate);
@@ -63,6 +65,7 @@ int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
struct nvkm_output **);
int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int);
+void gf119_sor_dp_vcpi(struct nvkm_output_dp *, int, u8, u8, u16, u16);
int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
struct nvkm_output **);
diff --git a/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drm/nouveau/nvkm/engine/disp/rootnv50.c
index 1a2506767..c1158b22a 100644
--- a/drm/nouveau/nvkm/engine/disp/rootnv50.c
+++ b/drm/nouveau/nvkm/engine/disp/rootnv50.c
@@ -200,6 +200,29 @@ 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_VCPI: {
+ struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
+ union {
+ struct nv50_disp_sor_dp_mst_vcpi_v0 v0;
+ } *args = data;
+ int ret = -ENOSYS;
+ nvif_ioctl(object, "disp sor dp mst vcpi size %d\n", size);
+ if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+ nvif_ioctl(object, "disp sor dp mst vcpi vers %d "
+ "slot %02x/%02x pbn %04x/%04x\n",
+ args->v0.version, args->v0.start_slot,
+ args->v0.num_slots, args->v0.pbn,
+ args->v0.aligned_pbn);
+ if (!outpdp->func->vcpi)
+ return -ENODEV;
+ outpdp->func->vcpi(outpdp, head, args->v0.start_slot,
+ args->v0.num_slots, args->v0.pbn,
+ args->v0.aligned_pbn);
+ 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 520bf693d..6ffdaa65a 100644
--- a/drm/nouveau/nvkm/engine/disp/sorgf119.c
+++ b/drm/nouveau/nvkm/engine/disp/sorgf119.c
@@ -103,12 +103,24 @@ gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
return 0;
}
+void
+gf119_sor_dp_vcpi(struct nvkm_output_dp *outp, int head, u8 slot,
+ u8 slot_nr, u16 pbn, u16 aligned)
+{
+ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+ const u32 hoff = head * 0x800;
+
+ nvkm_mask(device, 0x616588 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
+ nvkm_mask(device, 0x61658c + hoff, 0xffffffff, (aligned << 16) | pbn);
+}
+
static const struct nvkm_output_dp_func
gf119_sor_dp_func = {
.pattern = gf119_sor_dp_pattern,
.lnk_pwr = g94_sor_dp_lnk_pwr,
.lnk_ctl = gf119_sor_dp_lnk_ctl,
.drv_ctl = gf119_sor_dp_drv_ctl,
+ .vcpi = gf119_sor_dp_vcpi,
};
int
diff --git a/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drm/nouveau/nvkm/engine/disp/sorgm107.c
index 37790b261..4cf8ad4d1 100644
--- a/drm/nouveau/nvkm/engine/disp/sorgm107.c
+++ b/drm/nouveau/nvkm/engine/disp/sorgm107.c
@@ -43,6 +43,7 @@ gm107_sor_dp_func = {
.lnk_pwr = g94_sor_dp_lnk_pwr,
.lnk_ctl = gf119_sor_dp_lnk_ctl,
.drv_ctl = gf119_sor_dp_drv_ctl,
+ .vcpi = gf119_sor_dp_vcpi,
};
int
diff --git a/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drm/nouveau/nvkm/engine/disp/sorgm200.c
index c44fa7ea6..81b788fa6 100644
--- a/drm/nouveau/nvkm/engine/disp/sorgm200.c
+++ b/drm/nouveau/nvkm/engine/disp/sorgm200.c
@@ -120,6 +120,7 @@ gm200_sor_dp_func = {
.lnk_pwr = gm200_sor_dp_lnk_pwr,
.lnk_ctl = gf119_sor_dp_lnk_ctl,
.drv_ctl = gm200_sor_dp_drv_ctl,
+ .vcpi = gf119_sor_dp_vcpi,
};
int