diff options
author | Dave Airlie <airlied@redhat.com> | 2020-09-23 09:25:17 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-09-23 09:25:18 +1000 |
commit | fc88fef916e8971eefeacc62241b7408b7e7939d (patch) | |
tree | c2647e7388a752ffc1f9d12b5aaf9a83a69b5ba0 /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |
parent | db29dc7d3346328b3fc61057d224a242f9928289 (diff) | |
parent | 911d5bd5e7b8531b39301c2c27e5b90d7bd71b88 (diff) | |
download | linux-fc88fef916e8971eefeacc62241b7408b7e7939d.tar.gz linux-fc88fef916e8971eefeacc62241b7408b7e7939d.tar.bz2 linux-fc88fef916e8971eefeacc62241b7408b7e7939d.zip |
Merge tag 'amd-drm-next-5.10-2020-09-18' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.10-2020-09-18:
amdgpu:
- Support for PCIe DPC recovery
- Sienna Cichlid updates
- Navy Flounder updates
- RAS fixes
- Refactor DC interrupt handling
- Display fixes
- Fix issues with OLED panels
- Mclk fixes for navi1x
- Watermark fixes for renoir and raven2
- Misc code cleanups
- Misc bug fixes
amdkfd:
- Fix a memory leak
- Fix a crach in GPU reset
- Add process eviction counters
radeon:
- expose sclk via sysfs hwmon interface
- Revert bad PLL fix
scheduler:
- Kernel doc fixes
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200918204322.3931-1-alexander.deucher@amd.com
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.c | 252 |
1 files changed, 134 insertions, 118 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 ec29376667df..57738164625b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -228,17 +228,14 @@ static u32 dm_vblank_get_counter(struct amdgpu_device *adev, int crtc) return 0; else { struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc]; - struct dm_crtc_state *acrtc_state = to_dm_crtc_state( - acrtc->base.state); - - if (acrtc_state->stream == NULL) { + if (acrtc->dm_irq_params.stream == NULL) { DRM_ERROR("dc_stream_state is NULL for crtc '%d'!\n", crtc); return 0; } - return dc_stream_get_vblank_counter(acrtc_state->stream); + return dc_stream_get_vblank_counter(acrtc->dm_irq_params.stream); } } @@ -251,10 +248,8 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, return -EINVAL; else { struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc]; - struct dm_crtc_state *acrtc_state = to_dm_crtc_state( - acrtc->base.state); - if (acrtc_state->stream == NULL) { + if (acrtc->dm_irq_params.stream == NULL) { DRM_ERROR("dc_stream_state is NULL for crtc '%d'!\n", crtc); return 0; @@ -264,7 +259,7 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, * TODO rework base driver to use values directly. * for now parse it back into reg-format */ - dc_stream_get_scanoutpos(acrtc_state->stream, + dc_stream_get_scanoutpos(acrtc->dm_irq_params.stream, &v_blank_start, &v_blank_end, &h_position, @@ -323,6 +318,14 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev, return NULL; } +static inline bool amdgpu_dm_vrr_active_irq(struct amdgpu_crtc *acrtc) +{ + return acrtc->dm_irq_params.freesync_config.state == + VRR_STATE_ACTIVE_VARIABLE || + acrtc->dm_irq_params.freesync_config.state == + VRR_STATE_ACTIVE_FIXED; +} + static inline bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state) { return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE || @@ -343,7 +346,6 @@ static void dm_pflip_high_irq(void *interrupt_params) struct amdgpu_device *adev = irq_params->adev; unsigned long flags; struct drm_pending_vblank_event *e; - struct dm_crtc_state *acrtc_state; uint32_t vpos, hpos, v_blank_start, v_blank_end; bool vrr_active; @@ -375,12 +377,11 @@ static void dm_pflip_high_irq(void *interrupt_params) if (!e) WARN_ON(1); - acrtc_state = to_dm_crtc_state(amdgpu_crtc->base.state); - vrr_active = amdgpu_dm_vrr_active(acrtc_state); + vrr_active = amdgpu_dm_vrr_active_irq(amdgpu_crtc); /* Fixed refresh rate, or VRR scanout position outside front-porch? */ if (!vrr_active || - !dc_stream_get_scanoutpos(acrtc_state->stream, &v_blank_start, + !dc_stream_get_scanoutpos(amdgpu_crtc->dm_irq_params.stream, &v_blank_start, &v_blank_end, &hpos, &vpos) || (vpos < v_blank_start)) { /* Update to correct count and vblank timestamp if racing with @@ -425,7 +426,7 @@ static void dm_pflip_high_irq(void *interrupt_params) * of pageflip completion, so last_flip_vblank is the forbidden count * for queueing new pageflips if vsync + VRR is enabled. */ - amdgpu_crtc->last_flip_vblank = + amdgpu_crtc->dm_irq_params.last_flip_vblank = amdgpu_get_vblank_counter_kms(&amdgpu_crtc->base); amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; @@ -441,17 +442,17 @@ static void dm_vupdate_high_irq(void *interrupt_params) struct common_irq_params *irq_params = interrupt_params; struct amdgpu_device *adev = irq_params->adev; struct amdgpu_crtc *acrtc; - struct dm_crtc_state *acrtc_state; unsigned long flags; + int vrr_active; acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE); if (acrtc) { - acrtc_state = to_dm_crtc_state(acrtc->base.state); + vrr_active = amdgpu_dm_vrr_active_irq(acrtc); DRM_DEBUG_VBL("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, - amdgpu_dm_vrr_active(acrtc_state)); + vrr_active); /* Core vblank handling is done here after end of front-porch in * vrr mode, as vblank timestamping will give valid results @@ -459,22 +460,22 @@ static void dm_vupdate_high_irq(void *interrupt_params) * page-flip completion events that have been queued to us * if a pageflip happened inside front-porch. */ - if (amdgpu_dm_vrr_active(acrtc_state)) { + if (vrr_active) { drm_crtc_handle_vblank(&acrtc->base); /* BTR processing for pre-DCE12 ASICs */ - if (acrtc_state->stream && + if (acrtc->dm_irq_params.stream && adev->family < AMDGPU_FAMILY_AI) { spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); mod_freesync_handle_v_update( adev->dm.freesync_module, - acrtc_state->stream, - &acrtc_state->vrr_params); + acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params); dc_stream_adjust_vmin_vmax( adev->dm.dc, - acrtc_state->stream, - &acrtc_state->vrr_params.adjust); + acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params.adjust); spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); } } @@ -493,18 +494,17 @@ static void dm_crtc_high_irq(void *interrupt_params) struct common_irq_params *irq_params = interrupt_params; struct amdgpu_device *adev = irq_params->adev; struct amdgpu_crtc *acrtc; - struct dm_crtc_state *acrtc_state; unsigned long flags; + int vrr_active; acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); if (!acrtc) return; - acrtc_state = to_dm_crtc_state(acrtc->base.state); + vrr_active = amdgpu_dm_vrr_active_irq(acrtc); DRM_DEBUG_VBL("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id, - amdgpu_dm_vrr_active(acrtc_state), - acrtc_state->active_planes); + vrr_active, acrtc->dm_irq_params.active_planes); /** * Core vblank handling at start of front-porch is only possible @@ -512,7 +512,7 @@ static void dm_crtc_high_irq(void *interrupt_params) * valid results while done in front-porch. Otherwise defer it * to dm_vupdate_high_irq after end of front-porch. */ - if (!amdgpu_dm_vrr_active(acrtc_state)) + if (!vrr_active) drm_crtc_handle_vblank(&acrtc->base); /** @@ -527,14 +527,16 @@ static void dm_crtc_high_irq(void *interrupt_params) spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); - if (acrtc_state->stream && acrtc_state->vrr_params.supported && - acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { + if (acrtc->dm_irq_params.stream && + acrtc->dm_irq_params.vrr_params.supported && + acrtc->dm_irq_params.freesync_config.state == + VRR_STATE_ACTIVE_VARIABLE) { mod_freesync_handle_v_update(adev->dm.freesync_module, - acrtc_state->stream, - &acrtc_state->vrr_params); + acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params); - dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc_state->stream, - &acrtc_state->vrr_params.adjust); + dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params.adjust); } /* @@ -549,7 +551,7 @@ static void dm_crtc_high_irq(void *interrupt_params) */ if (adev->family >= AMDGPU_FAMILY_RV && acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED && - acrtc_state->active_planes == 0) { + acrtc->dm_irq_params.active_planes == 0) { if (acrtc->event) { drm_crtc_send_vblank_event(&acrtc->base, acrtc->event); acrtc->event = NULL; @@ -878,6 +880,45 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) return 0; } +static void amdgpu_check_debugfs_connector_property_change(struct amdgpu_device *adev, + struct drm_atomic_state *state) +{ + struct drm_connector *connector; + struct drm_crtc *crtc; + struct amdgpu_dm_connector *amdgpu_dm_connector; + struct drm_connector_state *conn_state; + struct dm_crtc_state *acrtc_state; + struct drm_crtc_state *crtc_state; + struct dc_stream_state *stream; + struct drm_device *dev = adev_to_drm(adev); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + + amdgpu_dm_connector = to_amdgpu_dm_connector(connector); + conn_state = connector->state; + + if (!(conn_state && conn_state->crtc)) + continue; + + crtc = conn_state->crtc; + acrtc_state = to_dm_crtc_state(crtc->state); + + if (!(acrtc_state && acrtc_state->stream)) + continue; + + stream = acrtc_state->stream; + + if (amdgpu_dm_connector->dsc_settings.dsc_force_enable || + amdgpu_dm_connector->dsc_settings.dsc_num_slices_v || + amdgpu_dm_connector->dsc_settings.dsc_num_slices_h || + amdgpu_dm_connector->dsc_settings.dsc_bits_per_pixel) { + conn_state = drm_atomic_get_connector_state(state, connector); + crtc_state = drm_atomic_get_crtc_state(state, crtc); + crtc_state->mode_changed = true; + } + } +} + static int amdgpu_dm_init(struct amdgpu_device *adev) { struct dc_init_data init_data; @@ -1425,9 +1466,6 @@ static int dm_late_init(void *handle) struct dmcu *dmcu = NULL; bool ret = true; - if (!adev->dm.fw_dmcu && !adev->dm.dmub_fw) - return detect_mst_link_for_all_connectors(adev_to_drm(adev)); - dmcu = adev->dm.dc->res_pool->dmcu; for (i = 0; i < 16; i++) @@ -3373,9 +3411,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) goto fail; } - /* No userspace support. */ - dm->dc->debug.disable_tri_buf = true; - return 0; fail: kfree(aencoder); @@ -4689,9 +4724,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, dc_link_get_link_cap(aconnector->dc_link)); #if defined(CONFIG_DRM_AMD_DC_DCN) - if (dsc_caps.is_dsc_supported) { + 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_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, @@ -4701,16 +4737,14 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, &stream->timing.dsc_cfg)) stream->timing.flags.DSC = 1; /* Overwrite the stream flag if DSC is enabled through debugfs */ - if (aconnector->dsc_settings.dsc_clock_en) + 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_slice_width) - stream->timing.dsc_cfg.num_slices_h = DIV_ROUND_UP(stream->timing.h_addressable, - aconnector->dsc_settings.dsc_slice_width); + 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_slice_height) - stream->timing.dsc_cfg.num_slices_v = DIV_ROUND_UP(stream->timing.v_addressable, - aconnector->dsc_settings.dsc_slice_height); + 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; @@ -4809,7 +4843,6 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) } state->active_planes = cur->active_planes; - state->vrr_params = cur->vrr_params; state->vrr_infopacket = cur->vrr_infopacket; state->abm_level = cur->abm_level; state->vrr_supported = cur->vrr_supported; @@ -5427,19 +5460,6 @@ static void dm_crtc_helper_disable(struct drm_crtc *crtc) { } -static bool does_crtc_have_active_cursor(struct drm_crtc_state *new_crtc_state) -{ - struct drm_device *dev = new_crtc_state->crtc->dev; - struct drm_plane *plane; - - drm_for_each_plane_mask(plane, dev, new_crtc_state->plane_mask) { - if (plane->type == DRM_PLANE_TYPE_CURSOR) - return true; - } - - return false; -} - static int count_crtc_active_planes(struct drm_crtc_state *new_crtc_state) { struct drm_atomic_state *state = new_crtc_state->state; @@ -5503,19 +5523,20 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, return ret; } - /* In some use cases, like reset, no stream is attached */ - if (!dm_crtc_state->stream) - return 0; - /* - * We want at least one hardware plane enabled to use - * the stream with a cursor enabled. + * We require the primary plane to be enabled whenever the CRTC is, otherwise + * drm_mode_cursor_universal may end up trying to enable the cursor plane while all other + * planes are disabled, which is not supported by the hardware. And there is legacy + * userspace which stops using the HW cursor altogether in response to the resulting EINVAL. */ - if (state->enable && state->active && - does_crtc_have_active_cursor(state) && - dm_crtc_state->active_planes == 0) + if (state->enable && + !(state->plane_mask & drm_plane_mask(crtc->primary))) return -EINVAL; + /* In some use cases, like reset, no stream is attached */ + if (!dm_crtc_state->stream) + return 0; + if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK) return 0; @@ -6862,6 +6883,7 @@ static void update_freesync_state_on_stream( struct mod_vrr_params vrr_params; struct dc_info_packet vrr_infopacket = {0}; struct amdgpu_device *adev = dm->adev; + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(new_crtc_state->base.crtc); unsigned long flags; if (!new_stream) @@ -6876,7 +6898,7 @@ static void update_freesync_state_on_stream( return; spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); - vrr_params = new_crtc_state->vrr_params; + vrr_params = acrtc->dm_irq_params.vrr_params; if (surface) { mod_freesync_handle_preflip( @@ -6907,7 +6929,7 @@ static void update_freesync_state_on_stream( &vrr_infopacket); new_crtc_state->freesync_timing_changed |= - (memcmp(&new_crtc_state->vrr_params.adjust, + (memcmp(&acrtc->dm_irq_params.vrr_params.adjust, &vrr_params.adjust, sizeof(vrr_params.adjust)) != 0); @@ -6916,10 +6938,10 @@ static void update_freesync_state_on_stream( &vrr_infopacket, sizeof(vrr_infopacket)) != 0); - new_crtc_state->vrr_params = vrr_params; + acrtc->dm_irq_params.vrr_params = vrr_params; new_crtc_state->vrr_infopacket = vrr_infopacket; - new_stream->adjust = new_crtc_state->vrr_params.adjust; + new_stream->adjust = acrtc->dm_irq_params.vrr_params.adjust; new_stream->vrr_infopacket = vrr_infopacket; if (new_crtc_state->freesync_vrr_info_changed) @@ -6931,7 +6953,7 @@ static void update_freesync_state_on_stream( spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); } -static void pre_update_freesync_state_on_stream( +static void update_stream_irq_parameters( struct amdgpu_display_manager *dm, struct dm_crtc_state *new_crtc_state) { @@ -6939,6 +6961,7 @@ static void pre_update_freesync_state_on_stream( struct mod_vrr_params vrr_params; struct mod_freesync_config config = new_crtc_state->freesync_config; struct amdgpu_device *adev = dm->adev; + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(new_crtc_state->base.crtc); unsigned long flags; if (!new_stream) @@ -6952,7 +6975,7 @@ static void pre_update_freesync_state_on_stream( return; spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); - vrr_params = new_crtc_state->vrr_params; + vrr_params = acrtc->dm_irq_params.vrr_params; if (new_crtc_state->vrr_supported && config.min_refresh_in_uhz && @@ -6969,11 +6992,14 @@ static void pre_update_freesync_state_on_stream( &config, &vrr_params); new_crtc_state->freesync_timing_changed |= - (memcmp(&new_crtc_state->vrr_params.adjust, - &vrr_params.adjust, - sizeof(vrr_params.adjust)) != 0); + (memcmp(&acrtc->dm_irq_params.vrr_params.adjust, + &vrr_params.adjust, sizeof(vrr_params.adjust)) != 0); - new_crtc_state->vrr_params = vrr_params; + new_crtc_state->freesync_config = config; + /* Copy state for access from DM IRQ handler */ + acrtc->dm_irq_params.freesync_config = config; + acrtc->dm_irq_params.active_planes = new_crtc_state->active_planes; + acrtc->dm_irq_params.vrr_params = vrr_params; spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); } @@ -7197,7 +7223,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, * on late submission of flips. */ spin_lock_irqsave(&pcrtc->dev->event_lock, flags); - last_flip_vblank = acrtc_attach->last_flip_vblank; + last_flip_vblank = acrtc_attach->dm_irq_params.last_flip_vblank; spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); } @@ -7281,7 +7307,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, spin_lock_irqsave(&pcrtc->dev->event_lock, flags); dc_stream_adjust_vmin_vmax( dm->dc, acrtc_state->stream, - &acrtc_state->vrr_params.adjust); + &acrtc_attach->dm_irq_params.vrr_params.adjust); spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); } mutex_lock(&dm->dc_lock); @@ -7431,34 +7457,6 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) { - struct drm_crtc *crtc; - struct drm_crtc_state *old_crtc_state, *new_crtc_state; - struct amdgpu_device *adev = drm_to_adev(dev); - int i; - - /* - * We evade vblank and pflip interrupts on CRTCs that are undergoing - * a modeset, being disabled, or have no active planes. - * - * It's done in atomic commit rather than commit tail for now since - * some of these interrupt handlers access the current CRTC state and - * potentially the stream pointer itself. - * - * Since the atomic state is swapped within atomic commit and not within - * commit tail this would leave to new state (that hasn't been committed yet) - * being accesssed from within the handlers. - * - * TODO: Fix this so we can do this in commit tail and not have to block - * in atomic check. - */ - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); - - if (old_crtc_state->active && - (!new_crtc_state->active || - drm_atomic_crtc_needs_modeset(new_crtc_state))) - manage_dm_interrupts(adev, acrtc, false); - } /* * Add check here for SoC's that support hardware cursor plane, to * unset legacy_cursor_update @@ -7508,6 +7506,20 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dc_resource_state_copy_construct_current(dm->dc, dc_state); } + for_each_oldnew_crtc_in_state (state, crtc, old_crtc_state, + new_crtc_state, i) { + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); + + if (old_crtc_state->active && + (!new_crtc_state->active || + drm_atomic_crtc_needs_modeset(new_crtc_state))) { + manage_dm_interrupts(adev, acrtc, false); + dc_stream_release(dm_old_crtc_state->stream); + } + } + /* update changed items */ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); @@ -7603,7 +7615,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) if (!status) status = dc_stream_get_status_from_state(dc_state, dm_new_crtc_state->stream); - if (!status) DC_ERR("got no status for stream %p on acrtc%p\n", dm_new_crtc_state->stream, acrtc); else @@ -7729,8 +7740,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); - /* Update freesync active state. */ - pre_update_freesync_state_on_stream(dm, dm_new_crtc_state); + /* For freesync config update on crtc state and params for irq */ + update_stream_irq_parameters(dm, dm_new_crtc_state); /* Handle vrr on->off / off->on transitions */ amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, @@ -7746,10 +7757,15 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); + if (new_crtc_state->active && (!old_crtc_state->active || drm_atomic_crtc_needs_modeset(new_crtc_state))) { + dc_stream_retain(dm_new_crtc_state->stream); + acrtc->dm_irq_params.stream = dm_new_crtc_state->stream; manage_dm_interrupts(adev, acrtc, true); + #ifdef CONFIG_DEBUG_FS /** * Frontend may have changed so reapply the CRC capture @@ -7993,8 +8009,6 @@ static void reset_freesync_config_for_crtc( { new_crtc_state->vrr_supported = false; - memset(&new_crtc_state->vrr_params, 0, - sizeof(new_crtc_state->vrr_params)); memset(&new_crtc_state->vrr_infopacket, 0, sizeof(new_crtc_state->vrr_infopacket)); } @@ -8565,6 +8579,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, int ret, i; bool lock_and_validation_needed = false; + amdgpu_check_debugfs_connector_property_change(adev, state); + ret = drm_atomic_helper_check_modeset(dev, state); if (ret) goto fail; |