From 7ebb38b556485449bfaa506a196439f6a6fd6ebd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 9 Nov 2012 09:38:06 +1000 Subject: [PATCH] drm/nv50/disp: call into core for dac load detection Signed-off-by: Ben Skeggs --- .../drm/nouveau/core/engine/disp/dacnv50.c | 6 +- .../gpu/drm/nouveau/core/engine/disp/nv50.c | 1 + .../gpu/drm/nouveau/core/engine/disp/nv50.h | 4 +- .../gpu/drm/nouveau/core/engine/disp/nv84.c | 1 + .../gpu/drm/nouveau/core/engine/disp/nv94.c | 1 + .../gpu/drm/nouveau/core/engine/disp/nva0.c | 1 + .../gpu/drm/nouveau/core/engine/disp/nva3.c | 1 + drivers/gpu/drm/nouveau/nv50_dac.c | 56 ++++--------------- drivers/gpu/drm/nouveau/nvd0_display.c | 2 +- 9 files changed, 22 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c index 18ba339c1625..d0817d94454c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c @@ -46,11 +46,11 @@ nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data) } int -nv50_dac_sense(struct nv50_disp_priv *priv, int or) +nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) { const u32 doff = (or * 0x800); int load = -EINVAL; - nv_wr32(priv, 0x61a00c + doff, 0x00100000); + nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); udelay(9500); nv_wr32(priv, 0x61a00c + doff, 0x80000000); load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; @@ -74,7 +74,7 @@ nv50_dac_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) ret = priv->dac.power(priv, or, data[0]); break; case NV50_DISP_DAC_LOAD: - ret = priv->dac.sense(priv, or); + ret = priv->dac.sense(priv, or, data[0]); if (ret >= 0) { data[0] = ret; ret = 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 37cf70fe30b2..bc397bc38ac7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -807,6 +807,7 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->dac.nr = 3; priv->sor.nr = 2; priv->dac.power = nv50_dac_power; + priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index 01eb830e18da..72cefd24ea02 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h @@ -19,7 +19,7 @@ struct nv50_disp_priv { struct { int nr; int (*power)(struct nv50_disp_priv *, int dac, u32 data); - int (*sense)(struct nv50_disp_priv *, int dac); + int (*sense)(struct nv50_disp_priv *, int dac, u32 load); } dac; struct { int nr; @@ -42,7 +42,7 @@ struct nv50_disp_priv { int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32); int nv50_dac_power(struct nv50_disp_priv *, int, u32); -int nv50_dac_sense(struct nv50_disp_priv *, int); +int nv50_dac_sense(struct nv50_disp_priv *, int, u32); #define SOR_MTHD(n) (n), (n) + 0x3f diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 69dff21076d5..4a52cb7a718c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -76,6 +76,7 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->dac.nr = 3; priv->sor.nr = 2; priv->dac.power = nv50_dac_power; + priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index 8dd8f8546dc3..36eb89c0f835 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -82,6 +82,7 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->dac.nr = 3; priv->sor.nr = 4; priv->dac.power = nv50_dac_power; + priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c index 9f0e354c5af6..7f247580db3a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c @@ -67,6 +67,7 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->dac.nr = 3; priv->sor.nr = 2; priv->dac.power = nv50_dac_power; + priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index 7aee31fb5dc5..398bb87db031 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -83,6 +83,7 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->dac.nr = 3; priv->sor.nr = 4; priv->dac.power = nv50_dac_power; + priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; INIT_LIST_HEAD(&priv->base.vblank.list); diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index 34abb588b482..622f0f9879ab 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -71,56 +71,22 @@ nv50_dac_disconnect(struct drm_encoder *encoder) static enum drm_connector_status nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { + struct nv50_display *priv = nv50_display(encoder->dev); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_device *device = nouveau_dev(encoder->dev); struct nouveau_drm *drm = nouveau_drm(encoder->dev); - enum drm_connector_status status = connector_status_disconnected; - uint32_t dpms_state, load_pattern, load_state; - int or = nv_encoder->or; - - nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001); - dpms_state = nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)); - - nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), - 0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); - 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 status; - } - - /* Use bios provided value if possible. */ - if (drm->vbios.dactestval) { - load_pattern = drm->vbios.dactestval; - NV_DEBUG(drm, "Using bios provided load_pattern of %d\n", - load_pattern); - } else { - load_pattern = 340; - NV_DEBUG(drm, "Using default load_pattern of %d\n", - load_pattern); - } - - nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or), - NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern); - mdelay(45); /* give it some time to process */ - load_state = nv_rd32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or)); - - nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0); - nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state | - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); + int or = nv_encoder->or, ret; + u32 load; - if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) == - NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) - status = connector_status_connected; - - if (status == connector_status_connected) - NV_DEBUG(drm, "Load was detected on output with or %d\n", or); + if (drm->vbios.dactestval) + load = drm->vbios.dactestval; else - NV_DEBUG(drm, "Load was not detected on output with or %d\n", or); + load = 340; + + ret = nv_exec(priv->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); + if (ret || load != 7) + return connector_status_disconnected; - return status; + return connector_status_connected; } static void diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 9bb28b030f4b..758daf709a99 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c @@ -1176,7 +1176,7 @@ nvd0_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct nvd0_disp *disp = nvd0_disp(encoder->dev); int ret, or = nouveau_encoder(encoder)->or; - u32 load; + u32 load = 0; ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); if (ret || load != 7) -- 2.30.2