Commit 9648da5a authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/disp/dp: determine link bandwidth requirements from head state



Training/Untraining will be hooked up to the routing logic, which
doesn't allow us to pass in a data rate.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 6c22ea37
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
 */
#include "dp.h"
#include "conn.h"
#include "head.h"
#include "ior.h"

#include <subdev/bios.h>
@@ -419,19 +420,28 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
}

int
nvkm_output_dp_train(struct nvkm_outp *outp, u32 datakbps)
nvkm_output_dp_train(struct nvkm_outp *outp, u32 unused)
{
	struct nvkm_dp *dp = nvkm_dp(outp);
	struct nvkm_ior *ior = dp->outp.ior;
	struct nvkm_head *head;
	bool retrain = true;
	u32 linkKBps;
	u32 datakbps = 0;
	u32 dataKBps;
	u32 linkKBps;
	u8  stat[3];
	int ret, i;

	mutex_lock(&dp->mutex);

	/* Check that link configuration meets current requirements. */
	list_for_each_entry(head, &outp->disp->head, head) {
		if (ior->asy.head & (1 << head->id)) {
			u32 khz = (head->asy.hz >> ior->asy.rgdiv) / 1000;
			datakbps += khz * head->asy.or.depth;
		}
	}

	linkKBps = ior->dp.bw * 27000 * ior->dp.nr;
	dataKBps = DIV_ROUND_UP(datakbps, 8);
	OUTP_DBG(&dp->outp, "data %d KB/s link %d KB/s mst %d->%d",
+6 −0
Original line number Diff line number Diff line
@@ -18,6 +18,12 @@ struct nvkm_head {
		u16 vsynce;
		u16 vblanke;
		u16 vblanks;
		u32 hz;

		/* Prior to GF119, these are set by the OR. */
		struct {
			u8 depth;
		} or;
	} arm, asy;
};

+13 −0
Original line number Diff line number Diff line
@@ -58,6 +58,19 @@ gf119_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
	data = nvkm_rd32(device, 0x640420 + hoff);
	state->vblanks = (data & 0xffff0000) >> 16;
	state->hblanks = (data & 0x0000ffff);
	state->hz = nvkm_rd32(device, 0x640450 + hoff);

	data = nvkm_rd32(device, 0x640404 + hoff);
	switch ((data & 0x000003c0) >> 6) {
	case 6: state->or.depth = 30; break;
	case 5: state->or.depth = 24; break;
	case 2: state->or.depth = 18; break;
	case 0: state->or.depth = 18; break; /*XXX: "default" */
	default:
		state->or.depth = 18;
		WARN_ON(1);
		break;
	}
}

static const struct nvkm_head_func
+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ nv50_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
	data = nvkm_rd32(device, 0x610b00 + hoff);
	state->vsynce = (data & 0xffff0000) >> 16;
	state->hsynce = (data & 0x0000ffff);
	state->hz = (nvkm_rd32(device, 0x610ad0 + hoff) & 0x003fffff) * 1000;
}

static const struct nvkm_head_func
+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ nv50_ior_base(struct nvkm_ior *ior)
void nv50_dac_power(struct nvkm_ior *, bool, bool, bool, bool, bool);
int nv50_dac_sense(struct nvkm_ior *, u32);

void nv50_pior_depth(struct nvkm_ior *, struct nvkm_ior_state *, u32 ctrl);

static inline u32
nv50_sor_link(struct nvkm_ior *ior)
{
Loading