diff options
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.patch | 442 |
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 + |