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

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
......@@ -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);
}
#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
......@@ -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)
......
......@@ -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");
}
......
......@@ -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 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
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) {
......
......@@ -29,9 +29,8 @@ struct nvkm_output_dp {
bool present;
u8 dpcd[16];
struct mutex mutex;
struct {
struct work_struct work;
wait_queue_head_t wait;
atomic_t done;
} lt;
};
......@@ -43,7 +42,7 @@ struct nvkm_output_dp_func {
int (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc);
};
int nvkm_output_dp_train(struct nvkm_output *, u32 rate, bool wait);
int nvkm_output_dp_train(struct nvkm_output *, u32 rate);
int nvkm_output_dp_ctor(const struct nvkm_output_dp_func *, struct nvkm_disp *,
int index, struct dcb_output *, struct nvkm_i2c_aux *,
......
......@@ -173,7 +173,7 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
return 0;
} else
if (args->v0.state != 0) {
nvkm_output_dp_train(&outpdp->base, 0, true);
nvkm_output_dp_train(&outpdp->base, 0);
return 0;
}
} else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment