From d3efc3aa67f80f319aa7f2c7a6fd767292018596 Mon Sep 17 00:00:00 2001 From: Mykola Lysenko Date: Tue, 15 Dec 2015 20:29:08 +0800 Subject: [PATCH 0628/1110] drm/amd/dal: create actual number of CRTCs For MST we need to create actual number of CRTCs, not number of links. Consider the situation: 1. One DDI DP connector available on board; 2. One DRM CRTC created for it; 3. DRM does not allow set mode on newly arrived MST downstream display as there is no connectors left, event though 3 is still available. Signed-off-by: Mykola Lysenko Acked-by: Jordan Lazare --- drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c | 85 +++++++++------------- .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c | 28 +++++-- .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h | 8 +- 3 files changed, 61 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c index f85ce3b..c69ae16 100644 --- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c @@ -578,10 +578,10 @@ error: void amdgpu_dm_fini(struct amdgpu_device *adev) { + amdgpu_dm_destroy_drm_device(&adev->dm); /* * TODO: pageflip, vlank interrupt * - * amdgpu_dm_destroy_drm_device(&adev->dm); * amdgpu_dm_irq_fini(adev); */ @@ -1024,7 +1024,7 @@ void amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) { struct amdgpu_display_manager *dm = &adev->dm; - uint32_t link_index; + uint32_t i; struct amdgpu_connector *aconnector; struct amdgpu_encoder *aencoder; struct amdgpu_crtc *acrtc; @@ -1039,62 +1039,58 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) return -1; } + for (i = 0; i < caps.max_targets; i++) { + acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); + if (!acrtc) + goto fail; + + if (amdgpu_dm_crtc_init( + dm, + acrtc, + i)) { + DRM_ERROR("KMS: Failed to initialize crtc\n"); + kfree(acrtc); + goto fail; + } + } + + dm->display_indexes_num = caps.max_targets; + /* loops over all connectors on the board */ - for (link_index = 0; link_index < link_cnt; link_index++) { + for (i = 0; i < link_cnt; i++) { - if (link_index > AMDGPU_DM_MAX_DISPLAY_INDEX) { + if (i > AMDGPU_DM_MAX_DISPLAY_INDEX) { DRM_ERROR( - "KMS: Cannot support more than %d display indeces\n", + "KMS: Cannot support more than %d display indexes\n", AMDGPU_DM_MAX_DISPLAY_INDEX); continue; } aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); if (!aconnector) - goto fail_connector; + goto fail; aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL); - if (!aencoder) - goto fail_encoder; - - acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); - if (!acrtc) - goto fail_crtc; - - if (amdgpu_dm_crtc_init( - dm, - acrtc, - link_index)) { - DRM_ERROR("KMS: Failed to initialize crtc\n"); - goto fail; + if (!aencoder) { + goto fail_free_connector; } - if (amdgpu_dm_encoder_init( - dm->ddev, - aencoder, - link_index, - acrtc)) { + if (amdgpu_dm_encoder_init(dm->ddev, aencoder, i)) { DRM_ERROR("KMS: Failed to initialize encoder\n"); - goto fail; + goto fail_free_encoder; } - if (amdgpu_dm_connector_init( - dm, - aconnector, - link_index, - aencoder)) { + if (amdgpu_dm_connector_init(dm, aconnector, i, aencoder)) { DRM_ERROR("KMS: Failed to initialize connector\n"); - goto fail; + goto fail_free_connector; } - dc_link_detect(dc_get_link_at_index(dm->dc, link_index)); + dc_link_detect(dc_get_link_at_index(dm->dc, i)); amdgpu_dm_update_connector_after_detect( aconnector); } - dm->display_indexes_num = link_cnt; - /* Software is initialized. Now we can register interrupt handlers. */ switch (adev->asic_type) { case CHIP_CARRIZO: @@ -1111,28 +1107,17 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) drm_mode_config_reset(dm->ddev); return 0; - +fail_free_encoder: + kfree(aencoder); +fail_free_connector: + kfree(aconnector); fail: - /* clean any dongling drm structure for the last (corrupted) - display target */ - amdgpu_dm_crtc_destroy(&acrtc->base); -fail_crtc: - amdgpu_dm_encoder_destroy(&aencoder->base); -fail_encoder: - amdgpu_dm_connector_destroy(&aconnector->base); -fail_connector: - if (dm->backlight_dev) { - backlight_device_unregister(dm->backlight_dev); - dm->backlight_dev = NULL; - } return -1; } -void amdgpu_dm_destroy_drm_device( - struct amdgpu_display_manager *dm) +void amdgpu_dm_destroy_drm_device(struct amdgpu_display_manager *dm) { drm_mode_config_cleanup(dm->ddev); - /*switch_dev_unregister(&dm->hdmi_audio_dev);*/ return; } diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c index c98fdbf..3189e87 100644 --- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c @@ -1125,7 +1125,24 @@ int amdgpu_dm_connector_atomic_set_property( void amdgpu_dm_connector_destroy(struct drm_connector *connector) { - /*drm_sysfs_connector_remove(connector);*/ + struct amdgpu_connector *aconnector = to_amdgpu_connector(connector); + const struct dc_link *link = aconnector->dc_link; + struct amdgpu_device *adev = connector->dev->dev_private; + struct amdgpu_display_manager *dm = &adev->dm; +#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\ + defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) + + if (link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) { + amdgpu_dm_register_backlight_device(dm); + + if (dm->backlight_dev) { + backlight_device_unregister(dm->backlight_dev); + dm->backlight_dev = NULL; + } + + } +#endif + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -1530,7 +1547,7 @@ static uint32_t rgb_formats[] = { int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, struct amdgpu_crtc *acrtc, - uint32_t link_index) + uint32_t crtc_index) { int res = -ENOMEM; @@ -1571,10 +1588,10 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, acrtc->max_cursor_width = 128; acrtc->max_cursor_height = 128; - acrtc->crtc_id = link_index; + acrtc->crtc_id = crtc_index; acrtc->base.enabled = false; - dm->adev->mode_info.crtcs[link_index] = acrtc; + dm->adev->mode_info.crtcs[crtc_index] = acrtc; drm_mode_crtc_set_gamma_size(&acrtc->base, 256); return 0; @@ -1897,8 +1914,7 @@ int amdgpu_dm_get_encoder_crtc_mask(struct amdgpu_device *adev) int amdgpu_dm_encoder_init( struct drm_device *dev, struct amdgpu_encoder *aencoder, - uint32_t link_index, - struct amdgpu_crtc *acrtc) + uint32_t link_index) { struct amdgpu_device *adev = dev->dev_private; diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h index 5d1152e..d737e33 100644 --- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h +++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h @@ -43,10 +43,10 @@ int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, struct amdgpu_connector *amdgpu_connector, uint32_t link_index, struct amdgpu_encoder *amdgpu_encoder); -int amdgpu_dm_encoder_init(struct drm_device *dev, - struct amdgpu_encoder *amdgpu_encoder, - uint32_t link_index, - struct amdgpu_crtc *amdgpu_crtc); +int amdgpu_dm_encoder_init( + struct drm_device *dev, + struct amdgpu_encoder *aencoder, + uint32_t link_index); void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc); void amdgpu_dm_connector_destroy(struct drm_connector *connector); -- 2.7.4