Commit 8777c5c1 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/dp: probe dpcd to determine connectedness

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent efa366fd
...@@ -111,15 +111,15 @@ nouveau_connector_destroy(struct drm_connector *connector) ...@@ -111,15 +111,15 @@ nouveau_connector_destroy(struct drm_connector *connector)
kfree(connector); kfree(connector);
} }
static struct nouveau_i2c_port * static struct nouveau_encoder *
nouveau_connector_ddc_detect(struct drm_connector *connector, nouveau_connector_ddc_detect(struct drm_connector *connector)
struct nouveau_encoder **pnv_encoder)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device); struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct nouveau_i2c_port *port = NULL; struct nouveau_encoder *nv_encoder;
struct drm_mode_object *obj;
int i, panel = -ENODEV; int i, panel = -ENODEV;
/* eDP panels need powering on by us (if the VBIOS doesn't default it /* 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,13 +134,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
} }
} }
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { for (i = 0; nv_encoder = NULL, i < DRM_CONNECTOR_MAX_ENCODER; i++) {
struct nouveau_encoder *nv_encoder; int id = connector->encoder_ids[i];
struct drm_mode_object *obj; if (id == 0)
int id;
id = connector->encoder_ids[i];
if (!id)
break; break;
obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
...@@ -148,22 +144,24 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, ...@@ -148,22 +144,24 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
continue; continue;
nv_encoder = nouveau_encoder(obj_to_encoder(obj)); nv_encoder = nouveau_encoder(obj_to_encoder(obj));
port = nv_encoder->i2c; if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
if (port && nv_probe_i2c(port, 0x50)) { int ret = nouveau_dp_detect(nv_encoder);
*pnv_encoder = nv_encoder; if (ret == 0)
break; break;
} else
if (nv_encoder->i2c) {
if (nv_probe_i2c(nv_encoder->i2c, 0x50))
break;
} }
port = NULL;
} }
/* eDP panel not detected, restore panel power GPIO to previous /* eDP panel not detected, restore panel power GPIO to previous
* state to avoid confusing the SOR for other output types. * state to avoid confusing the SOR for other output types.
*/ */
if (!port && panel == 0) if (!nv_encoder && panel == 0)
gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel); gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
return port; return nv_encoder;
} }
static struct nouveau_encoder * static struct nouveau_encoder *
...@@ -262,8 +260,8 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) ...@@ -262,8 +260,8 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
if (ret < 0 && ret != -EACCES) if (ret < 0 && ret != -EACCES)
return conn_status; return conn_status;
i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); nv_encoder = nouveau_connector_ddc_detect(connector);
if (i2c) { if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
nv_connector->edid = drm_get_edid(connector, &i2c->adapter); nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
drm_mode_connector_update_edid_property(connector, drm_mode_connector_update_edid_property(connector,
nv_connector->edid); nv_connector->edid);
...@@ -273,14 +271,6 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) ...@@ -273,14 +271,6 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
goto detect_analog; goto detect_analog;
} }
if (nv_encoder->dcb->type == DCB_OUTPUT_DP &&
!nouveau_dp_detect(to_drm_encoder(nv_encoder))) {
NV_ERROR(drm, "Detected %s, but failed init\n",
connector->name);
conn_status = connector_status_disconnected;
goto out;
}
/* Override encoder type for DVI-I based on whether EDID /* Override encoder type for DVI-I based on whether EDID
* says the display is digital or analog, both use the * says the display is digital or analog, both use the
* same i2c channel so the value returned from ddc_detect * same i2c channel so the value returned from ddc_detect
......
...@@ -55,11 +55,10 @@ nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch, ...@@ -55,11 +55,10 @@ nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch,
} }
bool int
nouveau_dp_detect(struct drm_encoder *encoder) nouveau_dp_detect(struct nouveau_encoder *nv_encoder)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_device *dev = nv_encoder->base.base.dev;
struct drm_device *dev = encoder->dev;
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_i2c_port *auxch; struct nouveau_i2c_port *auxch;
u8 *dpcd = nv_encoder->dp.dpcd; u8 *dpcd = nv_encoder->dp.dpcd;
...@@ -67,11 +66,11 @@ nouveau_dp_detect(struct drm_encoder *encoder) ...@@ -67,11 +66,11 @@ nouveau_dp_detect(struct drm_encoder *encoder)
auxch = nv_encoder->i2c; auxch = nv_encoder->i2c;
if (!auxch) if (!auxch)
return false; return -ENODEV;
ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8); ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8);
if (ret) if (ret)
return false; return ret;
nv_encoder->dp.link_bw = 27000 * dpcd[1]; nv_encoder->dp.link_bw = 27000 * dpcd[1];
nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK;
...@@ -91,6 +90,5 @@ nouveau_dp_detect(struct drm_encoder *encoder) ...@@ -91,6 +90,5 @@ nouveau_dp_detect(struct drm_encoder *encoder)
nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); nv_encoder->dp.link_nr, nv_encoder->dp.link_bw);
nouveau_dp_probe_oui(dev, auxch, dpcd); nouveau_dp_probe_oui(dev, auxch, dpcd);
return 0;
return true;
} }
...@@ -85,9 +85,7 @@ get_slave_funcs(struct drm_encoder *enc) ...@@ -85,9 +85,7 @@ get_slave_funcs(struct drm_encoder *enc)
} }
/* nouveau_dp.c */ /* nouveau_dp.c */
bool nouveau_dp_detect(struct drm_encoder *); int nouveau_dp_detect(struct nouveau_encoder *);
void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate,
struct nouveau_object *);
struct nouveau_connector * struct nouveau_connector *
nouveau_encoder_connector_get(struct nouveau_encoder *encoder); nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment