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 { ...@@ -319,9 +319,8 @@ static const struct dp_rates {
}; };
void 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); struct nv50_disp *disp = nv50_disp(outp->base.disp);
const struct dp_rates *cfg = nvkm_dp_rates; const struct dp_rates *cfg = nvkm_dp_rates;
struct dp_state _dp = { struct dp_state _dp = {
...@@ -353,9 +352,6 @@ nvkm_dp_train(struct work_struct *w) ...@@ -353,9 +352,6 @@ nvkm_dp_train(struct work_struct *w)
} }
cfg--; cfg--;
/* disable link interrupt handling during link training */
nvkm_notify_put(&outp->irq);
/* ensure sink is not in a low-power state */ /* ensure sink is not in a low-power state */
if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) { if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) {
if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) { if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
...@@ -400,9 +396,6 @@ nvkm_dp_train(struct work_struct *w) ...@@ -400,9 +396,6 @@ nvkm_dp_train(struct work_struct *w)
dp_link_train_fini(dp); dp_link_train_fini(dp);
/* signal completion and enable link interrupt handling */
OUTP_DBG(&outp->base, "training complete"); OUTP_DBG(&outp->base, "training complete");
atomic_set(&outp->lt.done, 1); atomic_set(&outp->lt.done, 1);
wake_up(&outp->lt.wait);
nvkm_notify_get(&outp->irq);
} }
#ifndef __NVKM_DISP_DPORT_H__ #ifndef __NVKM_DISP_DPORT_H__
#define __NVKM_DISP_DPORT_H__ #define __NVKM_DISP_DPORT_H__
#include <core/os.h> struct nvkm_output_dp;
/* DPCD Receiver Capabilities */ /* DPCD Receiver Capabilities */
#define DPCD_RC00_DPCD_REV 0x00000 #define DPCD_RC00_DPCD_REV 0x00000
...@@ -77,5 +77,5 @@ ...@@ -77,5 +77,5 @@
#define DPCD_SC00_SET_POWER_D0 0x01 #define DPCD_SC00_SET_POWER_D0 0x01
#define DPCD_SC00_SET_POWER_D3 0x03 #define DPCD_SC00_SET_POWER_D3 0x03
void nvkm_dp_train(struct work_struct *); void nvkm_dp_train(struct nvkm_output_dp *);
#endif #endif
...@@ -314,7 +314,7 @@ gf119_disp_intr_unk2_2(struct nv50_disp *disp, int head) ...@@ -314,7 +314,7 @@ gf119_disp_intr_unk2_2(struct nv50_disp *disp, int head)
break; break;
} }
if (nvkm_output_dp_train(outp, pclk, true)) if (nvkm_output_dp_train(outp, pclk))
OUTP_ERR(outp, "link not trained before attach"); OUTP_ERR(outp, "link not trained before attach");
} else { } else {
if (disp->func->sor.magic) if (disp->func->sor.magic)
......
...@@ -779,7 +779,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp *disp, int head) ...@@ -779,7 +779,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp *disp, int head)
break; 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"); OUTP_ERR(outp, "link not trained before attach");
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <nvif/event.h> #include <nvif/event.h>
int 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); struct nvkm_output_dp *outp = nvkm_output_dp(base);
bool retrain = true; bool retrain = true;
...@@ -39,6 +39,8 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) ...@@ -39,6 +39,8 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
u32 linkrate; u32 linkrate;
int ret, i; int ret, i;
mutex_lock(&outp->mutex);
/* check that the link is trained at a high enough rate */ /* check that the link is trained at a high enough rate */
ret = nvkm_rdaux(outp->aux, DPCD_LC00_LINK_BW_SET, link, 2); ret = nvkm_rdaux(outp->aux, DPCD_LC00_LINK_BW_SET, link, 2);
if (ret) { if (ret) {
...@@ -88,19 +90,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) ...@@ -88,19 +90,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
outp->dpcd[DPCD_RC02] = outp->dpcd[DPCD_RC02] =
outp->base.info.dpconf.link_nr; outp->base.info.dpconf.link_nr;
} }
atomic_set(&outp->lt.done, 0); nvkm_dp_train(outp);
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;
} }
mutex_unlock(&outp->mutex);
return ret; return ret;
} }
...@@ -118,7 +111,7 @@ nvkm_output_dp_enable(struct nvkm_output_dp *outp, bool enable) ...@@ -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, if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dpcd,
sizeof(outp->dpcd))) { sizeof(outp->dpcd))) {
nvkm_output_dp_train(&outp->base, 0, true); nvkm_output_dp_train(&outp->base, 0);
return; return;
} }
} }
...@@ -165,10 +158,10 @@ nvkm_output_dp_irq(struct nvkm_notify *notify) ...@@ -165,10 +158,10 @@ nvkm_output_dp_irq(struct nvkm_notify *notify)
}; };
OUTP_DBG(&outp->base, "IRQ: %d", line->mask); 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)); nvkm_event_send(&disp->hpd, rep.mask, conn->index, &rep, sizeof(rep));
return NVKM_NOTIFY_DROP; return NVKM_NOTIFY_KEEP;
} }
static void static void
...@@ -177,7 +170,6 @@ nvkm_output_dp_fini(struct nvkm_output *base) ...@@ -177,7 +170,6 @@ nvkm_output_dp_fini(struct nvkm_output *base)
struct nvkm_output_dp *outp = nvkm_output_dp(base); struct nvkm_output_dp *outp = nvkm_output_dp(base);
nvkm_notify_put(&outp->hpd); nvkm_notify_put(&outp->hpd);
nvkm_notify_put(&outp->irq); nvkm_notify_put(&outp->irq);
flush_work(&outp->lt.work);
nvkm_output_dp_enable(outp, false); nvkm_output_dp_enable(outp, false);
} }
...@@ -187,6 +179,7 @@ nvkm_output_dp_init(struct nvkm_output *base) ...@@ -187,6 +179,7 @@ nvkm_output_dp_init(struct nvkm_output *base)
struct nvkm_output_dp *outp = nvkm_output_dp(base); struct nvkm_output_dp *outp = nvkm_output_dp(base);
nvkm_notify_put(&outp->base.conn->hpd); nvkm_notify_put(&outp->base.conn->hpd);
nvkm_output_dp_enable(outp, true); nvkm_output_dp_enable(outp, true);
nvkm_notify_get(&outp->irq);
nvkm_notify_get(&outp->hpd); nvkm_notify_get(&outp->hpd);
} }
...@@ -238,11 +231,6 @@ nvkm_output_dp_ctor(const struct nvkm_output_dp_func *func, ...@@ -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_DBG(&outp->base, "bios dp %02x %02x %02x %02x",
outp->version, hdr, cnt, len); 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 */ /* link maintenance */
ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_irq, true, ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_irq, true,
&(struct nvkm_i2c_ntfy_req) { &(struct nvkm_i2c_ntfy_req) {
...@@ -257,6 +245,9 @@ nvkm_output_dp_ctor(const struct nvkm_output_dp_func *func, ...@@ -257,6 +245,9 @@ nvkm_output_dp_ctor(const struct nvkm_output_dp_func *func,
return ret; return ret;
} }
mutex_init(&outp->mutex);
atomic_set(&outp->lt.done, 0);
/* hotplug detect, replaces gpio-based mechanism with aux events */ /* hotplug detect, replaces gpio-based mechanism with aux events */
ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_hpd, true, ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_hpd, true,
&(struct nvkm_i2c_ntfy_req) { &(struct nvkm_i2c_ntfy_req) {
......
...@@ -29,9 +29,8 @@ struct nvkm_output_dp { ...@@ -29,9 +29,8 @@ struct nvkm_output_dp {
bool present; bool present;
u8 dpcd[16]; u8 dpcd[16];
struct mutex mutex;
struct { struct {
struct work_struct work;
wait_queue_head_t wait;
atomic_t done; atomic_t done;
} lt; } lt;
}; };
...@@ -43,7 +42,7 @@ struct nvkm_output_dp_func { ...@@ -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 (*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 nvkm_output_dp_ctor(const struct nvkm_output_dp_func *, struct nvkm_disp *,
int index, struct dcb_output *, struct nvkm_i2c_aux *, 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) ...@@ -173,7 +173,7 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
return 0; return 0;
} else } else
if (args->v0.state != 0) { if (args->v0.state != 0) {
nvkm_output_dp_train(&outpdp->base, 0, true); nvkm_output_dp_train(&outpdp->base, 0);
return 0; return 0;
} }
} else } 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