drm/nouveau/disp/sor/gf119-: add method to program mst payload information
authorBen Skeggs <bskeggs@redhat.com>
Fri, 4 Nov 2016 07:20:35 +0000 (17:20 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 7 Nov 2016 04:04:42 +0000 (14:04 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvif/cl5070.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c

index ed999fc..ae49dfd 100644 (file)
@@ -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;
index ef9ee0b..3c83a56 100644 (file)
@@ -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 **);
index 1a25067..c1158b2 100644 (file)
@@ -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;
index 520bf69..6ffdaa6 100644 (file)
@@ -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
index 37790b2..4cf8ad4 100644 (file)
@@ -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
index c44fa7e..81b788f 100644 (file)
@@ -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