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:
Dave Airlie
2021-12-10 13:52:51 +10:00
156 changed files with 5098 additions and 2350 deletions

View File

@@ -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;
}