mirror of
https://github.com/torvalds/linux.git
synced 2026-04-19 23:34:00 -04:00
Merge tag 'amd-drm-next-5.14-2021-06-02' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.14-2021-06-02:
amdgpu:
- GC/MM register access macro clean up for SR-IOV
- Beige Goby updates
- W=1 Fixes
- Aldebaran fixes
- Misc display fixes
- ACPI ATCS/ATIF handling rework
- SR-IOV fixes
- RAS fixes
- 16bpc fixed point format support
- Initial smartshift support
- RV/PCO power tuning fixes for suspend/resume
- More buffer object subclassing work
- Add new INFO query for additional vbios information
- Add new placement for preemptable SG buffers
amdkfd:
- Misc fixes
radeon:
- W=1 Fixes
- Misc cleanups
UAPI:
- Add new INFO query for additional vbios information
Useful for debugging vbios related issues. Proposed umr patch:
https://patchwork.freedesktop.org/patch/433297/
- 16bpc fixed point format support
IGT test:
https://lists.freedesktop.org/archives/igt-dev/2021-May/031507.html
Proposed Vulkan patch:
a25d480207
- Add a new GEM flag which is only used internally in the kernel driver. Userspace
is not allowed to set it.
drm:
- 16bpc fixed point format fourcc
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210602214009.4553-1-alexander.deucher@amd.com
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "dm_services_types.h"
|
||||
#include "dc.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dc/inc/core_types.h"
|
||||
#include "dal_asic_id.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
@@ -314,10 +315,8 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev,
|
||||
struct drm_crtc *crtc;
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
|
||||
if (otg_inst == -1) {
|
||||
WARN_ON(1);
|
||||
if (WARN_ON(otg_inst == -1))
|
||||
return adev->mode_info.crtcs[0];
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
@@ -396,8 +395,7 @@ static void dm_pflip_high_irq(void *interrupt_params)
|
||||
e = amdgpu_crtc->event;
|
||||
amdgpu_crtc->event = NULL;
|
||||
|
||||
if (!e)
|
||||
WARN_ON(1);
|
||||
WARN_ON(!e);
|
||||
|
||||
vrr_active = amdgpu_dm_vrr_active_irq(amdgpu_crtc);
|
||||
|
||||
@@ -600,14 +598,14 @@ static void dm_crtc_high_irq(void *interrupt_params)
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
/**
|
||||
* dm_dcn_vertical_interrupt0_high_irq() - Handles OTG Vertical interrupt0 for
|
||||
* DCN generation ASICs
|
||||
* @interrupt params - interrupt parameters
|
||||
* @interrupt_params: interrupt parameters
|
||||
*
|
||||
* Used to set crc window/read out crc value at vertical line 0 position
|
||||
*/
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
static void dm_dcn_vertical_interrupt0_high_irq(void *interrupt_params)
|
||||
{
|
||||
struct common_irq_params *irq_params = interrupt_params;
|
||||
@@ -981,7 +979,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
|
||||
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
}
|
||||
|
||||
adev->dm.dc->ctx->dmub_srv = dc_dmub_srv_create(adev->dm.dc, dmub_srv);
|
||||
if (!adev->dm.dc->ctx->dmub_srv)
|
||||
adev->dm.dc->ctx->dmub_srv = dc_dmub_srv_create(adev->dm.dc, dmub_srv);
|
||||
if (!adev->dm.dc->ctx->dmub_srv) {
|
||||
DRM_ERROR("Couldn't allocate DC DMUB server!\n");
|
||||
return -ENOMEM;
|
||||
@@ -1335,10 +1334,7 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adev->dm.dc->ctx->dmub_srv) {
|
||||
dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
|
||||
adev->dm.dc->ctx->dmub_srv = NULL;
|
||||
}
|
||||
dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
|
||||
|
||||
if (dc_enable_dmub_notifications(adev->dm.dc)) {
|
||||
kfree(adev->dm.dmub_notify);
|
||||
@@ -1715,7 +1711,6 @@ static int dm_late_init(void *handle)
|
||||
unsigned int linear_lut[16];
|
||||
int i;
|
||||
struct dmcu *dmcu = NULL;
|
||||
bool ret = true;
|
||||
|
||||
dmcu = adev->dm.dc->res_pool->dmcu;
|
||||
|
||||
@@ -1732,18 +1727,23 @@ static int dm_late_init(void *handle)
|
||||
* 0xFFFF x 0.01 = 0x28F
|
||||
*/
|
||||
params.min_abm_backlight = 0x28F;
|
||||
|
||||
/* In the case where abm is implemented on dmcub,
|
||||
* dmcu object will be null.
|
||||
* ABM 2.4 and up are implemented on dmcub.
|
||||
*/
|
||||
if (dmcu)
|
||||
ret = dmcu_load_iram(dmcu, params);
|
||||
else if (adev->dm.dc->ctx->dmub_srv)
|
||||
ret = dmub_init_abm_config(adev->dm.dc->res_pool, params);
|
||||
* dmcu object will be null.
|
||||
* ABM 2.4 and up are implemented on dmcub.
|
||||
*/
|
||||
if (dmcu) {
|
||||
if (!dmcu_load_iram(dmcu, params))
|
||||
return -EINVAL;
|
||||
} else if (adev->dm.dc->ctx->dmub_srv) {
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
int edp_num;
|
||||
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
get_edp_links(adev->dm.dc, edp_links, &edp_num);
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
if (!dmub_init_abm_config(adev->dm.dc->res_pool, params, i))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return detect_mst_link_for_all_connectors(adev_to_drm(adev));
|
||||
}
|
||||
@@ -2008,7 +2008,6 @@ static int dm_suspend(void *handle)
|
||||
|
||||
amdgpu_dm_irq_suspend(adev);
|
||||
|
||||
|
||||
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
|
||||
|
||||
return 0;
|
||||
@@ -2747,6 +2746,7 @@ static void handle_hpd_rx_irq(void *param)
|
||||
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
union hpd_irq_data hpd_irq_data;
|
||||
bool lock_flag = 0;
|
||||
|
||||
memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
|
||||
|
||||
@@ -2776,15 +2776,28 @@ static void handle_hpd_rx_irq(void *param)
|
||||
}
|
||||
}
|
||||
|
||||
if (!amdgpu_in_reset(adev)) {
|
||||
/*
|
||||
* TODO: We need the lock to avoid touching DC state while it's being
|
||||
* modified during automated compliance testing, or when link loss
|
||||
* happens. While this should be split into subhandlers and proper
|
||||
* interfaces to avoid having to conditionally lock like this in the
|
||||
* outer layer, we need this workaround temporarily to allow MST
|
||||
* lightup in some scenarios to avoid timeout.
|
||||
*/
|
||||
if (!amdgpu_in_reset(adev) &&
|
||||
(hpd_rx_irq_check_link_loss_status(dc_link, &hpd_irq_data) ||
|
||||
hpd_irq_data.bytes.device_service_irq.bits.AUTOMATED_TEST)) {
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
lock_flag = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL);
|
||||
#else
|
||||
result = dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL);
|
||||
#endif
|
||||
if (!amdgpu_in_reset(adev) && lock_flag)
|
||||
mutex_unlock(&adev->dm.dc_lock);
|
||||
}
|
||||
|
||||
out:
|
||||
if (result && !is_mst_root_connector) {
|
||||
@@ -3407,7 +3420,7 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
|
||||
if (dm->backlight_caps.caps_valid)
|
||||
return;
|
||||
|
||||
amdgpu_acpi_get_backlight_caps(dm->adev, &caps);
|
||||
amdgpu_acpi_get_backlight_caps(&caps);
|
||||
if (caps.caps_valid) {
|
||||
dm->backlight_caps.caps_valid = true;
|
||||
if (caps.aux_support)
|
||||
@@ -3499,7 +3512,7 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
rc = dc_link_set_backlight_level_nits(link[i], true, brightness[i],
|
||||
AUX_BL_DEFAULT_TRANSITION_TIME_MS);
|
||||
if (!rc) {
|
||||
DRM_ERROR("DM: Failed to update backlight via AUX on eDP[%d]\n", i);
|
||||
DRM_DEBUG("DM: Failed to update backlight via AUX on eDP[%d]\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3507,7 +3520,7 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
for (i = 0; i < dm->num_of_edps; i++) {
|
||||
rc = dc_link_set_backlight_level(dm->backlight_link[i], brightness[i], 0);
|
||||
if (!rc) {
|
||||
DRM_ERROR("DM: Failed to update backlight on eDP[%d]\n", i);
|
||||
DRM_DEBUG("DM: Failed to update backlight on eDP[%d]\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4953,6 +4966,14 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
||||
case DRM_FORMAT_ABGR16161616F:
|
||||
plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F;
|
||||
break;
|
||||
case DRM_FORMAT_XRGB16161616:
|
||||
case DRM_FORMAT_ARGB16161616:
|
||||
plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616;
|
||||
break;
|
||||
case DRM_FORMAT_XBGR16161616:
|
||||
case DRM_FORMAT_ABGR16161616:
|
||||
plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR(
|
||||
"Unsupported screen format %p4cc\n",
|
||||
@@ -5529,6 +5550,63 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
|
||||
struct dc_sink *sink, struct dc_stream_state *stream,
|
||||
struct dsc_dec_dpcd_caps *dsc_caps)
|
||||
{
|
||||
stream->timing.flags.DSC = 0;
|
||||
|
||||
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
|
||||
dsc_caps);
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
||||
struct dc_sink *sink, struct dc_stream_state *stream,
|
||||
struct dsc_dec_dpcd_caps *dsc_caps)
|
||||
{
|
||||
struct drm_connector *drm_connector = &aconnector->base;
|
||||
uint32_t link_bandwidth_kbps;
|
||||
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
dc_link_get_link_cap(aconnector->dc_link));
|
||||
/* Set DSC policy according to dsc_clock_en */
|
||||
dc_dsc_policy_set_enable_dsc_when_not_needed(
|
||||
aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
|
||||
|
||||
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
|
||||
if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
0,
|
||||
link_bandwidth_kbps,
|
||||
&stream->timing,
|
||||
&stream->timing.dsc_cfg)) {
|
||||
stream->timing.flags.DSC = 1;
|
||||
DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from SST RX\n", __func__, drm_connector->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Overwrite the stream flag if DSC is enabled through debugfs */
|
||||
if (aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE)
|
||||
stream->timing.flags.DSC = 1;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_h)
|
||||
stream->timing.dsc_cfg.num_slices_h = aconnector->dsc_settings.dsc_num_slices_h;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_v)
|
||||
stream->timing.dsc_cfg.num_slices_v = aconnector->dsc_settings.dsc_num_slices_v;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
|
||||
stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct drm_display_mode *
|
||||
get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector,
|
||||
bool use_probed_modes)
|
||||
@@ -5625,12 +5703,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
struct drm_display_mode saved_mode;
|
||||
struct drm_display_mode *freesync_mode = NULL;
|
||||
bool native_mode_found = false;
|
||||
bool recalculate_timing = dm_state ? (dm_state->scaling != RMX_OFF) : false;
|
||||
bool recalculate_timing = false;
|
||||
bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
|
||||
int mode_refresh;
|
||||
int preferred_refresh = 0;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dsc_dec_dpcd_caps dsc_caps;
|
||||
uint32_t link_bandwidth_kbps;
|
||||
#endif
|
||||
struct dc_sink *sink = NULL;
|
||||
|
||||
@@ -5688,7 +5766,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
*/
|
||||
DRM_DEBUG_DRIVER("No preferred mode found\n");
|
||||
} else {
|
||||
recalculate_timing |= amdgpu_freesync_vid_mode &&
|
||||
recalculate_timing = amdgpu_freesync_vid_mode &&
|
||||
is_freesync_video_mode(&mode, aconnector);
|
||||
if (recalculate_timing) {
|
||||
freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
|
||||
@@ -5696,11 +5774,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
mode = *freesync_mode;
|
||||
} else {
|
||||
decide_crtc_timing_for_drm_display_mode(
|
||||
&mode, preferred_mode,
|
||||
dm_state ? (dm_state->scaling != RMX_OFF) : false);
|
||||
}
|
||||
&mode, preferred_mode, scale);
|
||||
|
||||
preferred_refresh = drm_mode_vrefresh(preferred_mode);
|
||||
preferred_refresh = drm_mode_vrefresh(preferred_mode);
|
||||
}
|
||||
}
|
||||
|
||||
if (recalculate_timing)
|
||||
@@ -5712,7 +5789,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
* If scaling is enabled and refresh rate didn't change
|
||||
* we copy the vic and polarities of the old timings
|
||||
*/
|
||||
if (!recalculate_timing || mode_refresh != preferred_refresh)
|
||||
if (!scale || mode_refresh != preferred_refresh)
|
||||
fill_stream_properties_from_drm_display_mode(
|
||||
stream, &mode, &aconnector->base, con_state, NULL,
|
||||
requested_bpc);
|
||||
@@ -5721,45 +5798,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
stream, &mode, &aconnector->base, con_state, old_stream,
|
||||
requested_bpc);
|
||||
|
||||
stream->timing.flags.DSC = 0;
|
||||
|
||||
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
|
||||
&dsc_caps);
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
dc_link_get_link_cap(aconnector->dc_link));
|
||||
|
||||
if (aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE && dsc_caps.is_dsc_supported) {
|
||||
/* Set DSC policy according to dsc_clock_en */
|
||||
dc_dsc_policy_set_enable_dsc_when_not_needed(
|
||||
aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
|
||||
|
||||
if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
|
||||
&dsc_caps,
|
||||
aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
0,
|
||||
link_bandwidth_kbps,
|
||||
&stream->timing,
|
||||
&stream->timing.dsc_cfg))
|
||||
stream->timing.flags.DSC = 1;
|
||||
/* Overwrite the stream flag if DSC is enabled through debugfs */
|
||||
if (aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE)
|
||||
stream->timing.flags.DSC = 1;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_h)
|
||||
stream->timing.dsc_cfg.num_slices_h = aconnector->dsc_settings.dsc_num_slices_h;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_v)
|
||||
stream->timing.dsc_cfg.num_slices_v = aconnector->dsc_settings.dsc_num_slices_v;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
|
||||
stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
|
||||
}
|
||||
/* SST DSC determination policy */
|
||||
update_dsc_caps(aconnector, sink, stream, &dsc_caps);
|
||||
if (aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE && dsc_caps.is_dsc_supported)
|
||||
apply_dsc_policy_for_stream(aconnector, sink, stream, &dsc_caps);
|
||||
#endif
|
||||
}
|
||||
|
||||
update_stream_scaling_settings(&mode, dm_state, stream);
|
||||
|
||||
@@ -6558,9 +6602,8 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
||||
|
||||
dm_update_crtc_active_planes(crtc, crtc_state);
|
||||
|
||||
if (unlikely(!dm_crtc_state->stream &&
|
||||
modeset_required(crtc_state, NULL, dm_crtc_state->stream))) {
|
||||
WARN_ON(1);
|
||||
if (WARN_ON(unlikely(!dm_crtc_state->stream &&
|
||||
modeset_required(crtc_state, NULL, dm_crtc_state->stream)))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -7059,6 +7102,10 @@ static const uint32_t rgb_formats[] = {
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_XRGB16161616,
|
||||
DRM_FORMAT_XBGR16161616,
|
||||
DRM_FORMAT_ARGB16161616,
|
||||
DRM_FORMAT_ABGR16161616,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_RGB565,
|
||||
@@ -8967,7 +9014,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
}
|
||||
|
||||
status = dc_stream_get_status(dm_new_crtc_state->stream);
|
||||
WARN_ON(!status);
|
||||
|
||||
if (WARN_ON(!status))
|
||||
continue;
|
||||
|
||||
WARN_ON(!status->plane_count);
|
||||
|
||||
/*
|
||||
@@ -9974,7 +10024,7 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
|
||||
|
||||
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");
|
||||
drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -10010,11 +10060,11 @@ 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;
|
||||
struct drm_plane_state *new_plane_state;
|
||||
struct drm_plane_state *primary_state, *cursor_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) {
|
||||
for_each_new_plane_in_state_reverse(state, plane, new_plane_state, i) {
|
||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
|
||||
if (drm_atomic_plane_disabling(plane->state, new_plane_state))
|
||||
return 0;
|
||||
@@ -10041,6 +10091,14 @@ static int validate_overlay(struct drm_atomic_state *state)
|
||||
if (!primary_state->crtc)
|
||||
return 0;
|
||||
|
||||
/* check if cursor plane is enabled */
|
||||
cursor_state = drm_atomic_get_plane_state(state, overlay_state->crtc->cursor);
|
||||
if (IS_ERR(cursor_state))
|
||||
return PTR_ERR(cursor_state);
|
||||
|
||||
if (drm_atomic_plane_disabling(plane->state, cursor_state))
|
||||
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 ||
|
||||
|
||||
Reference in New Issue
Block a user