aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-11-08 18:38:06 -0500
committerBen Skeggs <bskeggs@redhat.com>2012-11-28 18:57:50 -0500
commit7ebb38b556485449bfaa506a196439f6a6fd6ebd (patch)
tree05d7dd2db64a7c4def70207d3ee6750246fd4b02 /drivers
parentef22c8bb7b3fac45919b7fde412d36d1a8367d51 (diff)
drm/nv50/disp: call into core for dac load detection
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv84.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv94.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nva0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nva3.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_dac.c56
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c2
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)
46} 46}
47 47
48int 48int
49nv50_dac_sense(struct nv50_disp_priv *priv, int or) 49nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval)
50{ 50{
51 const u32 doff = (or * 0x800); 51 const u32 doff = (or * 0x800);
52 int load = -EINVAL; 52 int load = -EINVAL;
53 nv_wr32(priv, 0x61a00c + doff, 0x00100000); 53 nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval);
54 udelay(9500); 54 udelay(9500);
55 nv_wr32(priv, 0x61a00c + doff, 0x80000000); 55 nv_wr32(priv, 0x61a00c + doff, 0x80000000);
56 load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; 56 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)
74 ret = priv->dac.power(priv, or, data[0]); 74 ret = priv->dac.power(priv, or, data[0]);
75 break; 75 break;
76 case NV50_DISP_DAC_LOAD: 76 case NV50_DISP_DAC_LOAD:
77 ret = priv->dac.sense(priv, or); 77 ret = priv->dac.sense(priv, or, data[0]);
78 if (ret >= 0) { 78 if (ret >= 0) {
79 data[0] = ret; 79 data[0] = ret;
80 ret = 0; 80 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,
807 priv->dac.nr = 3; 807 priv->dac.nr = 3;
808 priv->sor.nr = 2; 808 priv->sor.nr = 2;
809 priv->dac.power = nv50_dac_power; 809 priv->dac.power = nv50_dac_power;
810 priv->dac.sense = nv50_dac_sense;
810 priv->sor.power = nv50_sor_power; 811 priv->sor.power = nv50_sor_power;
811 812
812 INIT_LIST_HEAD(&priv->base.vblank.list); 813 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 {
19 struct { 19 struct {
20 int nr; 20 int nr;
21 int (*power)(struct nv50_disp_priv *, int dac, u32 data); 21 int (*power)(struct nv50_disp_priv *, int dac, u32 data);
22 int (*sense)(struct nv50_disp_priv *, int dac); 22 int (*sense)(struct nv50_disp_priv *, int dac, u32 load);
23 } dac; 23 } dac;
24 struct { 24 struct {
25 int nr; 25 int nr;
@@ -42,7 +42,7 @@ struct nv50_disp_priv {
42 42
43int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32); 43int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32);
44int nv50_dac_power(struct nv50_disp_priv *, int, u32); 44int nv50_dac_power(struct nv50_disp_priv *, int, u32);
45int nv50_dac_sense(struct nv50_disp_priv *, int); 45int nv50_dac_sense(struct nv50_disp_priv *, int, u32);
46 46
47#define SOR_MTHD(n) (n), (n) + 0x3f 47#define SOR_MTHD(n) (n), (n) + 0x3f
48 48
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,
76 priv->dac.nr = 3; 76 priv->dac.nr = 3;
77 priv->sor.nr = 2; 77 priv->sor.nr = 2;
78 priv->dac.power = nv50_dac_power; 78 priv->dac.power = nv50_dac_power;
79 priv->dac.sense = nv50_dac_sense;
79 priv->sor.power = nv50_sor_power; 80 priv->sor.power = nv50_sor_power;
80 81
81 INIT_LIST_HEAD(&priv->base.vblank.list); 82 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,
82 priv->dac.nr = 3; 82 priv->dac.nr = 3;
83 priv->sor.nr = 4; 83 priv->sor.nr = 4;
84 priv->dac.power = nv50_dac_power; 84 priv->dac.power = nv50_dac_power;
85 priv->dac.sense = nv50_dac_sense;
85 priv->sor.power = nv50_sor_power; 86 priv->sor.power = nv50_sor_power;
86 87
87 INIT_LIST_HEAD(&priv->base.vblank.list); 88 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,
67 priv->dac.nr = 3; 67 priv->dac.nr = 3;
68 priv->sor.nr = 2; 68 priv->sor.nr = 2;
69 priv->dac.power = nv50_dac_power; 69 priv->dac.power = nv50_dac_power;
70 priv->dac.sense = nv50_dac_sense;
70 priv->sor.power = nv50_sor_power; 71 priv->sor.power = nv50_sor_power;
71 72
72 INIT_LIST_HEAD(&priv->base.vblank.list); 73 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,
83 priv->dac.nr = 3; 83 priv->dac.nr = 3;
84 priv->sor.nr = 4; 84 priv->sor.nr = 4;
85 priv->dac.power = nv50_dac_power; 85 priv->dac.power = nv50_dac_power;
86 priv->dac.sense = nv50_dac_sense;
86 priv->sor.power = nv50_sor_power; 87 priv->sor.power = nv50_sor_power;
87 88
88 INIT_LIST_HEAD(&priv->base.vblank.list); 89 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)
71static enum drm_connector_status 71static enum drm_connector_status
72nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) 72nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
73{ 73{
74 struct nv50_display *priv = nv50_display(encoder->dev);
74 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 75 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
75 struct nouveau_device *device = nouveau_dev(encoder->dev);
76 struct nouveau_drm *drm = nouveau_drm(encoder->dev); 76 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
77 enum drm_connector_status status = connector_status_disconnected; 77 int or = nv_encoder->or, ret;
78 uint32_t dpms_state, load_pattern, load_state; 78 u32 load;
79 int or = nv_encoder->or;
80
81 nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001);
82 dpms_state = nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or));
83
84 nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
85 0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
86 if (!nv_wait(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
87 NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
88 NV_ERROR(drm, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
89 NV_ERROR(drm, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
90 nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
91 return status;
92 }
93
94 /* Use bios provided value if possible. */
95 if (drm->vbios.dactestval) {
96 load_pattern = drm->vbios.dactestval;
97 NV_DEBUG(drm, "Using bios provided load_pattern of %d\n",
98 load_pattern);
99 } else {
100 load_pattern = 340;
101 NV_DEBUG(drm, "Using default load_pattern of %d\n",
102 load_pattern);
103 }
104
105 nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or),
106 NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern);
107 mdelay(45); /* give it some time to process */
108 load_state = nv_rd32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or));
109
110 nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0);
111 nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state |
112 NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
113 79
114 if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) == 80 if (drm->vbios.dactestval)
115 NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) 81 load = drm->vbios.dactestval;
116 status = connector_status_connected;
117
118 if (status == connector_status_connected)
119 NV_DEBUG(drm, "Load was detected on output with or %d\n", or);
120 else 82 else
121 NV_DEBUG(drm, "Load was not detected on output with or %d\n", or); 83 load = 340;
84
85 ret = nv_exec(priv->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load));
86 if (ret || load != 7)
87 return connector_status_disconnected;
122 88
123 return status; 89 return connector_status_connected;
124} 90}
125 91
126static void 92static 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)
1176{ 1176{
1177 struct nvd0_disp *disp = nvd0_disp(encoder->dev); 1177 struct nvd0_disp *disp = nvd0_disp(encoder->dev);
1178 int ret, or = nouveau_encoder(encoder)->or; 1178 int ret, or = nouveau_encoder(encoder)->or;
1179 u32 load; 1179 u32 load = 0;
1180 1180
1181 ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); 1181 ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load));
1182 if (ret || load != 7) 1182 if (ret || load != 7)