From ef22c8bb7b3fac45919b7fde412d36d1a8367d51 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 9 Nov 2012 09:32:56 +1000 Subject: [PATCH] drm/nv50/disp: call into core to handle dac/sor power state changes Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/core/engine/disp/nv50.c | 12 +++++++- .../gpu/drm/nouveau/core/engine/disp/nv50.h | 6 ++-- .../gpu/drm/nouveau/core/engine/disp/nv84.c | 13 ++++++++- .../gpu/drm/nouveau/core/engine/disp/nv94.c | 19 +++++++++++- .../gpu/drm/nouveau/core/engine/disp/nva0.c | 4 ++- .../gpu/drm/nouveau/core/engine/disp/nva3.c | 4 ++- drivers/gpu/drm/nouveau/nv50_dac.c | 22 +++++--------- drivers/gpu/drm/nouveau/nv50_sor.c | 29 +++---------------- 8 files changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index c7f288b83bcf..37cf70fe30b2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -653,9 +653,17 @@ nv50_disp_base_ofuncs = { .fini = nv50_disp_base_fini, }; +static struct nouveau_omthds +nv50_disp_base_omthds[] = { + { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, + { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, + { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, + {}, +}; + static struct nouveau_oclass nv50_disp_base_oclass[] = { - { NV50_DISP_CLASS, &nv50_disp_base_ofuncs }, + { NV50_DISP_CLASS, &nv50_disp_base_ofuncs, nv50_disp_base_omthds }, {} }; @@ -798,6 +806,8 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 2; + priv->dac.power = nv50_dac_power; + priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); spin_lock_init(&priv->base.vblank.lock); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index 48e3f0d58cbf..01eb830e18da 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h @@ -38,8 +38,6 @@ struct nv50_disp_priv { } sor; }; -extern struct nouveau_omthds nva3_disp_base_omthds[]; - #define DAC_MTHD(n) (n), (n) + 0x03 int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32); @@ -107,6 +105,10 @@ extern struct nouveau_ofuncs nv50_disp_base_ofuncs; extern struct nouveau_oclass nv50_disp_cclass; void nv50_disp_intr(struct nouveau_subdev *); +extern struct nouveau_omthds nv84_disp_base_omthds[]; + +extern struct nouveau_omthds nva3_disp_base_omthds[]; + extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs; extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs; extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 3132301341d1..69dff21076d5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -39,9 +39,18 @@ nv84_disp_sclass[] = { {} }; +struct nouveau_omthds +nv84_disp_base_omthds[] = { + { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, + { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, + { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, + { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, + {}, +}; + static struct nouveau_oclass nv84_disp_base_oclass[] = { - { NV84_DISP_CLASS, &nv50_disp_base_ofuncs }, + { NV84_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds }, {} }; @@ -66,6 +75,8 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 2; + priv->dac.power = nv50_dac_power; + priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); spin_lock_init(&priv->base.vblank.lock); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index 851abb73bc94..8dd8f8546dc3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -39,9 +39,24 @@ nv94_disp_sclass[] = { {} }; +static struct nouveau_omthds +nv94_disp_base_omthds[] = { + { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, + { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(1)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(2)), nv50_sor_mthd }, + { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(3)), nv50_sor_mthd }, + { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, + { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, + {}, +}; + static struct nouveau_oclass nv94_disp_base_oclass[] = { - { NV94_DISP_CLASS, &nv50_disp_base_ofuncs }, + { NV94_DISP_CLASS, &nv50_disp_base_ofuncs, nv94_disp_base_omthds }, {} }; @@ -66,6 +81,8 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 4; + priv->dac.power = nv50_dac_power; + priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); spin_lock_init(&priv->base.vblank.lock); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c index f96ab6c55947..9f0e354c5af6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c @@ -41,7 +41,7 @@ nva0_disp_sclass[] = { static struct nouveau_oclass nva0_disp_base_oclass[] = { - { NVA0_DISP_CLASS, &nv50_disp_base_ofuncs }, + { NVA0_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds }, {} }; @@ -66,6 +66,8 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 2; + priv->dac.power = nv50_dac_power; + priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); spin_lock_init(&priv->base.vblank.lock); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index b557108b2f36..7aee31fb5dc5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -57,7 +57,7 @@ nva3_disp_base_omthds[] = { static struct nouveau_oclass nva3_disp_base_oclass[] = { - { NVA3_DISP_CLASS, &nv50_disp_base_ofuncs }, + { NVA3_DISP_CLASS, &nv50_disp_base_ofuncs, nva3_disp_base_omthds }, {} }; @@ -82,6 +82,8 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->head.nr = 2; priv->dac.nr = 3; priv->sor.nr = 4; + priv->dac.power = nv50_dac_power; + priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); spin_lock_init(&priv->base.vblank.lock); diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index de964e84c74f..34abb588b482 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -36,6 +36,8 @@ #include "nouveau_crtc.h" #include "nv50_display.h" +#include + #include static void @@ -124,7 +126,7 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) static void nv50_dac_dpms(struct drm_encoder *encoder, int mode) { - struct nouveau_device *device = nouveau_dev(encoder->dev); + struct nv50_display *priv = nv50_display(encoder->dev); struct nouveau_drm *drm = nouveau_drm(encoder->dev); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); uint32_t val; @@ -132,19 +134,10 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) NV_DEBUG(drm, "or %d mode %d\n", or, mode); - /* wait for it to be done */ - if (!nv_wait(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { - NV_ERROR(drm, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); - NV_ERROR(drm, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, - nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or))); - return; - } - - val = nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F; - if (mode != DRM_MODE_DPMS_ON) - val |= NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED; + val = NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED; + else + val = 0; switch (mode) { case DRM_MODE_DPMS_STANDBY: @@ -162,8 +155,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) break; } - nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val | - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); + nv_call(priv->core, NV50_DISP_DAC_PWR + or, val); } static void diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 9b903ca1d1b9..5498f0ef7d5e 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -36,6 +36,8 @@ #include "nouveau_crtc.h" #include "nv50_display.h" +#include + #include static u32 @@ -267,12 +269,11 @@ nv50_sor_disconnect(struct drm_encoder *encoder) static void nv50_sor_dpms(struct drm_encoder *encoder, int mode) { - struct nouveau_device *device = nouveau_dev(encoder->dev); + struct nv50_display *priv = nv50_display(encoder->dev); struct nouveau_drm *drm = nouveau_drm(encoder->dev); struct drm_device *dev = encoder->dev; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_encoder *enc; - uint32_t val; int or = nv_encoder->or; NV_DEBUG(drm, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode); @@ -292,29 +293,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) return; } - /* wait for it to be done */ - if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or), - NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) { - NV_ERROR(drm, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or); - NV_ERROR(drm, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or, - nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or))); - } - - val = nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or)); - - if (mode == DRM_MODE_DPMS_ON) - val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON; - else - val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON; - - nv_wr32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val | - NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING); - if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_STATE(or), - NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { - NV_ERROR(drm, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or); - NV_ERROR(drm, "SOR_DPMS_STATE(%d) = 0x%08x\n", or, - nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_STATE(or))); - } + nv_call(priv->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { struct dp_train_func func = { -- GitLab