aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c48
1 files changed, 33 insertions, 15 deletions
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 c96407379224..d743e2705399 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -368,15 +368,6 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
return false;
}
-static inline void reverse_planes_order(struct dc_surface_update *array_of_surface_update,
- int planes_count)
-{
- int i, j;
-
- for (i = 0, j = planes_count - 1; i < j; i++, j--)
- swap(array_of_surface_update[i], array_of_surface_update[j]);
-}
-
/*
* DC will program planes with their z-order determined by their ordering
* in the dc_surface_updates array. This comparator is used to sort them
@@ -1302,6 +1293,7 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev)
struct dmub_srv *dmub_srv = adev->dm.dmub_srv;
enum dmub_status status;
bool init;
+ int r;
if (!dmub_srv) {
/* DMUB isn't supported on the ASIC. */
@@ -1319,7 +1311,9 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev)
DRM_WARN("Wait for DMUB auto-load failed: %d\n", status);
} else {
/* Perform the full hardware initialization. */
- dm_dmub_hw_init(adev);
+ r = dm_dmub_hw_init(adev);
+ if (r)
+ DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
}
}
@@ -11090,8 +11084,12 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
int cursor_scale_w, cursor_scale_h;
int i;
- /* Overlay cursor not supported on HW before DCN */
- if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) {
+ /* Overlay cursor not supported on HW before DCN
+ * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions
+ * as previous DCN generations, so enable native mode on DCN401 in addition to DCE
+ */
+ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 ||
+ amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
*cursor_mode = DM_CURSOR_NATIVE_MODE;
return 0;
}
@@ -11234,7 +11232,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_plane *plane;
- struct drm_plane_state *old_plane_state, *new_plane_state;
+ struct drm_plane_state *old_plane_state, *new_plane_state, *new_cursor_state;
enum dc_status status;
int ret, i;
bool lock_and_validation_needed = false;
@@ -11462,19 +11460,39 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
drm_dbg_atomic(dev, "MPO enablement requested on crtc:[%p]\n", crtc);
}
- /* Check cursor planes restrictions */
+ /* Check cursor restrictions */
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
enum amdgpu_dm_cursor_mode required_cursor_mode;
+ int is_rotated, is_scaled;
/* Overlay cusor not subject to native cursor restrictions */
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE)
continue;
+ /* Check if rotation or scaling is enabled on DCN401 */
+ if ((drm_plane_mask(crtc->cursor) & new_crtc_state->plane_mask) &&
+ amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
+ new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
+
+ is_rotated = new_cursor_state &&
+ ((new_cursor_state->rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0);
+ is_scaled = new_cursor_state && ((new_cursor_state->src_w >> 16 != new_cursor_state->crtc_w) ||
+ (new_cursor_state->src_h >> 16 != new_cursor_state->crtc_h));
+
+ if (is_rotated || is_scaled) {
+ drm_dbg_driver(
+ crtc->dev,
+ "[CRTC:%d:%s] cannot enable hardware cursor due to rotation/scaling\n",
+ crtc->base.id, crtc->name);
+ ret = -EINVAL;
+ goto fail;
+ }
+ }
+
/* If HW can only do native cursor, check restrictions again */
ret = dm_crtc_get_cursor_mode(adev, state, dm_new_crtc_state,
&required_cursor_mode);
-
if (ret) {
drm_dbg_driver(crtc->dev,
"[CRTC:%d:%s] Checking cursor mode failed\n",