Commit 1f8711ba authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/disp/dp: remove workqueue for link training



There haven't been any callers from an atomic context for a while now,
so let's remove the extra complexity.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent a3f8a41f
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -319,9 +319,8 @@ static const struct dp_rates {
};

void
nvkm_dp_train(struct work_struct *w)
nvkm_dp_train(struct nvkm_output_dp *outp)
{
	struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work);
	struct nv50_disp *disp = nv50_disp(outp->base.disp);
	const struct dp_rates *cfg = nvkm_dp_rates;
	struct dp_state _dp = {
@@ -353,9 +352,6 @@ nvkm_dp_train(struct work_struct *w)
	}
	cfg--;

	/* disable link interrupt handling during link training */
	nvkm_notify_put(&outp->irq);

	/* ensure sink is not in a low-power state */
	if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) {
		if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
@@ -400,9 +396,6 @@ nvkm_dp_train(struct work_struct *w)

	dp_link_train_fini(dp);

	/* signal completion and enable link interrupt handling */
	OUTP_DBG(&outp->base, "training complete");
	atomic_set(&outp->lt.done, 1);
	wake_up(&outp->lt.wait);
	nvkm_notify_get(&outp->irq);
}
+2 −2
Original line number Diff line number Diff line
#ifndef __NVKM_DISP_DPORT_H__
#define __NVKM_DISP_DPORT_H__
#include <core/os.h>
struct nvkm_output_dp;

/* DPCD Receiver Capabilities */
#define DPCD_RC00_DPCD_REV                                              0x00000
@@ -77,5 +77,5 @@
#define DPCD_SC00_SET_POWER_D0                                             0x01
#define DPCD_SC00_SET_POWER_D3                                             0x03

void nvkm_dp_train(struct work_struct *);
void nvkm_dp_train(struct nvkm_output_dp *);
#endif
+1 −1
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ gf119_disp_intr_unk2_2(struct nv50_disp *disp, int head)
			break;
		}

		if (nvkm_output_dp_train(outp, pclk, true))
		if (nvkm_output_dp_train(outp, pclk))
			OUTP_ERR(outp, "link not trained before attach");
	} else {
		if (disp->func->sor.magic)
+1 −1
Original line number Diff line number Diff line
@@ -779,7 +779,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp *disp, int head)
			break;
		}

		if (nvkm_output_dp_train(outp, datarate / soff, true))
		if (nvkm_output_dp_train(outp, datarate / soff))
			OUTP_ERR(outp, "link not trained before attach");
	}

+12 −21
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
#include <nvif/event.h>

int
nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
nvkm_output_dp_train(struct nvkm_output *base, u32 datarate)
{
	struct nvkm_output_dp *outp = nvkm_output_dp(base);
	bool retrain = true;
@@ -39,6 +39,8 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
	u32 linkrate;
	int ret, i;

	mutex_lock(&outp->mutex);

	/* check that the link is trained at a high enough rate */
	ret = nvkm_rdaux(outp->aux, DPCD_LC00_LINK_BW_SET, link, 2);
	if (ret) {
@@ -88,19 +90,10 @@ done:
			outp->dpcd[DPCD_RC02] =
				outp->base.info.dpconf.link_nr;
		}
		atomic_set(&outp->lt.done, 0);
		schedule_work(&outp->lt.work);
	} else {
		nvkm_notify_get(&outp->irq);
	}

	if (wait) {
		if (!wait_event_timeout(outp->lt.wait,
					atomic_read(&outp->lt.done),
					msecs_to_jiffies(2000)))
			ret = -ETIMEDOUT;
		nvkm_dp_train(outp);
	}

	mutex_unlock(&outp->mutex);
	return ret;
}

@@ -118,7 +111,7 @@ nvkm_output_dp_enable(struct nvkm_output_dp *outp, bool enable)

		if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dpcd,
				sizeof(outp->dpcd))) {
			nvkm_output_dp_train(&outp->base, 0, true);
			nvkm_output_dp_train(&outp->base, 0);
			return;
		}
	}
@@ -165,10 +158,10 @@ nvkm_output_dp_irq(struct nvkm_notify *notify)
	};

	OUTP_DBG(&outp->base, "IRQ: %d", line->mask);
	nvkm_output_dp_train(&outp->base, 0, true);
	nvkm_output_dp_train(&outp->base, 0);

	nvkm_event_send(&disp->hpd, rep.mask, conn->index, &rep, sizeof(rep));
	return NVKM_NOTIFY_DROP;
	return NVKM_NOTIFY_KEEP;
}

static void
@@ -177,7 +170,6 @@ nvkm_output_dp_fini(struct nvkm_output *base)
	struct nvkm_output_dp *outp = nvkm_output_dp(base);
	nvkm_notify_put(&outp->hpd);
	nvkm_notify_put(&outp->irq);
	flush_work(&outp->lt.work);
	nvkm_output_dp_enable(outp, false);
}

@@ -187,6 +179,7 @@ nvkm_output_dp_init(struct nvkm_output *base)
	struct nvkm_output_dp *outp = nvkm_output_dp(base);
	nvkm_notify_put(&outp->base.conn->hpd);
	nvkm_output_dp_enable(outp, true);
	nvkm_notify_get(&outp->irq);
	nvkm_notify_get(&outp->hpd);
}

@@ -238,11 +231,6 @@ nvkm_output_dp_ctor(const struct nvkm_output_dp_func *func,
	OUTP_DBG(&outp->base, "bios dp %02x %02x %02x %02x",
		 outp->version, hdr, cnt, len);

	/* link training */
	INIT_WORK(&outp->lt.work, nvkm_dp_train);
	init_waitqueue_head(&outp->lt.wait);
	atomic_set(&outp->lt.done, 0);

	/* link maintenance */
	ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_irq, true,
			       &(struct nvkm_i2c_ntfy_req) {
@@ -257,6 +245,9 @@ nvkm_output_dp_ctor(const struct nvkm_output_dp_func *func,
		return ret;
	}

	mutex_init(&outp->mutex);
	atomic_set(&outp->lt.done, 0);

	/* hotplug detect, replaces gpio-based mechanism with aux events */
	ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_hpd, true,
			       &(struct nvkm_i2c_ntfy_req) {
Loading