Commit f2a40513 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/disp/sor/gf119-: add method to control mst enable



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 1f8711ba
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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;
+12 −10
Original line number Diff line number Diff line
@@ -203,6 +203,7 @@ 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);
		if (!outpdp->lt.mst) {
			struct nvbios_init init = {
				.subdev = subdev,
				.bios = subdev->device->bios,
@@ -216,6 +217,7 @@ gf119_disp_intr_unk2_0(struct nv50_disp *disp, int head)
			atomic_set(&outpdp->lt.done, 0);
		}
	}
}

static void
gf119_disp_intr_unk2_1(struct nv50_disp *disp, int head)
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ struct nvkm_output_dp {
	struct mutex mutex;
	struct {
		atomic_t done;
		bool mst;
	} lt;
};

+20 −0
Original line number Diff line number Diff line
@@ -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;
+3 −1
Original line number Diff line number Diff line
@@ -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;
}