aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-06-06 04:09:55 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-06-11 02:11:42 -0400
commit8777c5c11764d8336d8270f96778158c34c92108 (patch)
treea31c7eb43a6662cb85893a5789539569a20c836d
parentefa366fdf5658ca9ccad38e235818d121b1b8002 (diff)
drm/nouveau/dp: probe dpcd to determine connectedness
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c48
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h4
3 files changed, 26 insertions, 40 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 7dac5e216799..1fa222e8f007 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -111,15 +111,15 @@ nouveau_connector_destroy(struct drm_connector *connector)
111 kfree(connector); 111 kfree(connector);
112} 112}
113 113
114static struct nouveau_i2c_port * 114static struct nouveau_encoder *
115nouveau_connector_ddc_detect(struct drm_connector *connector, 115nouveau_connector_ddc_detect(struct drm_connector *connector)
116 struct nouveau_encoder **pnv_encoder)
117{ 116{
118 struct drm_device *dev = connector->dev; 117 struct drm_device *dev = connector->dev;
119 struct nouveau_connector *nv_connector = nouveau_connector(connector); 118 struct nouveau_connector *nv_connector = nouveau_connector(connector);
120 struct nouveau_drm *drm = nouveau_drm(dev); 119 struct nouveau_drm *drm = nouveau_drm(dev);
121 struct nouveau_gpio *gpio = nouveau_gpio(drm->device); 120 struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
122 struct nouveau_i2c_port *port = NULL; 121 struct nouveau_encoder *nv_encoder;
122 struct drm_mode_object *obj;
123 int i, panel = -ENODEV; 123 int i, panel = -ENODEV;
124 124
125 /* eDP panels need powering on by us (if the VBIOS doesn't default it 125 /* eDP panels need powering on by us (if the VBIOS doesn't default it
@@ -134,13 +134,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
134 } 134 }
135 } 135 }
136 136
137 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 137 for (i = 0; nv_encoder = NULL, i < DRM_CONNECTOR_MAX_ENCODER; i++) {
138 struct nouveau_encoder *nv_encoder; 138 int id = connector->encoder_ids[i];
139 struct drm_mode_object *obj; 139 if (id == 0)
140 int id;
141
142 id = connector->encoder_ids[i];
143 if (!id)
144 break; 140 break;
145 141
146 obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); 142 obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
@@ -148,22 +144,24 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
148 continue; 144 continue;
149 nv_encoder = nouveau_encoder(obj_to_encoder(obj)); 145 nv_encoder = nouveau_encoder(obj_to_encoder(obj));
150 146
151 port = nv_encoder->i2c; 147 if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
152 if (port && nv_probe_i2c(port, 0x50)) { 148 int ret = nouveau_dp_detect(nv_encoder);
153 *pnv_encoder = nv_encoder; 149 if (ret == 0)
154 break; 150 break;
151 } else
152 if (nv_encoder->i2c) {
153 if (nv_probe_i2c(nv_encoder->i2c, 0x50))
154 break;
155 } 155 }
156
157 port = NULL;
158 } 156 }
159 157
160 /* eDP panel not detected, restore panel power GPIO to previous 158 /* eDP panel not detected, restore panel power GPIO to previous
161 * state to avoid confusing the SOR for other output types. 159 * state to avoid confusing the SOR for other output types.
162 */ 160 */
163 if (!port && panel == 0) 161 if (!nv_encoder && panel == 0)
164 gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel); 162 gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
165 163
166 return port; 164 return nv_encoder;
167} 165}
168 166
169static struct nouveau_encoder * 167static struct nouveau_encoder *
@@ -262,8 +260,8 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
262 if (ret < 0 && ret != -EACCES) 260 if (ret < 0 && ret != -EACCES)
263 return conn_status; 261 return conn_status;
264 262
265 i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); 263 nv_encoder = nouveau_connector_ddc_detect(connector);
266 if (i2c) { 264 if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
267 nv_connector->edid = drm_get_edid(connector, &i2c->adapter); 265 nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
268 drm_mode_connector_update_edid_property(connector, 266 drm_mode_connector_update_edid_property(connector,
269 nv_connector->edid); 267 nv_connector->edid);
@@ -273,14 +271,6 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
273 goto detect_analog; 271 goto detect_analog;
274 } 272 }
275 273
276 if (nv_encoder->dcb->type == DCB_OUTPUT_DP &&
277 !nouveau_dp_detect(to_drm_encoder(nv_encoder))) {
278 NV_ERROR(drm, "Detected %s, but failed init\n",
279 connector->name);
280 conn_status = connector_status_disconnected;
281 goto out;
282 }
283
284 /* Override encoder type for DVI-I based on whether EDID 274 /* Override encoder type for DVI-I based on whether EDID
285 * says the display is digital or analog, both use the 275 * says the display is digital or analog, both use the
286 * same i2c channel so the value returned from ddc_detect 276 * same i2c channel so the value returned from ddc_detect
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 36fd22500569..5675ffc175ae 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -55,11 +55,10 @@ nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch,
55 55
56} 56}
57 57
58bool 58int
59nouveau_dp_detect(struct drm_encoder *encoder) 59nouveau_dp_detect(struct nouveau_encoder *nv_encoder)
60{ 60{
61 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 61 struct drm_device *dev = nv_encoder->base.base.dev;
62 struct drm_device *dev = encoder->dev;
63 struct nouveau_drm *drm = nouveau_drm(dev); 62 struct nouveau_drm *drm = nouveau_drm(dev);
64 struct nouveau_i2c_port *auxch; 63 struct nouveau_i2c_port *auxch;
65 u8 *dpcd = nv_encoder->dp.dpcd; 64 u8 *dpcd = nv_encoder->dp.dpcd;
@@ -67,11 +66,11 @@ nouveau_dp_detect(struct drm_encoder *encoder)
67 66
68 auxch = nv_encoder->i2c; 67 auxch = nv_encoder->i2c;
69 if (!auxch) 68 if (!auxch)
70 return false; 69 return -ENODEV;
71 70
72 ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8); 71 ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8);
73 if (ret) 72 if (ret)
74 return false; 73 return ret;
75 74
76 nv_encoder->dp.link_bw = 27000 * dpcd[1]; 75 nv_encoder->dp.link_bw = 27000 * dpcd[1];
77 nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; 76 nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK;
@@ -91,6 +90,5 @@ nouveau_dp_detect(struct drm_encoder *encoder)
91 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); 90 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw);
92 91
93 nouveau_dp_probe_oui(dev, auxch, dpcd); 92 nouveau_dp_probe_oui(dev, auxch, dpcd);
94 93 return 0;
95 return true;
96} 94}
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index fcf89c8c67b7..5f0e37fc2849 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -85,9 +85,7 @@ get_slave_funcs(struct drm_encoder *enc)
85} 85}
86 86
87/* nouveau_dp.c */ 87/* nouveau_dp.c */
88bool nouveau_dp_detect(struct drm_encoder *); 88int nouveau_dp_detect(struct nouveau_encoder *);
89void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate,
90 struct nouveau_object *);
91 89
92struct nouveau_connector * 90struct nouveau_connector *
93nouveau_encoder_connector_get(struct nouveau_encoder *encoder); 91nouveau_encoder_connector_get(struct nouveau_encoder *encoder);