diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0487-drm-amd-display-Universal-cursor-plane-hook-up.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0487-drm-amd-display-Universal-cursor-plane-hook-up.patch | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0487-drm-amd-display-Universal-cursor-plane-hook-up.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0487-drm-amd-display-Universal-cursor-plane-hook-up.patch new file mode 100644 index 00000000..b0c50f10 --- /dev/null +++ b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0487-drm-amd-display-Universal-cursor-plane-hook-up.patch @@ -0,0 +1,404 @@ +From 07f8ab34f839cfcbc0d0b64f161df4dc11564f22 Mon Sep 17 00:00:00 2001 +From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> +Date: Sun, 2 Apr 2017 11:55:41 -0400 +Subject: [PATCH 0487/4131] drm/amd/display: Universal cursor plane hook-up. + +Switch from legacy cursor to DRM cursor plane. Cursor +is not an actual plane but more of a subplane of each +pipe. Bind a DRM cursor plane instance to each CRTC. +Eliminate seperate FB object allocation for cursor and +clean dm_crtc_cursor_set. + +Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> +Signed-off-by: Leo (Sunpeng) Li <sunpeng.li@amd.com> +Reviewed-by: Harry Wentland <Harry.Wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> +--- + .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 240 ++++++++------------- + 1 file changed, 89 insertions(+), 151 deletions(-) + +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 d93c17f..e6eaea9 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 +@@ -135,127 +135,27 @@ static void dm_set_cursor( + } + } + +-static int dm_crtc_unpin_cursor_bo_old( +- struct amdgpu_crtc *amdgpu_crtc) +-{ +- struct amdgpu_bo *robj; +- int ret = 0; +- +- if (NULL != amdgpu_crtc && NULL != amdgpu_crtc->cursor_bo) { +- robj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); +- +- ret = amdgpu_bo_reserve(robj, false); +- +- if (likely(ret == 0)) { +- ret = amdgpu_bo_unpin(robj); +- +- if (unlikely(ret != 0)) { +- DRM_ERROR( +- "%s: unpin failed (ret=%d), bo %p\n", +- __func__, +- ret, +- amdgpu_crtc->cursor_bo); +- } +- +- amdgpu_bo_unreserve(robj); +- } else { +- DRM_ERROR( +- "%s: reserve failed (ret=%d), bo %p\n", +- __func__, +- ret, +- amdgpu_crtc->cursor_bo); +- } +- +- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo); +- amdgpu_crtc->cursor_bo = NULL; +- } +- +- return ret; +-} +- +-static int dm_crtc_pin_cursor_bo_new( +- struct drm_crtc *crtc, +- struct drm_file *file_priv, +- uint32_t handle, +- struct amdgpu_bo **ret_obj) +-{ +- struct amdgpu_crtc *amdgpu_crtc; +- struct amdgpu_bo *robj; +- struct drm_gem_object *obj; +- int ret = -EINVAL; +- +- if (NULL != crtc) { +- struct drm_device *dev = crtc->dev; +- struct amdgpu_device *adev = dev->dev_private; +- uint64_t gpu_addr; +- +- amdgpu_crtc = to_amdgpu_crtc(crtc); +- +- obj = drm_gem_object_lookup(file_priv, handle); +- +- if (!obj) { +- DRM_ERROR( +- "Cannot find cursor object %x for crtc %d\n", +- handle, +- amdgpu_crtc->crtc_id); +- goto release; +- } +- robj = gem_to_amdgpu_bo(obj); +- +- ret = amdgpu_bo_reserve(robj, false); +- +- if (unlikely(ret != 0)) { +- drm_gem_object_unreference_unlocked(obj); +- DRM_ERROR("dm_crtc_pin_cursor_bo_new ret %x, handle %x\n", +- ret, handle); +- goto release; +- } +- +- ret = amdgpu_bo_pin_restricted(robj, AMDGPU_GEM_DOMAIN_VRAM, 0, +- adev->mc.visible_vram_size, +- &gpu_addr); +- +- if (ret == 0) { +- amdgpu_crtc->cursor_addr = gpu_addr; +- *ret_obj = robj; +- } +- amdgpu_bo_unreserve(robj); +- if (ret) +- drm_gem_object_unreference_unlocked(obj); +- +- } +-release: +- +- return ret; +-} +- + static int dm_crtc_cursor_set( + struct drm_crtc *crtc, +- struct drm_file *file_priv, +- uint32_t handle, ++ uint64_t address, + uint32_t width, + uint32_t height) + { +- struct amdgpu_bo *new_cursor_bo; + struct dc_cursor_position position; + + int ret; + + struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); +- + ret = EINVAL; +- new_cursor_bo = NULL; + + DRM_DEBUG_KMS( +- "%s: crtc_id=%d with handle %d and size %d to %d, bo_object %p\n", ++ "%s: crtc_id=%d with size %d to %d \n", + __func__, + amdgpu_crtc->crtc_id, +- handle, + width, +- height, +- amdgpu_crtc->cursor_bo); ++ height); + +- if (!handle) { ++ if (!address) { + /* turn off cursor */ + position.enable = false; + position.x = 0; +@@ -267,8 +167,6 @@ static int dm_crtc_cursor_set( + amdgpu_crtc->stream, + &position); + } +- /*unpin old cursor buffer and update cache*/ +- ret = dm_crtc_unpin_cursor_bo_old(amdgpu_crtc); + goto release; + + } +@@ -282,21 +180,9 @@ static int dm_crtc_cursor_set( + height); + goto release; + } +- /*try to pin new cursor bo*/ +- ret = dm_crtc_pin_cursor_bo_new(crtc, file_priv, handle, &new_cursor_bo); +- /*if map not successful then return an error*/ +- if (ret) +- goto release; + + /*program new cursor bo to hardware*/ +- dm_set_cursor(amdgpu_crtc, amdgpu_crtc->cursor_addr, width, height); +- +- /*un map old, not used anymore cursor bo , +- * return memory and mapping back */ +- dm_crtc_unpin_cursor_bo_old(amdgpu_crtc); +- +- /*assign new cursor bo to our internal cache*/ +- amdgpu_crtc->cursor_bo = &new_cursor_bo->gem_base; ++ dm_set_cursor(amdgpu_crtc, address, width, height); + + release: + return ret; +@@ -358,23 +244,6 @@ static int dm_crtc_cursor_move(struct drm_crtc *crtc, + return 0; + } + +-static void dm_crtc_cursor_reset(struct drm_crtc *crtc) +-{ +- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); +- +- DRM_DEBUG_KMS( +- "%s: with cursor_bo %p\n", +- __func__, +- amdgpu_crtc->cursor_bo); +- +- if (amdgpu_crtc->cursor_bo && amdgpu_crtc->stream) { +- dm_set_cursor( +- amdgpu_crtc, +- amdgpu_crtc->cursor_addr, +- amdgpu_crtc->cursor_width, +- amdgpu_crtc->cursor_height); +- } +-} + static bool fill_rects_from_plane_state( + const struct drm_plane_state *state, + struct dc_surface *surface) +@@ -1156,8 +1025,6 @@ static int amdgpu_atomic_helper_page_flip(struct drm_crtc *crtc, + /* Implemented only the options currently availible for the driver */ + static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { + .reset = drm_atomic_helper_crtc_reset, +- .cursor_set = dm_crtc_cursor_set, +- .cursor_move = dm_crtc_cursor_move, + .destroy = amdgpu_dm_crtc_destroy, + .gamma_set = drm_atomic_helper_legacy_gamma_set, + .set_config = drm_atomic_helper_set_config, +@@ -1726,6 +1593,18 @@ static int dm_plane_helper_prepare_fb( + } + + amdgpu_bo_ref(rbo); ++ ++ /* It's a hack for s3 since in 4.9 kernel filter out cursor buffer ++ * prepare and cleanup in drm_atomic_helper_prepare_planes ++ * and drm_atomic_helper_cleanup_planes because fb doens't in s3. ++ * IN 4.10 kernel this code should be removed and amdgpu_device_suspend ++ * code touching fram buffers should be avoided for DC. ++ */ ++ if (plane->type == DRM_PLANE_TYPE_CURSOR) { ++ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(new_state->crtc); ++ ++ acrtc->cursor_bo = obj; ++ } + return 0; + } + +@@ -1823,6 +1702,10 @@ static uint32_t yuv_formats[] = { + DRM_FORMAT_NV21, + }; + ++static const u32 cursor_formats[] = { ++ DRM_FORMAT_ARGB8888 ++}; ++ + int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, + struct amdgpu_plane *aplane, + unsigned long possible_crtcs) +@@ -1853,7 +1736,14 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, + aplane->plane_type, NULL); + break; + case DRM_PLANE_TYPE_CURSOR: +- DRM_ERROR("KMS: Cursor plane not implemented."); ++ res = drm_universal_plane_init( ++ dm->adev->ddev, ++ &aplane->base, ++ possible_crtcs, ++ &dm_plane_funcs, ++ cursor_formats, ++ ARRAY_SIZE(cursor_formats), NULL, ++ aplane->plane_type, NULL); + break; + } + +@@ -1865,9 +1755,18 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, + struct drm_plane *plane, + uint32_t crtc_index) + { +- struct amdgpu_crtc *acrtc; ++ struct amdgpu_crtc *acrtc = NULL; ++ struct amdgpu_plane *cursor_plane; ++ + int res = -ENOMEM; + ++ cursor_plane = kzalloc(sizeof(*cursor_plane), GFP_KERNEL); ++ if (!cursor_plane) ++ goto fail; ++ ++ cursor_plane->base.type = DRM_PLANE_TYPE_CURSOR; ++ res = amdgpu_dm_plane_init(dm, cursor_plane, 0); ++ + acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); + if (!acrtc) + goto fail; +@@ -1876,7 +1775,7 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, + dm->ddev, + &acrtc->base, + plane, +- NULL, ++ &cursor_plane->base, + &amdgpu_dm_crtc_funcs, NULL); + + if (res) +@@ -1895,7 +1794,10 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, + + return 0; + fail: +- kfree(acrtc); ++ if (acrtc) ++ kfree(acrtc); ++ if (cursor_plane) ++ kfree(cursor_plane); + acrtc->crtc_id = -1; + return res; + } +@@ -2414,6 +2316,34 @@ static void remove_stream(struct amdgpu_device *adev, struct amdgpu_crtc *acrtc) + acrtc->enabled = false; + } + ++static void handle_cursor_update( ++ struct drm_plane *plane, ++ struct drm_plane_state *old_plane_state) ++{ ++ if (!plane->state->fb && !old_plane_state->fb) ++ return; ++ ++ /* Check if it's a cursor on/off update or just cursor move*/ ++ if (plane->state->fb == old_plane_state->fb) ++ dm_crtc_cursor_move( ++ plane->state->crtc, ++ plane->state->crtc_x, ++ plane->state->crtc_y); ++ else { ++ struct amdgpu_framebuffer *afb = ++ to_amdgpu_framebuffer(plane->state->fb); ++ dm_crtc_cursor_set( ++ (!!plane->state->fb) ? ++ plane->state->crtc : ++ old_plane_state->crtc, ++ (!!plane->state->fb) ? ++ afb->address : ++ 0, ++ plane->state->crtc_w, ++ plane->state->crtc_h); ++ } ++} ++ + + /* + * Executes flip +@@ -2505,6 +2435,11 @@ static void amdgpu_dm_commit_surfaces(struct drm_atomic_state *state, + struct dm_connector_state *con_state = NULL; + bool pflip_needed; + ++ if (plane->type == DRM_PLANE_TYPE_CURSOR) { ++ handle_cursor_update(plane, old_plane_state); ++ continue; ++ } ++ + if (!fb || !crtc || !crtc->state->active) + continue; + +@@ -2789,7 +2724,6 @@ void amdgpu_dm_atomic_commit_tail( + adev->dm.freesync_module, &acrtc->stream, 1); + + manage_dm_interrupts(adev, acrtc, true); +- dm_crtc_cursor_reset(&acrtc->base); + } + + +@@ -3169,18 +3103,19 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + } + } + ++ + /* +- * TODO revisit when removing commit action +- * and looking at atomic flags directly ++ * Hack: Commit needs planes right now, specifically for gamma ++ * TODO rework commit to check CRTC for gamma change + */ ++ if (crtc_state->color_mgmt_changed) { + +- /* commit needs planes right now (for gamma, eg.) */ +- /* TODO rework commit to chack crtc for gamma change */ +- ret = drm_atomic_add_affected_planes(state, crtc); +- if (ret) +- return ret; ++ ret = drm_atomic_add_affected_planes(state, crtc); ++ if (ret) ++ return ret; + +- ret = -EINVAL; ++ ret = -EINVAL; ++ } + } + + /* Check scaling and undersacn changes*/ +@@ -3235,6 +3170,9 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, + struct drm_crtc_state *crtc_state; + bool pflip_needed; + ++ /*TODO Implement atomic check for cursor plane */ ++ if (plane->type == DRM_PLANE_TYPE_CURSOR) ++ continue; + + if (!fb || !crtc || crtc_set[i] != crtc || + !crtc->state->planes_changed || !crtc->state->active) +-- +2.7.4 + |