drm/nv50/disp: call into core for dac load detection
authorBen Skeggs <bskeggs@redhat.com>
Thu, 8 Nov 2012 23:38:06 +0000 (09:38 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:57:50 +0000 (09:57 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
drivers/gpu/drm/nouveau/nv50_dac.c
drivers/gpu/drm/nouveau/nvd0_display.c

index 18ba339c1625aa33463490651e8832cecfb889d8..d0817d94454ceb0d17536995e0c053b8585fdf72 100644 (file)
@@ -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;
index 37cf70fe30b282f831dbc4c526bdf85a59fe1266..bc397bc38ac75a28dc0fb29a4dc39dea2302f682 100644 (file)
@@ -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);
index 01eb830e18da32ca153c6c2a6c46345aab0e4c70..72cefd24ea0259c4b3be453277b02c0090f90f3e 100644 (file)
@@ -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
 
index 69dff21076d5d49c0432034cfb54181196b6671f..4a52cb7a718c5554299df8541abad6f0f21468bb 100644 (file)
@@ -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);
index 8dd8f8546dc32f92b6d5d05ea2f42df87e56e1bc..36eb89c0f83513d95189bb0d8eb2305390c95c44 100644 (file)
@@ -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);
index 9f0e354c5af6de814dfccaa258adcdc77ffac73c..7f247580db3a425a5ffe74f558ccb2c304a778b5 100644 (file)
@@ -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);
index 7aee31fb5dc5ad0b071c5cfce1c8a3690bd228ba..398bb87db03153e46d982e1818fdd9fb12125b6f 100644 (file)
@@ -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);
index 34abb588b48268eb98d58ea1994eedf5c221e2f4..622f0f9879abd058d6b879656588966e90736836 100644 (file)
@@ -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
index 9bb28b030f4b8f753a86792255f8b4a411e94eed..758daf709a990b3c57fa158dab4b3264d76a2df1 100644 (file)
@@ -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)