drm/radeon: restructure edid fetching
Split radeon_ddc_get_modes() and move it into radeon_connectors.c since that is the only place that uses it. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
88fd4789cd
commit
72a5c970a5
|
@ -262,6 +262,79 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void radeon_connector_get_edid(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
|
||||
if (radeon_connector->edid)
|
||||
return;
|
||||
|
||||
/* on hw with routers, select right port */
|
||||
if (radeon_connector->router.ddc_valid)
|
||||
radeon_router_select_ddc_port(radeon_connector);
|
||||
|
||||
if ((radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
|
||||
ENCODER_OBJECT_ID_NONE) &&
|
||||
radeon_connector->ddc_bus->has_aux) {
|
||||
radeon_connector->edid = drm_get_edid(connector,
|
||||
&radeon_connector->ddc_bus->aux.ddc);
|
||||
} else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
|
||||
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
|
||||
|
||||
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
|
||||
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
|
||||
radeon_connector->ddc_bus->has_aux)
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->aux.ddc);
|
||||
else if (radeon_connector->ddc_bus)
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->adapter);
|
||||
} else if (radeon_connector->ddc_bus) {
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->adapter);
|
||||
}
|
||||
|
||||
if (!radeon_connector->edid) {
|
||||
if (rdev->is_atom_bios) {
|
||||
/* some laptops provide a hardcoded edid in rom for LCDs */
|
||||
if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP)))
|
||||
radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
|
||||
} else {
|
||||
/* some servers provide a hardcoded edid in rom for KVMs */
|
||||
radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void radeon_connector_free_edid(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
|
||||
if (radeon_connector->edid) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int radeon_ddc_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
int ret;
|
||||
|
||||
if (radeon_connector->edid) {
|
||||
drm_mode_connector_update_edid_property(connector, radeon_connector->edid);
|
||||
ret = drm_add_edid_modes(connector, radeon_connector->edid);
|
||||
drm_edid_to_eld(connector, radeon_connector->edid);
|
||||
return ret;
|
||||
}
|
||||
drm_mode_connector_update_edid_property(connector, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
|
||||
{
|
||||
int enc_id = connector->encoder_ids[0];
|
||||
|
@ -661,22 +734,20 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
|
|||
|
||||
static int radeon_lvds_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_encoder *encoder;
|
||||
int ret = 0;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
if (radeon_connector->ddc_bus) {
|
||||
ret = radeon_ddc_get_modes(radeon_connector);
|
||||
if (ret > 0) {
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
if (encoder) {
|
||||
radeon_fixup_lvds_native_mode(encoder, connector);
|
||||
/* add scaled modes */
|
||||
radeon_add_common_modes(encoder, connector);
|
||||
}
|
||||
return ret;
|
||||
radeon_connector_get_edid(connector);
|
||||
ret = radeon_ddc_get_modes(connector);
|
||||
if (ret > 0) {
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
if (encoder) {
|
||||
radeon_fixup_lvds_native_mode(encoder, connector);
|
||||
/* add scaled modes */
|
||||
radeon_add_common_modes(encoder, connector);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
|
@ -751,16 +822,9 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
|
|||
}
|
||||
|
||||
/* check for edid as well */
|
||||
radeon_connector_get_edid(connector);
|
||||
if (radeon_connector->edid)
|
||||
ret = connector_status_connected;
|
||||
else {
|
||||
if (radeon_connector->ddc_bus) {
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->adapter);
|
||||
if (radeon_connector->edid)
|
||||
ret = connector_status_connected;
|
||||
}
|
||||
}
|
||||
/* check acpi lid status ??? */
|
||||
|
||||
radeon_connector_update_scratch_regs(connector, ret);
|
||||
|
@ -773,8 +837,7 @@ static void radeon_connector_destroy(struct drm_connector *connector)
|
|||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
|
||||
if (radeon_connector->edid)
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector_free_edid(connector);
|
||||
kfree(radeon_connector->con_priv);
|
||||
drm_connector_unregister(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
|
@ -833,10 +896,10 @@ static const struct drm_connector_funcs radeon_lvds_connector_funcs = {
|
|||
|
||||
static int radeon_vga_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
int ret;
|
||||
|
||||
ret = radeon_ddc_get_modes(radeon_connector);
|
||||
radeon_connector_get_edid(connector);
|
||||
ret = radeon_ddc_get_modes(connector);
|
||||
|
||||
radeon_get_native_mode(connector);
|
||||
|
||||
|
@ -881,28 +944,26 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
|
|||
dret = radeon_ddc_probe(radeon_connector, false);
|
||||
if (dret) {
|
||||
radeon_connector->detected_by_load = false;
|
||||
if (radeon_connector->edid) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
}
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
||||
radeon_connector_free_edid(connector);
|
||||
radeon_connector_get_edid(connector);
|
||||
|
||||
if (!radeon_connector->edid) {
|
||||
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
|
||||
connector->name);
|
||||
ret = connector_status_connected;
|
||||
} else {
|
||||
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
radeon_connector->use_digital =
|
||||
!!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
|
||||
/* some oems have boards with separate digital and analog connectors
|
||||
* with a shared ddc line (often vga + hdmi)
|
||||
*/
|
||||
if (radeon_connector->use_digital && radeon_connector->shared_ddc) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
radeon_connector_free_edid(connector);
|
||||
ret = connector_status_disconnected;
|
||||
} else
|
||||
} else {
|
||||
ret = connector_status_connected;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
|
@ -1094,18 +1155,16 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||
dret = radeon_ddc_probe(radeon_connector, false);
|
||||
if (dret) {
|
||||
radeon_connector->detected_by_load = false;
|
||||
if (radeon_connector->edid) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
}
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
||||
radeon_connector_free_edid(connector);
|
||||
radeon_connector_get_edid(connector);
|
||||
|
||||
if (!radeon_connector->edid) {
|
||||
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
|
||||
connector->name);
|
||||
/* rs690 seems to have a problem with connectors not existing and always
|
||||
* return a block of 0's. If we see this just stop polling on this output */
|
||||
if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) {
|
||||
if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) &&
|
||||
radeon_connector->base.null_edid_counter) {
|
||||
ret = connector_status_disconnected;
|
||||
DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n",
|
||||
connector->name);
|
||||
|
@ -1115,18 +1174,18 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||
broken_edid = true; /* defer use_digital to later */
|
||||
}
|
||||
} else {
|
||||
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
radeon_connector->use_digital =
|
||||
!!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
|
||||
/* some oems have boards with separate digital and analog connectors
|
||||
* with a shared ddc line (often vga + hdmi)
|
||||
*/
|
||||
if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
radeon_connector_free_edid(connector);
|
||||
ret = connector_status_disconnected;
|
||||
} else
|
||||
} else {
|
||||
ret = connector_status_connected;
|
||||
|
||||
}
|
||||
/* This gets complicated. We have boards with VGA + HDMI with a
|
||||
* shared DDC line and we have boards with DVI-D + HDMI with a shared
|
||||
* DDC line. The latter is more complex because with DVI<->HDMI adapters
|
||||
|
@ -1146,8 +1205,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||
if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) {
|
||||
/* hpd is our only option in this case */
|
||||
if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
radeon_connector_free_edid(connector);
|
||||
ret = connector_status_disconnected;
|
||||
}
|
||||
}
|
||||
|
@ -1356,7 +1414,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
|
|||
if (!radeon_dig_connector->edp_on)
|
||||
atombios_set_edp_panel_power(connector,
|
||||
ATOM_TRANSMITTER_ACTION_POWER_ON);
|
||||
ret = radeon_ddc_get_modes(radeon_connector);
|
||||
radeon_connector_get_edid(connector);
|
||||
ret = radeon_ddc_get_modes(connector);
|
||||
if (!radeon_dig_connector->edp_on)
|
||||
atombios_set_edp_panel_power(connector,
|
||||
ATOM_TRANSMITTER_ACTION_POWER_OFF);
|
||||
|
@ -1367,7 +1426,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
|
|||
if (encoder)
|
||||
radeon_atom_ext_encoder_setup_ddc(encoder);
|
||||
}
|
||||
ret = radeon_ddc_get_modes(radeon_connector);
|
||||
radeon_connector_get_edid(connector);
|
||||
ret = radeon_ddc_get_modes(connector);
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
|
@ -1400,7 +1460,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
|
|||
if (encoder)
|
||||
radeon_atom_ext_encoder_setup_ddc(encoder);
|
||||
}
|
||||
ret = radeon_ddc_get_modes(radeon_connector);
|
||||
radeon_connector_get_edid(connector);
|
||||
ret = radeon_ddc_get_modes(connector);
|
||||
|
||||
radeon_get_native_mode(connector);
|
||||
}
|
||||
|
@ -1493,10 +1554,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (radeon_connector->edid) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
}
|
||||
radeon_connector_free_edid(connector);
|
||||
|
||||
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
|
||||
|
|
|
@ -823,64 +823,6 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
|
||||
{
|
||||
struct drm_device *dev = radeon_connector->base.dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
int ret = 0;
|
||||
|
||||
/* don't leak the edid if we already fetched it in detect() */
|
||||
if (radeon_connector->edid)
|
||||
goto got_edid;
|
||||
|
||||
/* on hw with routers, select right port */
|
||||
if (radeon_connector->router.ddc_valid)
|
||||
radeon_router_select_ddc_port(radeon_connector);
|
||||
|
||||
if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
|
||||
ENCODER_OBJECT_ID_NONE) {
|
||||
if (radeon_connector->ddc_bus->has_aux)
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->aux.ddc);
|
||||
} else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
|
||||
(radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
|
||||
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
|
||||
|
||||
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
|
||||
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
|
||||
radeon_connector->ddc_bus->has_aux)
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->aux.ddc);
|
||||
else if (radeon_connector->ddc_bus && !radeon_connector->edid)
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->adapter);
|
||||
} else {
|
||||
if (radeon_connector->ddc_bus && !radeon_connector->edid)
|
||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||
&radeon_connector->ddc_bus->adapter);
|
||||
}
|
||||
|
||||
if (!radeon_connector->edid) {
|
||||
if (rdev->is_atom_bios) {
|
||||
/* some laptops provide a hardcoded edid in rom for LCDs */
|
||||
if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) ||
|
||||
(radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)))
|
||||
radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
|
||||
} else
|
||||
/* some servers provide a hardcoded edid in rom for KVMs */
|
||||
radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
|
||||
}
|
||||
if (radeon_connector->edid) {
|
||||
got_edid:
|
||||
drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
|
||||
ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
|
||||
drm_edid_to_eld(&radeon_connector->base, radeon_connector->edid);
|
||||
return ret;
|
||||
}
|
||||
drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* avivo */
|
||||
|
||||
/**
|
||||
|
|
|
@ -738,7 +738,6 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
|
|||
extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
|
||||
extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
|
||||
extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux);
|
||||
extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
|
||||
|
||||
extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
|
||||
|
||||
|
|
Loading…
Reference in New Issue