aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0977-drm-amd-dal-create-actual-number-of-CRTCs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0977-drm-amd-dal-create-actual-number-of-CRTCs.patch')
-rw-r--r--common/recipes-kernel/linux/files/0977-drm-amd-dal-create-actual-number-of-CRTCs.patch258
1 files changed, 258 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0977-drm-amd-dal-create-actual-number-of-CRTCs.patch b/common/recipes-kernel/linux/files/0977-drm-amd-dal-create-actual-number-of-CRTCs.patch
new file mode 100644
index 00000000..b6329154
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0977-drm-amd-dal-create-actual-number-of-CRTCs.patch
@@ -0,0 +1,258 @@
+From 79eb59f4b2d6eab65bbe6cbb549017a2a65b7667 Mon Sep 17 00:00:00 2001
+From: Mykola Lysenko <Mykola.Lysenko@amd.com>
+Date: Tue, 15 Dec 2015 20:29:08 +0800
+Subject: [PATCH 0977/1050] 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.
+
+Change-Id: I6c50ecc4da87ad03c48d28d3ab5d1206f751f3f6
+Signed-off-by: Mykola Lysenko <Mykola.Lysenko@amd.com>
+Acked-by: Jordan Lazare <Jordan.Lazare@amd.com>
+---
+ 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 b671f9b..5c5950b 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 a4570ed..df4f412 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
+@@ -1128,7 +1128,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);
+ }
+@@ -1532,7 +1549,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;
+
+@@ -1573,10 +1590,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);
+
+ acrtc->pflip_queue =
+@@ -1902,8 +1919,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);
+--
+1.9.1
+