Browse Source

drm/nouveau/disp/sor/gf119-: add method to program mst payload information

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Ben Skeggs 8 years ago
parent
commit
4cddeb9b31

+ 10 - 0
drivers/gpu/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;

+ 3 - 0
drivers/gpu/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 **);

+ 23 - 0
drivers/gpu/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;

+ 12 - 0
drivers/gpu/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

+ 1 - 0
drivers/gpu/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

+ 1 - 0
drivers/gpu/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