diff options
author | Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> | 2017-03-28 16:57:52 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 17:22:17 -0400 |
commit | 7c7f5b15be6528b33d825ead6acb739d7d061a2e (patch) | |
tree | 93336895662530093c76410b81c728eec0377f8c /drivers/gpu/drm/amd/display/amdgpu_dm | |
parent | bb01672c79649de08fe335b55aea5315d781c443 (diff) | |
download | linux-7c7f5b15be6528b33d825ead6acb739d7d061a2e.tar.bz2 |
drm/amd/display: Refactor edid read.
Allow Linux to use DRM provided EDID read functioality
by moving DAL edid implementation to module hence
removing this code from DC by this cleaning up DC
code for upstream.
v2: Removing ddc_service. No more need for it.
Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm')
4 files changed, 87 insertions, 19 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 5b096be44e59..01d04fa2419e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -435,3 +435,50 @@ bool dm_helpers_submit_i2c( return result; } + +enum dc_edid_status dm_helpers_read_local_edid( + struct dc_context *ctx, + struct dc_link *link, + struct dc_sink *sink) +{ + struct amdgpu_connector *aconnector = link->priv; + struct i2c_adapter *ddc; + int retry = 3; + enum dc_edid_status edid_status; + struct edid *edid; + + if (link->aux_mode) + ddc = &aconnector->dm_dp_aux.aux.ddc; + else + ddc = &aconnector->i2c->base; + + /* some dongles read edid incorrectly the first time, + * do check sum and retry to make sure read correct edid. + */ + do { + + edid = drm_get_edid(&aconnector->base, ddc); + + if (!edid) + return EDID_NO_RESPONSE; + + sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1); + memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length); + + /* We don't need the original edid anymore */ + kfree(edid); + + edid_status = dm_helpers_parse_edid_caps( + ctx, + &sink->dc_edid, + &sink->edid_caps); + + } while (edid_status == EDID_BAD_CHECKSUM && --retry > 0); + + if (edid_status != EDID_OK) + DRM_ERROR("EDID err: %d, on connector: %s", + edid_status, + aconnector->base.name); + + return edid_status; +} diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 069511bb6fab..187464ac27b3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -81,24 +81,43 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg struct drm_device *drm_dev = pci_get_drvdata(pdev); struct amdgpu_device *adev = drm_dev->dev_private; struct dc *dc = adev->dm.dc; + enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? I2C_MOT_TRUE : I2C_MOT_FALSE; bool res; - switch (msg->request) { + switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_READ: - res = dc_read_dpcd( - dc, - TO_DM_AUX(aux)->link_index, - msg->address, - msg->buffer, - msg->size); + res = dc_read_aux_dpcd( + dc, + TO_DM_AUX(aux)->link_index, + msg->address, + msg->buffer, + msg->size); break; case DP_AUX_NATIVE_WRITE: - res = dc_write_dpcd( - dc, - TO_DM_AUX(aux)->link_index, - msg->address, - msg->buffer, - msg->size); + res = dc_write_aux_dpcd( + dc, + TO_DM_AUX(aux)->link_index, + msg->address, + msg->buffer, + msg->size); + break; + case DP_AUX_I2C_READ: + res = dc_read_aux_i2c( + dc, + TO_DM_AUX(aux)->link_index, + mot, + msg->address, + msg->buffer, + msg->size); + break; + case DP_AUX_I2C_WRITE: + res = dc_write_aux_i2c( + dc, + TO_DM_AUX(aux)->link_index, + mot, + msg->address, + msg->buffer, + msg->size); break; default: return 0; @@ -418,7 +437,7 @@ static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { .register_connector = dm_dp_mst_register_connector }; -void amdgpu_dm_initialize_mst_connector( +void amdgpu_dm_initialize_dp_connector( struct amdgpu_display_manager *dm, struct amdgpu_connector *aconnector) { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 6130d62ac65c..418061f3b46b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -29,7 +29,7 @@ struct amdgpu_display_manager; struct amdgpu_connector; -void amdgpu_dm_initialize_mst_connector( +void amdgpu_dm_initialize_dp_connector( struct amdgpu_display_manager *dm, struct amdgpu_connector *aconnector); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c index c09af2b3350c..345df1b6d82b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c @@ -2047,7 +2047,7 @@ int amdgpu_dm_connector_init( if (connector_type == DRM_MODE_CONNECTOR_DisplayPort || connector_type == DRM_MODE_CONNECTOR_eDP) - amdgpu_dm_initialize_mst_connector(dm, aconnector); + amdgpu_dm_initialize_dp_connector(dm, aconnector); #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\ defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) @@ -3038,9 +3038,11 @@ static bool is_dp_capable_without_timing_msa( uint8_t dpcd_data; bool capable = false; if (amdgpu_connector->dc_link && - dc_read_dpcd(dc, amdgpu_connector->dc_link->link_index, - DP_DOWN_STREAM_PORT_COUNT, - &dpcd_data, sizeof(dpcd_data)) ) + dc_read_aux_dpcd( + dc, + amdgpu_connector->dc_link->link_index, + DP_DOWN_STREAM_PORT_COUNT, + &dpcd_data, sizeof(dpcd_data))) capable = (dpcd_data & DP_MSA_TIMING_PAR_IGNORED) ? true:false; return capable; |