diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-05-26 02:09:06 (GMT) |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-06-11 06:10:57 (GMT) |
commit | ebd6acbb068b6558735eb80aabce1e7af9e78e1e (patch) | |
tree | 8794d7facf957999a40ea338d85a3dbdc342c74f /drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | |
parent | 55f083c33feb7231c7574a64cd01b0477715a370 (diff) | |
download | linux-ebd6acbb068b6558735eb80aabce1e7af9e78e1e.tar.xz |
drm/g94-/disp: add method to power-off dp lanes
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index 526b752..e183277 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c @@ -47,8 +47,12 @@ int nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nv50_disp_priv *priv = (void *)object->engine; + const u8 type = (mthd & NV50_DISP_SOR_MTHD_TYPE) >> 12; const u8 head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3; + const u8 link = (mthd & NV50_DISP_SOR_MTHD_LINK) >> 2; const u8 or = (mthd & NV50_DISP_SOR_MTHD_OR); + const u16 mask = (0x0100 << head) | (0x0040 << link) | (0x0001 << or); + struct nvkm_output *outp = NULL, *temp; u32 data; int ret = -EINVAL; @@ -56,6 +60,13 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) return -EINVAL; data = *(u32 *)args; + list_for_each_entry(temp, &priv->base.outp, head) { + if ((temp->info.hasht & 0xff) == type && + (temp->info.hashm & mask) == mask) { + outp = temp; + break; + } + } switch (mthd & ~0x3f) { case NV50_DISP_SOR_PWR: @@ -71,6 +82,23 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID; ret = 0; break; + case NV94_DISP_SOR_DP_PWR: + if (outp) { + struct nvkm_output_dp *outpdp = (void *)outp; + switch (data) { + case NV94_DISP_SOR_DP_PWR_STATE_OFF: + ((struct nvkm_output_dp_impl *)nv_oclass(outp)) + ->lnk_pwr(outpdp, 0); + atomic_set(&outpdp->lt.done, 0); + break; + case NV94_DISP_SOR_DP_PWR_STATE_ON: + nvkm_output_dp_train(&outpdp->base, 0, true); + break; + default: + return -EINVAL; + } + } + break; default: BUG_ON(1); } |