new_acrtc = to_amdgpu_crtc(new_plane_crtc);
 
-               if ((new_plane_state->crtc_w > new_acrtc->max_cursor_width) ||
-                       (new_plane_state->crtc_h > new_acrtc->max_cursor_height)) {
-                       DRM_DEBUG_ATOMIC("Bad cursor size %d x %d\n",
-                                                        new_plane_state->crtc_w, new_plane_state->crtc_h);
-                       return -EINVAL;
-               }
-
                if (new_plane_state->src_x != 0 || new_plane_state->src_y != 0) {
                        DRM_DEBUG_ATOMIC("Cropping not supported for cursor plane\n");
                        return -EINVAL;
        return ret;
 }
 
+static int dm_check_crtc_cursor(struct drm_atomic_state *state,
+                               struct drm_crtc *crtc,
+                               struct drm_crtc_state *new_crtc_state)
+{
+       struct drm_plane_state *new_cursor_state, *new_primary_state;
+       int cursor_scale_w, cursor_scale_h, primary_scale_w, primary_scale_h;
+
+       /* On DCE and DCN there is no dedicated hardware cursor plane. We get a
+        * cursor per pipe but it's going to inherit the scaling and
+        * positioning from the underlying pipe. Check the cursor plane's
+        * blending properties match the primary plane's. */
+
+       new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
+       new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary);
+       if (!new_cursor_state || !new_primary_state || !new_cursor_state->fb) {
+               return 0;
+       }
+
+       cursor_scale_w = new_cursor_state->crtc_w * 1000 /
+                        (new_cursor_state->src_w >> 16);
+       cursor_scale_h = new_cursor_state->crtc_h * 1000 /
+                        (new_cursor_state->src_h >> 16);
+
+       primary_scale_w = new_primary_state->crtc_w * 1000 /
+                        (new_primary_state->src_w >> 16);
+       primary_scale_h = new_primary_state->crtc_h * 1000 /
+                        (new_primary_state->src_h >> 16);
+
+       if (cursor_scale_w != primary_scale_w ||
+           cursor_scale_h != primary_scale_h) {
+               DRM_DEBUG_ATOMIC("Cursor plane scaling doesn't match primary plane\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm_crtc *crtc)
 {
        if (ret)
                goto fail;
 
+       /* Check cursor planes scaling */
+       for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+               ret = dm_check_crtc_cursor(state, crtc, new_crtc_state);
+               if (ret)
+                       goto fail;
+       }
+
        if (state->legacy_cursor_update) {
                /*
                 * This is a fast cursor update coming from the plane update