mirror of
https://github.com/torvalds/linux.git
synced 2026-04-20 07:43:57 -04:00
Merge drm/drm-next into drm-misc-next
Backmerging to get v5.12 fixes. Requested for vmwgfx. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
This commit is contained in:
@@ -2552,11 +2552,14 @@ static void handle_hpd_irq(void *param)
|
||||
struct drm_connector *connector = &aconnector->base;
|
||||
struct drm_device *dev = connector->dev;
|
||||
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state);
|
||||
#endif
|
||||
|
||||
if (adev->dm.disable_hpd_irq)
|
||||
return;
|
||||
|
||||
/*
|
||||
* In case of failure or MST no need to update connector status or notify the OS
|
||||
* since (for MST case) MST does this in its own context.
|
||||
@@ -2696,6 +2699,10 @@ static void handle_hpd_rx_irq(void *param)
|
||||
|
||||
memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
|
||||
|
||||
if (adev->dm.disable_hpd_irq)
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
|
||||
* conflict, after implement i2c helper, this mutex should be
|
||||
@@ -4008,6 +4015,23 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
|
||||
scaling_info->src_rect.x = state->src_x >> 16;
|
||||
scaling_info->src_rect.y = state->src_y >> 16;
|
||||
|
||||
/*
|
||||
* For reasons we don't (yet) fully understand a non-zero
|
||||
* src_y coordinate into an NV12 buffer can cause a
|
||||
* system hang. To avoid hangs (and maybe be overly cautious)
|
||||
* let's reject both non-zero src_x and src_y.
|
||||
*
|
||||
* We currently know of only one use-case to reproduce a
|
||||
* scenario with non-zero src_x and src_y for NV12, which
|
||||
* is to gesture the YouTube Android app into full screen
|
||||
* on ChromeOS.
|
||||
*/
|
||||
if (state->fb &&
|
||||
state->fb->format->format == DRM_FORMAT_NV12 &&
|
||||
(scaling_info->src_rect.x != 0 ||
|
||||
scaling_info->src_rect.y != 0))
|
||||
return -EINVAL;
|
||||
|
||||
scaling_info->src_rect.width = state->src_w >> 16;
|
||||
if (scaling_info->src_rect.width == 0)
|
||||
return -EINVAL;
|
||||
@@ -4225,6 +4249,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(plane->dev);
|
||||
const struct drm_format_info *info = drm_format_info(format);
|
||||
int i;
|
||||
|
||||
enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
|
||||
|
||||
@@ -4232,17 +4257,21 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
|
||||
return false;
|
||||
|
||||
/*
|
||||
* We always have to allow this modifier, because core DRM still
|
||||
* checks LINEAR support if userspace does not provide modifers.
|
||||
* We always have to allow these modifiers:
|
||||
* 1. Core DRM checks for LINEAR support if userspace does not provide modifiers.
|
||||
* 2. Not passing any modifiers is the same as explicitly passing INVALID.
|
||||
*/
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR)
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR ||
|
||||
modifier == DRM_FORMAT_MOD_INVALID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The arbitrary tiling support for multiplane formats has not been hooked
|
||||
* up.
|
||||
*/
|
||||
if (info->num_planes > 1)
|
||||
/* Check that the modifier is on the list of the plane's supported modifiers. */
|
||||
for (i = 0; i < plane->modifier_count; i++) {
|
||||
if (modifier == plane->modifiers[i])
|
||||
break;
|
||||
}
|
||||
if (i == plane->modifier_count)
|
||||
return false;
|
||||
|
||||
/*
|
||||
@@ -4263,6 +4292,10 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
|
||||
/* Per radeonsi comments 16/64 bpp are more complicated. */
|
||||
if (info->cpp[0] != 4)
|
||||
return false;
|
||||
/* We support multi-planar formats, but not when combined with
|
||||
* additional DCC metadata planes. */
|
||||
if (info->num_planes > 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -4463,7 +4496,7 @@ add_gfx10_3_modifiers(const struct amdgpu_device *adev,
|
||||
AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
|
||||
|
||||
add_modifier(mods, size, capacity, AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
|
||||
@@ -4475,7 +4508,7 @@ add_gfx10_3_modifiers(const struct amdgpu_device *adev,
|
||||
AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
|
||||
|
||||
add_modifier(mods, size, capacity, AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
|
||||
@@ -9832,6 +9865,53 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
|
||||
}
|
||||
#endif
|
||||
|
||||
static int validate_overlay(struct drm_atomic_state *state)
|
||||
{
|
||||
int i;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *old_plane_state, *new_plane_state;
|
||||
struct drm_plane_state *primary_state, *overlay_state = NULL;
|
||||
|
||||
/* Check if primary plane is contained inside overlay */
|
||||
for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
|
||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
|
||||
if (drm_atomic_plane_disabling(plane->state, new_plane_state))
|
||||
return 0;
|
||||
|
||||
overlay_state = new_plane_state;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if we're making changes to the overlay plane */
|
||||
if (!overlay_state)
|
||||
return 0;
|
||||
|
||||
/* check if overlay plane is enabled */
|
||||
if (!overlay_state->crtc)
|
||||
return 0;
|
||||
|
||||
/* find the primary plane for the CRTC that the overlay is enabled on */
|
||||
primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary);
|
||||
if (IS_ERR(primary_state))
|
||||
return PTR_ERR(primary_state);
|
||||
|
||||
/* check if primary plane is enabled */
|
||||
if (!primary_state->crtc)
|
||||
return 0;
|
||||
|
||||
/* Perform the bounds check to ensure the overlay plane covers the primary */
|
||||
if (primary_state->crtc_x < overlay_state->crtc_x ||
|
||||
primary_state->crtc_y < overlay_state->crtc_y ||
|
||||
primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w ||
|
||||
primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) {
|
||||
DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
|
||||
* @dev: The DRM device
|
||||
@@ -10006,6 +10086,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = validate_overlay(state);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* Add new/modified planes */
|
||||
for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
|
||||
ret = dm_update_plane_state(dc, state, plane,
|
||||
|
||||
Reference in New Issue
Block a user