mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
synced 2026-04-18 06:33:43 -04:00
Merge tag 'amd-drm-next-5.17-2021-12-02' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.17-2021-12-02: amdgpu: - Use generic drm fb helpers - PSR fixes - Rework DCN3.1 clkmgr - DPCD 1.3 fixes - Misc display fixes can cleanups - Clock query fixes for APUs - LTTPR fixes - DSC fixes - Misc PM fixes - RAS fixes - OLED backlight fix - SRIOV fixes - Add STB (Smart Trace Buffer) for supported dGPUs - IH rework - Enable seamless boot for DCN3.01 amdkfd: - Rework more stuff around IP discovery enumeration - Further clean up of interfaces with amdgpu - SVM fixes radeon: - Indentation fixes UAPI: - Add a new KFD header that defines some of the sysfs bitfields and enums that userspace has been using for a while The corresponding bit-fields and enums in user mode are defined in https://github.com/RadeonOpenCompute/ROCT-Thunk-Interface/blob/master/include/hsakmttypes.h Signed-off-by: Dave Airlie <airlied@redhat.com> # Conflicts: # drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211202191643.5970-1-alexander.deucher@amd.com
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
#include <drm/drm_hdcp.h>
|
||||
#endif
|
||||
#include "amdgpu_pm.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
|
||||
#include "amd_shared.h"
|
||||
#include "amdgpu_dm_irq.h"
|
||||
@@ -789,8 +790,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
|
||||
plink = adev->dm.dc->links[notify.link_index];
|
||||
if (plink) {
|
||||
plink->hpd_status =
|
||||
notify.hpd_status ==
|
||||
DP_HPD_PLUG ? true : false;
|
||||
notify.hpd_status == DP_HPD_PLUG;
|
||||
}
|
||||
}
|
||||
queue_work(adev->dm.delayed_hpd_wq, &dmub_hpd_wrk->handle_hpd_work);
|
||||
@@ -1455,6 +1455,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
|
||||
init_data.flags.power_down_display_on_boot = true;
|
||||
|
||||
if (check_seamless_boot_capability(adev)) {
|
||||
init_data.flags.power_down_display_on_boot = false;
|
||||
init_data.flags.allow_seamless_boot_optimization = true;
|
||||
DRM_INFO("Seamless boot condition check passed\n");
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&adev->dm.da_list);
|
||||
/* Display Core create. */
|
||||
adev->dm.dc = dc_create(&init_data);
|
||||
@@ -1479,8 +1485,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER)
|
||||
adev->dm.dc->debug.disable_stutter = true;
|
||||
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_DSC)
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
|
||||
adev->dm.dc->debug.disable_dsc = true;
|
||||
adev->dm.dc->debug.disable_dsc_edp = true;
|
||||
}
|
||||
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING)
|
||||
adev->dm.dc->debug.disable_clock_gate = true;
|
||||
@@ -2303,14 +2311,6 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
res = dc_validate_global_state(dc, context, false);
|
||||
|
||||
if (res != DC_OK) {
|
||||
DRM_ERROR("%s:resource validation failed, dc_status:%d\n", __func__, res);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
res = dc_commit_state(dc, context);
|
||||
|
||||
fail:
|
||||
@@ -2561,6 +2561,22 @@ static int dm_resume(void *handle)
|
||||
if (amdgpu_in_reset(adev)) {
|
||||
dc_state = dm->cached_dc_state;
|
||||
|
||||
/*
|
||||
* The dc->current_state is backed up into dm->cached_dc_state
|
||||
* before we commit 0 streams.
|
||||
*
|
||||
* DC will clear link encoder assignments on the real state
|
||||
* but the changes won't propagate over to the copy we made
|
||||
* before the 0 streams commit.
|
||||
*
|
||||
* DC expects that link encoder assignments are *not* valid
|
||||
* when committing a state, so as a workaround it needs to be
|
||||
* cleared here.
|
||||
*/
|
||||
link_enc_cfg_init(dm->dc, dc_state);
|
||||
|
||||
amdgpu_dm_outbox_init(adev);
|
||||
|
||||
r = dm_dmub_hw_init(adev);
|
||||
if (r)
|
||||
DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
|
||||
@@ -2572,20 +2588,11 @@ static int dm_resume(void *handle)
|
||||
|
||||
for (i = 0; i < dc_state->stream_count; i++) {
|
||||
dc_state->streams[i]->mode_changed = true;
|
||||
for (j = 0; j < dc_state->stream_status->plane_count; j++) {
|
||||
dc_state->stream_status->plane_states[j]->update_flags.raw
|
||||
for (j = 0; j < dc_state->stream_status[i].plane_count; j++) {
|
||||
dc_state->stream_status[i].plane_states[j]->update_flags.raw
|
||||
= 0xffffffff;
|
||||
}
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/*
|
||||
* Resource allocation happens for link encoders for newer ASIC in
|
||||
* dc_validate_global_state, so we need to revalidate it.
|
||||
*
|
||||
* This shouldn't fail (it passed once before), so warn if it does.
|
||||
*/
|
||||
WARN_ON(dc_validate_global_state(dm->dc, dc_state, false) != DC_OK);
|
||||
#endif
|
||||
|
||||
WARN_ON(!dc_commit_state(dm->dc, dc_state));
|
||||
|
||||
@@ -3909,6 +3916,9 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
caps = dm->backlight_caps[bl_idx];
|
||||
|
||||
dm->brightness[bl_idx] = user_brightness;
|
||||
/* update scratch register */
|
||||
if (bl_idx == 0)
|
||||
amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]);
|
||||
brightness = convert_brightness_from_user(&caps, dm->brightness[bl_idx]);
|
||||
link = (struct dc_link *)dm->backlight_link[bl_idx];
|
||||
|
||||
@@ -4251,6 +4261,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable vblank IRQs aggressively for power-saving.
|
||||
*
|
||||
* TODO: Fix vblank control helpers to delay PSR entry to allow this when PSR
|
||||
* is also supported.
|
||||
*/
|
||||
adev_to_drm(adev)->vblank_disable_immediate = !psr_feature_enabled;
|
||||
|
||||
/* Software is initialized. Now we can register interrupt handlers. */
|
||||
switch (adev->asic_type) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_SI)
|
||||
@@ -6036,7 +6054,8 @@ static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
|
||||
{
|
||||
stream->timing.flags.DSC = 0;
|
||||
|
||||
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
if (aconnector->dc_link && (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT ||
|
||||
sink->sink_signal == SIGNAL_TYPE_EDP)) {
|
||||
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,
|
||||
@@ -6044,6 +6063,64 @@ static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
|
||||
struct dc_sink *sink, struct dc_stream_state *stream,
|
||||
struct dsc_dec_dpcd_caps *dsc_caps,
|
||||
uint32_t max_dsc_target_bpp_limit_override)
|
||||
{
|
||||
const struct dc_link_settings *verified_link_cap = NULL;
|
||||
uint32_t link_bw_in_kbps;
|
||||
uint32_t edp_min_bpp_x16, edp_max_bpp_x16;
|
||||
struct dc *dc = sink->ctx->dc;
|
||||
struct dc_dsc_bw_range bw_range = {0};
|
||||
struct dc_dsc_config dsc_cfg = {0};
|
||||
|
||||
verified_link_cap = dc_link_get_link_cap(stream->link);
|
||||
link_bw_in_kbps = dc_link_bandwidth_kbps(stream->link, verified_link_cap);
|
||||
edp_min_bpp_x16 = 8 * 16;
|
||||
edp_max_bpp_x16 = 8 * 16;
|
||||
|
||||
if (edp_max_bpp_x16 > dsc_caps->edp_max_bits_per_pixel)
|
||||
edp_max_bpp_x16 = dsc_caps->edp_max_bits_per_pixel;
|
||||
|
||||
if (edp_max_bpp_x16 < edp_min_bpp_x16)
|
||||
edp_min_bpp_x16 = edp_max_bpp_x16;
|
||||
|
||||
if (dc_dsc_compute_bandwidth_range(dc->res_pool->dscs[0],
|
||||
dc->debug.dsc_min_slice_height_override,
|
||||
edp_min_bpp_x16, edp_max_bpp_x16,
|
||||
dsc_caps,
|
||||
&stream->timing,
|
||||
&bw_range)) {
|
||||
|
||||
if (bw_range.max_kbps < link_bw_in_kbps) {
|
||||
if (dc_dsc_compute_config(dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
dc->debug.dsc_min_slice_height_override,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
0,
|
||||
&stream->timing,
|
||||
&dsc_cfg)) {
|
||||
stream->timing.dsc_cfg = dsc_cfg;
|
||||
stream->timing.flags.DSC = 1;
|
||||
stream->timing.dsc_cfg.bits_per_pixel = edp_max_bpp_x16;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_dsc_compute_config(dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
dc->debug.dsc_min_slice_height_override,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
link_bw_in_kbps,
|
||||
&stream->timing,
|
||||
&dsc_cfg)) {
|
||||
stream->timing.dsc_cfg = dsc_cfg;
|
||||
stream->timing.flags.DSC = 1;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -6051,6 +6128,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
||||
struct drm_connector *drm_connector = &aconnector->base;
|
||||
uint32_t link_bandwidth_kbps;
|
||||
uint32_t max_dsc_target_bpp_limit_override = 0;
|
||||
struct dc *dc = sink->ctx->dc;
|
||||
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
dc_link_get_link_cap(aconnector->dc_link));
|
||||
@@ -6063,7 +6141,12 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
||||
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 (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP && !dc->debug.disable_dsc_edp &&
|
||||
dc->caps.edp_dsc_support && aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE) {
|
||||
|
||||
apply_dsc_policy_for_edp(aconnector, sink, stream, dsc_caps, max_dsc_target_bpp_limit_override);
|
||||
|
||||
} else 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,
|
||||
@@ -10759,8 +10842,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
trace_amdgpu_dm_atomic_check_begin(state);
|
||||
|
||||
ret = drm_atomic_helper_check_modeset(dev, state);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("drm_atomic_helper_check_modeset() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check connector changes */
|
||||
for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
|
||||
@@ -10776,6 +10861,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
|
||||
new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc);
|
||||
if (IS_ERR(new_crtc_state)) {
|
||||
DRM_DEBUG_DRIVER("drm_atomic_get_crtc_state() failed\n");
|
||||
ret = PTR_ERR(new_crtc_state);
|
||||
goto fail;
|
||||
}
|
||||
@@ -10790,8 +10876,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
|
||||
ret = add_affected_mst_dsc_crtcs(state, crtc);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("add_affected_mst_dsc_crtcs() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10806,19 +10894,25 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
continue;
|
||||
|
||||
ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!new_crtc_state->enable)
|
||||
continue;
|
||||
|
||||
ret = drm_atomic_add_affected_connectors(state, crtc);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("drm_atomic_add_affected_connectors() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = drm_atomic_add_affected_planes(state, crtc);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("drm_atomic_add_affected_planes() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dm_old_crtc_state->dsc_force_changed)
|
||||
new_crtc_state->mode_changed = true;
|
||||
@@ -10855,6 +10949,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
|
||||
if (IS_ERR(new_plane_state)) {
|
||||
ret = PTR_ERR(new_plane_state);
|
||||
DRM_DEBUG_DRIVER("new_plane_state is BAD\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@@ -10867,8 +10962,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
new_plane_state,
|
||||
false,
|
||||
&lock_and_validation_needed);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable all crtcs which require disable */
|
||||
@@ -10878,8 +10975,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
new_crtc_state,
|
||||
false,
|
||||
&lock_and_validation_needed);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("DISABLE: dm_update_crtc_state() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable all crtcs which require enable */
|
||||
@@ -10889,8 +10988,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
new_crtc_state,
|
||||
true,
|
||||
&lock_and_validation_needed);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("ENABLE: dm_update_crtc_state() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add new/modified planes */
|
||||
@@ -10900,20 +11001,26 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
new_plane_state,
|
||||
true,
|
||||
&lock_and_validation_needed);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run this here since we want to validate the streams we created */
|
||||
ret = drm_atomic_helper_check_planes(dev, state);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("drm_atomic_helper_check_planes() failed\n");
|
||||
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)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("dm_check_crtc_cursor() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->legacy_cursor_update) {
|
||||
@@ -11000,20 +11107,28 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
*/
|
||||
if (lock_and_validation_needed) {
|
||||
ret = dm_atomic_get_state(state, &dm_state);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("dm_atomic_get_state() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = do_aquire_global_lock(dev, state);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("do_aquire_global_lock() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars))
|
||||
if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars)) {
|
||||
DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("dm_update_mst_vcpi_slots_for_dsc() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -11023,12 +11138,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
* to get stuck in an infinite loop and hang eventually.
|
||||
*/
|
||||
ret = drm_dp_mst_atomic_check(state);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("drm_dp_mst_atomic_check() failed\n");
|
||||
goto fail;
|
||||
status = dc_validate_global_state(dc, dm_state->context, false);
|
||||
}
|
||||
status = dc_validate_global_state(dc, dm_state->context, true);
|
||||
if (status != DC_OK) {
|
||||
drm_dbg_atomic(dev,
|
||||
"DC global validation failure: %s (%d)",
|
||||
DRM_DEBUG_DRIVER("DC global validation failure: %s (%d)",
|
||||
dc_status_to_str(status), status);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
@@ -11529,3 +11645,24 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context
|
||||
ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS,
|
||||
(uint32_t *)operation_result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether seamless boot is supported.
|
||||
*
|
||||
* So far we only support seamless boot on CHIP_VANGOGH.
|
||||
* If everything goes well, we may consider expanding
|
||||
* seamless boot to other ASICs.
|
||||
*/
|
||||
bool check_seamless_boot_capability(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VANGOGH:
|
||||
if (!adev->mman.keep_stolen_vga_memory)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user