aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0311-drm-amd-display-decouple-per-crtc-plane-model.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0311-drm-amd-display-decouple-per-crtc-plane-model.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0311-drm-amd-display-decouple-per-crtc-plane-model.patch442
1 files changed, 442 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0311-drm-amd-display-decouple-per-crtc-plane-model.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0311-drm-amd-display-decouple-per-crtc-plane-model.patch
new file mode 100644
index 00000000..4dd78268
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0311-drm-amd-display-decouple-per-crtc-plane-model.patch
@@ -0,0 +1,442 @@
+From 4a15ecf11c1492f254643aadfbb047cc5c417e24 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 15 Jun 2017 16:24:01 -0400
+Subject: [PATCH 0311/4131] drm/amd/display: decouple per-crtc-plane model
+
+Current design has per-crtc-plane model.
+As a result, for asic's that support underlay,
+are unable to expose it to user space for modesetting.
+
+To enable this, the drm driver intialisation now runs
+for number of surfaces instead of stream/crtc.
+
+This patch plumbs surface capabilities to drm framework
+so that it can be effectively used by user space.
+
+Tests: (On Chromium OS for Stoney Only)
+* 'modetest -p' now shows additional plane
+ with YUV capabilities in case of CZ and ST.
+* 'plane_test' fails with below error:
+ [drm:amdgpu_dm_connector_atomic_set_property [amdgpu]] *ERROR* Unsupported screen depth 0
+ as ther is no support for YUYV
+* Checked multimonitor display works fine
+
+Signed-off-by: Shirish S <shirish.s@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Kalyan Alle <kalyan.alle@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 8 ++
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 67 ++++++++++++----
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 88 +++++++++++++++-------
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.h | 5 +-
+ drivers/gpu/drm/amd/display/dc/dc.h | 1 +
+ .../drm/amd/display/dc/dce100/dce100_resource.c | 2 +
+ .../drm/amd/display/dc/dce110/dce110_resource.c | 2 +
+ .../drm/amd/display/dc/dce112/dce112_resource.c | 2 +
+ .../drm/amd/display/dc/dce120/dce120_resource.c | 2 +
+ .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 2 +
+ 10 files changed, 133 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+index baf78dd..1b89a18 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+@@ -60,6 +60,7 @@ struct amdgpu_hpd;
+
+ #define AMDGPU_MAX_HPD_PINS 6
+ #define AMDGPU_MAX_CRTCS 6
++#define AMDGPU_MAX_PLANES 6
+ #define AMDGPU_MAX_AFMT_BLOCKS 9
+
+ enum amdgpu_rmx_type {
+@@ -327,6 +328,7 @@ struct amdgpu_mode_info {
+ struct card_info *atom_card_info;
+ bool mode_config_initialized;
+ struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS];
++ struct amdgpu_plane *planes[AMDGPU_MAX_PLANES];
+ struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS];
+ /* DVI-I properties */
+ struct drm_property *coherent_mode_property;
+@@ -360,6 +362,7 @@ struct amdgpu_mode_info {
+ int num_dig; /* number of dig blocks */
+ int disp_priority;
+ const struct amdgpu_display_funcs *funcs;
++ enum drm_plane_type *plane_type;
+ };
+
+ #define AMDGPU_MAX_BL_LEVEL 0xFF
+@@ -440,6 +443,11 @@ struct amdgpu_crtc {
+ struct drm_pending_vblank_event *event;
+ };
+
++struct amdgpu_plane {
++ struct drm_plane base;
++ enum drm_plane_type plane_type;
++};
++
+ struct amdgpu_encoder_atom_dig {
+ bool linkb;
+ /* atom dig */
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index bd52a5c..1a40811 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -49,6 +49,28 @@
+
+ #include "modules/inc/mod_freesync.h"
+
++static enum drm_plane_type dm_surfaces_type_default[AMDGPU_MAX_PLANES] = {
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++};
++
++static enum drm_plane_type dm_surfaces_type_carizzo[AMDGPU_MAX_PLANES] = {
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_OVERLAY,/* YUV Capable Underlay */
++};
++
++static enum drm_plane_type dm_surfaces_type_stoney[AMDGPU_MAX_PLANES] = {
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_PRIMARY,
++ DRM_PLANE_TYPE_OVERLAY, /* YUV Capable Underlay */
++};
++
+ /*
+ * dm_vblank_get_counter
+ *
+@@ -1051,30 +1073,34 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
+ uint32_t i;
+ struct amdgpu_connector *aconnector;
+ struct amdgpu_encoder *aencoder;
+- struct amdgpu_crtc *acrtc;
++ struct amdgpu_mode_info *mode_info = &adev->mode_info;
+ uint32_t link_cnt;
+
+ link_cnt = dm->dc->caps.max_links;
+-
+ if (amdgpu_dm_mode_config_init(dm->adev)) {
+ DRM_ERROR("DM: Failed to initialize mode config\n");
+- return -1;
++ goto fail;
+ }
+
+- for (i = 0; i < dm->dc->caps.max_streams; i++) {
+- acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL);
+- if (!acrtc)
+- goto fail;
++ for (i = 0; i < dm->dc->caps.max_surfaces; i++) {
++ mode_info->planes[i] = kzalloc(sizeof(struct amdgpu_plane),
++ GFP_KERNEL);
++ if (!mode_info->planes[i]) {
++ DRM_ERROR("KMS: Failed to allocate surface\n");
++ goto fail_free_planes;
++ }
++ mode_info->planes[i]->plane_type = mode_info->plane_type[i];
++ if (amdgpu_dm_plane_init(dm, mode_info->planes[i], 1)) {
++ DRM_ERROR("KMS: Failed to initialize plane\n");
++ goto fail_free_planes;
++ }
++ }
+
+- if (amdgpu_dm_crtc_init(
+- dm,
+- acrtc,
+- i)) {
++ for (i = 0; i < dm->dc->caps.max_streams; i++)
++ if (amdgpu_dm_crtc_init(dm, &mode_info->planes[i]->base, i)) {
+ DRM_ERROR("KMS: Failed to initialize crtc\n");
+- kfree(acrtc);
+- goto fail;
++ goto fail_free_planes;
+ }
+- }
+
+ dm->display_indexes_num = dm->dc->caps.max_streams;
+
+@@ -1125,12 +1151,12 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
+ case CHIP_VEGA10:
+ if (dce110_register_irq_handlers(dm->adev)) {
+ DRM_ERROR("DM: Failed to initialize IRQ\n");
+- return -1;
++ goto fail_free_encoder;
+ }
+ break;
+ default:
+ DRM_ERROR("Usupported ASIC type: 0x%X\n", adev->asic_type);
+- return -1;
++ goto fail_free_encoder;
+ }
+
+ drm_mode_config_reset(dm->ddev);
+@@ -1140,6 +1166,9 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
+ kfree(aencoder);
+ fail_free_connector:
+ kfree(aconnector);
++fail_free_planes:
++ for (i = 0; i < dm->dc->caps.max_surfaces; i++)
++ kfree(mode_info->planes[i]);
+ fail:
+ return -1;
+ }
+@@ -1366,33 +1395,39 @@ static int dm_early_init(void *handle)
+ adev->mode_info.num_crtc = 6;
+ adev->mode_info.num_hpd = 6;
+ adev->mode_info.num_dig = 6;
++ adev->mode_info.plane_type = dm_surfaces_type_default;
+ break;
+ case CHIP_FIJI:
+ case CHIP_TONGA:
+ adev->mode_info.num_crtc = 6;
+ adev->mode_info.num_hpd = 6;
+ adev->mode_info.num_dig = 7;
++ adev->mode_info.plane_type = dm_surfaces_type_default;
+ break;
+ case CHIP_CARRIZO:
+ adev->mode_info.num_crtc = 3;
+ adev->mode_info.num_hpd = 6;
+ adev->mode_info.num_dig = 9;
++ adev->mode_info.plane_type = dm_surfaces_type_carizzo;
+ break;
+ case CHIP_STONEY:
+ adev->mode_info.num_crtc = 2;
+ adev->mode_info.num_hpd = 6;
+ adev->mode_info.num_dig = 9;
++ adev->mode_info.plane_type = dm_surfaces_type_stoney;
+ break;
+ case CHIP_POLARIS11:
+ case CHIP_POLARIS12:
+ adev->mode_info.num_crtc = 5;
+ adev->mode_info.num_hpd = 5;
+ adev->mode_info.num_dig = 5;
++ adev->mode_info.plane_type = dm_surfaces_type_default;
+ break;
+ case CHIP_POLARIS10:
+ adev->mode_info.num_crtc = 6;
+ adev->mode_info.num_hpd = 6;
+ adev->mode_info.num_dig = 6;
++ adev->mode_info.plane_type = dm_surfaces_type_default;
+ break;
+ case CHIP_VEGA10:
+ adev->mode_info.num_crtc = 6;
+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 bf645fd..e8de976 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
+@@ -1609,6 +1609,8 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = {
+ };
+
+ static const struct drm_plane_funcs dm_plane_funcs = {
++ .update_plane = drm_atomic_helper_update_plane,
++ .disable_plane = drm_atomic_helper_disable_plane,
+ .reset = drm_atomic_helper_plane_reset,
+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state
+@@ -1740,39 +1742,68 @@ static uint32_t rgb_formats[] = {
+ DRM_FORMAT_ABGR2101010,
+ };
+
++static uint32_t yuv_formats[] = {
++ DRM_FORMAT_YUYV,
++ DRM_FORMAT_YVYU,
++ DRM_FORMAT_UYVY,
++ DRM_FORMAT_VYUY,
++};
++
++int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
++ struct amdgpu_plane *aplane,
++ unsigned long possible_crtcs)
++ {
++ int res = -EPERM;
++
++ switch (aplane->plane_type) {
++ case DRM_PLANE_TYPE_PRIMARY:
++ aplane->base.format_default = true;
++
++ res = drm_universal_plane_init(
++ dm->adev->ddev,
++ &aplane->base,
++ possible_crtcs,
++ &dm_plane_funcs,
++ rgb_formats,
++ ARRAY_SIZE(rgb_formats), NULL,
++ aplane->plane_type, NULL);
++ break;
++ case DRM_PLANE_TYPE_OVERLAY:
++ res = drm_universal_plane_init(
++ dm->adev->ddev,
++ &aplane->base,
++ possible_crtcs,
++ &dm_plane_funcs,
++ yuv_formats,
++ ARRAY_SIZE(yuv_formats), NULL,
++ aplane->plane_type, NULL);
++ break;
++ case DRM_PLANE_TYPE_CURSOR:
++ DRM_ERROR("KMS: Cursor plane not implemented.");
++ break;
++ }
++
++ drm_plane_helper_add(&aplane->base, &dm_plane_helper_funcs);
++ return res;
++}
++
+ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
+- struct amdgpu_crtc *acrtc,
++ struct drm_plane *plane,
+ uint32_t crtc_index)
+ {
++ struct amdgpu_crtc *acrtc;
+ int res = -ENOMEM;
+
+- struct drm_plane *primary_plane =
+- kzalloc(sizeof(*primary_plane), GFP_KERNEL);
+-
+- if (!primary_plane)
+- goto fail_plane;
+-
+- primary_plane->format_default = true;
+-
+- res = drm_universal_plane_init(
+- dm->adev->ddev,
+- primary_plane,
+- 0,
+- &dm_plane_funcs,
+- rgb_formats,
+- ARRAY_SIZE(rgb_formats), NULL,
+- DRM_PLANE_TYPE_PRIMARY, NULL);
+-
+- primary_plane->crtc = &acrtc->base;
+-
+- drm_plane_helper_add(primary_plane, &dm_plane_helper_funcs);
++ acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL);
++ if (!acrtc)
++ goto fail;
+
+- res = drm_crtc_init_with_planes(
+- dm->ddev,
+- &acrtc->base,
+- primary_plane,
+- NULL,
+- &amdgpu_dm_crtc_funcs, NULL);
++ res = drm_crtc_init_with_planes(
++ dm->ddev,
++ &acrtc->base,
++ plane,
++ NULL,
++ &amdgpu_dm_crtc_funcs, NULL);
+
+ if (res)
+ goto fail;
+@@ -1790,8 +1821,7 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
+
+ return 0;
+ fail:
+- kfree(primary_plane);
+-fail_plane:
++ kfree(acrtc);
+ acrtc->crtc_id = -1;
+ return res;
+ }
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.h
+index 1bbeb87..ab6d51d 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.h
+@@ -34,8 +34,11 @@ struct dc_validation_set;
+ struct dc_surface;
+
+ /*TODO Jodan Hersen use the one in amdgpu_dm*/
++int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
++ struct amdgpu_plane *aplane,
++ unsigned long possible_crtcs);
+ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
+- struct amdgpu_crtc *amdgpu_crtc,
++ struct drm_plane *plane,
+ uint32_t link_index);
+ int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
+ struct amdgpu_connector *amdgpu_connector,
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index 0731045..9dd8b2a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -45,6 +45,7 @@ struct dc_caps {
+ uint32_t max_links;
+ uint32_t max_audios;
+ uint32_t max_slave_planes;
++ uint32_t max_surfaces;
+ uint32_t max_downscale_ratio;
+ uint32_t i2c_speed_in_khz;
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+index b6f77f8..d1685df 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+@@ -1035,6 +1035,8 @@ static bool construct(
+ }
+ }
+
++ dc->public.caps.max_surfaces = pool->base.pipe_count;
++
+ if (!resource_construct(num_virtual_links, dc, &pool->base,
+ &res_create_funcs))
+ goto res_create_fail;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+index e300203..065a298 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+@@ -1455,6 +1455,8 @@ static bool construct(
+ if (!dce110_hw_sequencer_construct(dc))
+ goto res_create_fail;
+
++ dc->public.caps.max_surfaces = pool->base.pipe_count;
++
+ bw_calcs_init(&dc->bw_dceip, &dc->bw_vbios, dc->ctx->asic_id);
+
+ bw_calcs_data_update_from_pplib(dc);
+diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+index 32aa1b5..ece3ec7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+@@ -1409,6 +1409,8 @@ static bool construct(
+ &res_create_funcs))
+ goto res_create_fail;
+
++ dc->public.caps.max_surfaces = pool->base.pipe_count;
++
+ /* Create hardware sequencer */
+ if (!dce112_hw_sequencer_construct(dc))
+ goto res_create_fail;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+index efa5888..f677a77 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+@@ -1060,6 +1060,8 @@ static bool construct(
+ if (!dce120_hw_sequencer_create(dc))
+ goto controller_create_fail;
+
++ dc->public.caps.max_surfaces = pool->base.pipe_count;
++
+ bw_calcs_init(&dc->bw_dceip, &dc->bw_vbios, dc->ctx->asic_id);
+
+ bw_calcs_data_update_from_pplib(dc);
+diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+index a3e8182..752e0e7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+@@ -1043,6 +1043,8 @@ static bool construct(
+ }
+ }
+
++ dc->public.caps.max_surfaces = pool->base.pipe_count;
++
+ if (!resource_construct(num_virtual_links, dc, &pool->base,
+ &res_create_funcs))
+ goto res_create_fail;
+--
+2.7.4
+