Commit d6273d8f authored by Dave Airlie's avatar Dave Airlie

Merge tag 'amd-drm-fixes-5.13-2021-06-02' of...

Merge tag 'amd-drm-fixes-5.13-2021-06-02' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes

amd-drm-fixes-5.13-2021-06-02:

amdgpu:
- Display fixes
- FRU EEPROM error handling fix
- RAS fix
- PSP fix
- Releasing pinned BO fix
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210603040410.4080-1-alexander.deucher@amd.com
parents ff7a24a8 e7591a8d
...@@ -337,7 +337,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev, ...@@ -337,7 +337,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
{ {
struct amdgpu_ctx *ctx; struct amdgpu_ctx *ctx;
struct amdgpu_ctx_mgr *mgr; struct amdgpu_ctx_mgr *mgr;
unsigned long ras_counter;
if (!fpriv) if (!fpriv)
return -EINVAL; return -EINVAL;
...@@ -362,21 +361,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev, ...@@ -362,21 +361,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
if (atomic_read(&ctx->guilty)) if (atomic_read(&ctx->guilty))
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY; out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
/*query ue count*/
ras_counter = amdgpu_ras_query_error_count(adev, false);
/*ras counter is monotonic increasing*/
if (ras_counter != ctx->ras_counter_ue) {
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_UE;
ctx->ras_counter_ue = ras_counter;
}
/*query ce count*/
ras_counter = amdgpu_ras_query_error_count(adev, true);
if (ras_counter != ctx->ras_counter_ce) {
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_CE;
ctx->ras_counter_ce = ras_counter;
}
mutex_unlock(&mgr->lock); mutex_unlock(&mgr->lock);
return 0; return 0;
} }
......
...@@ -3118,7 +3118,9 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) ...@@ -3118,7 +3118,9 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
*/ */
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev) bool amdgpu_device_has_dc_support(struct amdgpu_device *adev)
{ {
if (amdgpu_sriov_vf(adev) || adev->enable_virtual_display) if (amdgpu_sriov_vf(adev) ||
adev->enable_virtual_display ||
(adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK))
return false; return false;
return amdgpu_device_asic_has_dc_support(adev->asic_type); return amdgpu_device_asic_has_dc_support(adev->asic_type);
......
...@@ -101,7 +101,8 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr, ...@@ -101,7 +101,8 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
int amdgpu_fru_get_product_info(struct amdgpu_device *adev) int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
{ {
unsigned char buff[34]; unsigned char buff[34];
int addrptr = 0, size = 0; int addrptr, size;
int len;
if (!is_fru_eeprom_supported(adev)) if (!is_fru_eeprom_supported(adev))
return 0; return 0;
...@@ -109,7 +110,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) ...@@ -109,7 +110,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
/* If algo exists, it means that the i2c_adapter's initialized */ /* If algo exists, it means that the i2c_adapter's initialized */
if (!adev->pm.smu_i2c.algo) { if (!adev->pm.smu_i2c.algo) {
DRM_WARN("Cannot access FRU, EEPROM accessor not initialized"); DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
return 0; return -ENODEV;
} }
/* There's a lot of repetition here. This is due to the FRU having /* There's a lot of repetition here. This is due to the FRU having
...@@ -128,7 +129,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) ...@@ -128,7 +129,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
size = amdgpu_fru_read_eeprom(adev, addrptr, buff); size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
if (size < 1) { if (size < 1) {
DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size); DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
return size; return -EINVAL;
} }
/* Increment the addrptr by the size of the field, and 1 due to the /* Increment the addrptr by the size of the field, and 1 due to the
...@@ -138,43 +139,45 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) ...@@ -138,43 +139,45 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
size = amdgpu_fru_read_eeprom(adev, addrptr, buff); size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
if (size < 1) { if (size < 1) {
DRM_ERROR("Failed to read FRU product name, ret:%d", size); DRM_ERROR("Failed to read FRU product name, ret:%d", size);
return size; return -EINVAL;
} }
len = size;
/* Product name should only be 32 characters. Any more, /* Product name should only be 32 characters. Any more,
* and something could be wrong. Cap it at 32 to be safe * and something could be wrong. Cap it at 32 to be safe
*/ */
if (size > 32) { if (len >= sizeof(adev->product_name)) {
DRM_WARN("FRU Product Number is larger than 32 characters. This is likely a mistake"); DRM_WARN("FRU Product Number is larger than 32 characters. This is likely a mistake");
size = 32; len = sizeof(adev->product_name) - 1;
} }
/* Start at 2 due to buff using fields 0 and 1 for the address */ /* Start at 2 due to buff using fields 0 and 1 for the address */
memcpy(adev->product_name, &buff[2], size); memcpy(adev->product_name, &buff[2], len);
adev->product_name[size] = '\0'; adev->product_name[len] = '\0';
addrptr += size + 1; addrptr += size + 1;
size = amdgpu_fru_read_eeprom(adev, addrptr, buff); size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
if (size < 1) { if (size < 1) {
DRM_ERROR("Failed to read FRU product number, ret:%d", size); DRM_ERROR("Failed to read FRU product number, ret:%d", size);
return size; return -EINVAL;
} }
len = size;
/* Product number should only be 16 characters. Any more, /* Product number should only be 16 characters. Any more,
* and something could be wrong. Cap it at 16 to be safe * and something could be wrong. Cap it at 16 to be safe
*/ */
if (size > 16) { if (len >= sizeof(adev->product_number)) {
DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake"); DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake");
size = 16; len = sizeof(adev->product_number) - 1;
} }
memcpy(adev->product_number, &buff[2], size); memcpy(adev->product_number, &buff[2], len);
adev->product_number[size] = '\0'; adev->product_number[len] = '\0';
addrptr += size + 1; addrptr += size + 1;
size = amdgpu_fru_read_eeprom(adev, addrptr, buff); size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
if (size < 1) { if (size < 1) {
DRM_ERROR("Failed to read FRU product version, ret:%d", size); DRM_ERROR("Failed to read FRU product version, ret:%d", size);
return size; return -EINVAL;
} }
addrptr += size + 1; addrptr += size + 1;
...@@ -182,18 +185,19 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) ...@@ -182,18 +185,19 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
if (size < 1) { if (size < 1) {
DRM_ERROR("Failed to read FRU serial number, ret:%d", size); DRM_ERROR("Failed to read FRU serial number, ret:%d", size);
return size; return -EINVAL;
} }
len = size;
/* Serial number should only be 16 characters. Any more, /* Serial number should only be 16 characters. Any more,
* and something could be wrong. Cap it at 16 to be safe * and something could be wrong. Cap it at 16 to be safe
*/ */
if (size > 16) { if (len >= sizeof(adev->serial)) {
DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake"); DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake");
size = 16; len = sizeof(adev->serial) - 1;
} }
memcpy(adev->serial, &buff[2], size); memcpy(adev->serial, &buff[2], len);
adev->serial[size] = '\0'; adev->serial[len] = '\0';
return 0; return 0;
} }
...@@ -76,6 +76,7 @@ struct psp_ring ...@@ -76,6 +76,7 @@ struct psp_ring
uint64_t ring_mem_mc_addr; uint64_t ring_mem_mc_addr;
void *ring_mem_handle; void *ring_mem_handle;
uint32_t ring_size; uint32_t ring_size;
uint32_t ring_wptr;
}; };
/* More registers may will be supported */ /* More registers may will be supported */
......
...@@ -720,7 +720,7 @@ static uint32_t psp_v11_0_ring_get_wptr(struct psp_context *psp) ...@@ -720,7 +720,7 @@ static uint32_t psp_v11_0_ring_get_wptr(struct psp_context *psp)
struct amdgpu_device *adev = psp->adev; struct amdgpu_device *adev = psp->adev;
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102); data = psp->km_ring.ring_wptr;
else else
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
...@@ -734,6 +734,7 @@ static void psp_v11_0_ring_set_wptr(struct psp_context *psp, uint32_t value) ...@@ -734,6 +734,7 @@ static void psp_v11_0_ring_set_wptr(struct psp_context *psp, uint32_t value)
if (amdgpu_sriov_vf(adev)) { if (amdgpu_sriov_vf(adev)) {
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value); WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value);
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD); WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD);
psp->km_ring.ring_wptr = value;
} else } else
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value); WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value);
} }
......
...@@ -379,7 +379,7 @@ static uint32_t psp_v3_1_ring_get_wptr(struct psp_context *psp) ...@@ -379,7 +379,7 @@ static uint32_t psp_v3_1_ring_get_wptr(struct psp_context *psp)
struct amdgpu_device *adev = psp->adev; struct amdgpu_device *adev = psp->adev;
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102); data = psp->km_ring.ring_wptr;
else else
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
return data; return data;
...@@ -394,6 +394,7 @@ static void psp_v3_1_ring_set_wptr(struct psp_context *psp, uint32_t value) ...@@ -394,6 +394,7 @@ static void psp_v3_1_ring_set_wptr(struct psp_context *psp, uint32_t value)
/* send interrupt to PSP for SRIOV ring write pointer update */ /* send interrupt to PSP for SRIOV ring write pointer update */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
GFX_CTRL_CMD_ID_CONSUME_CMD); GFX_CTRL_CMD_ID_CONSUME_CMD);
psp->km_ring.ring_wptr = value;
} else } else
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value); WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value);
} }
......
...@@ -357,6 +357,7 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -357,6 +357,7 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
error: error:
dma_fence_put(fence); dma_fence_put(fence);
amdgpu_bo_unpin(bo);
amdgpu_bo_unreserve(bo); amdgpu_bo_unreserve(bo);
amdgpu_bo_unref(&bo); amdgpu_bo_unref(&bo);
return r; return r;
......
...@@ -925,7 +925,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) ...@@ -925,7 +925,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu); 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) { if (!adev->dm.dc->ctx->dmub_srv) {
DRM_ERROR("Couldn't allocate DC DMUB server!\n"); DRM_ERROR("Couldn't allocate DC DMUB server!\n");
return -ENOMEM; return -ENOMEM;
...@@ -1954,7 +1955,6 @@ static int dm_suspend(void *handle) ...@@ -1954,7 +1955,6 @@ static int dm_suspend(void *handle)
amdgpu_dm_irq_suspend(adev); amdgpu_dm_irq_suspend(adev);
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
return 0; return 0;
...@@ -5500,7 +5500,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, ...@@ -5500,7 +5500,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
struct drm_display_mode saved_mode; struct drm_display_mode saved_mode;
struct drm_display_mode *freesync_mode = NULL; struct drm_display_mode *freesync_mode = NULL;
bool native_mode_found = false; 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 mode_refresh;
int preferred_refresh = 0; int preferred_refresh = 0;
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
...@@ -5563,7 +5564,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, ...@@ -5563,7 +5564,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
*/ */
DRM_DEBUG_DRIVER("No preferred mode found\n"); DRM_DEBUG_DRIVER("No preferred mode found\n");
} else { } else {
recalculate_timing |= amdgpu_freesync_vid_mode && recalculate_timing = amdgpu_freesync_vid_mode &&
is_freesync_video_mode(&mode, aconnector); is_freesync_video_mode(&mode, aconnector);
if (recalculate_timing) { if (recalculate_timing) {
freesync_mode = get_highest_refresh_rate_mode(aconnector, false); freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
...@@ -5571,11 +5572,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, ...@@ -5571,11 +5572,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
mode = *freesync_mode; mode = *freesync_mode;
} else { } else {
decide_crtc_timing_for_drm_display_mode( decide_crtc_timing_for_drm_display_mode(
&mode, preferred_mode, &mode, preferred_mode, scale);
dm_state ? (dm_state->scaling != RMX_OFF) : false);
}
preferred_refresh = drm_mode_vrefresh(preferred_mode); preferred_refresh = drm_mode_vrefresh(preferred_mode);
}
} }
if (recalculate_timing) if (recalculate_timing)
...@@ -5587,7 +5587,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, ...@@ -5587,7 +5587,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
* If scaling is enabled and refresh rate didn't change * If scaling is enabled and refresh rate didn't change
* we copy the vic and polarities of the old timings * 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( fill_stream_properties_from_drm_display_mode(
stream, &mode, &aconnector->base, con_state, NULL, stream, &mode, &aconnector->base, con_state, NULL,
requested_bpc); requested_bpc);
...@@ -9854,7 +9854,7 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, ...@@ -9854,7 +9854,7 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
if (cursor_scale_w != primary_scale_w || if (cursor_scale_w != primary_scale_w ||
cursor_scale_h != primary_scale_h) { 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; return -EINVAL;
} }
...@@ -9891,7 +9891,7 @@ static int validate_overlay(struct drm_atomic_state *state) ...@@ -9891,7 +9891,7 @@ static int validate_overlay(struct drm_atomic_state *state)
int i; int i;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *old_plane_state, *new_plane_state; struct drm_plane_state *old_plane_state, *new_plane_state;
struct drm_plane_state *primary_state, *overlay_state = NULL; struct drm_plane_state *primary_state, *cursor_state, *overlay_state = NULL;
/* Check if primary plane is contained inside overlay */ /* 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_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
...@@ -9921,6 +9921,14 @@ static int validate_overlay(struct drm_atomic_state *state) ...@@ -9921,6 +9921,14 @@ static int validate_overlay(struct drm_atomic_state *state)
if (!primary_state->crtc) if (!primary_state->crtc)
return 0; 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 */ /* Perform the bounds check to ensure the overlay plane covers the primary */
if (primary_state->crtc_x < overlay_state->crtc_x || if (primary_state->crtc_x < overlay_state->crtc_x ||
primary_state->crtc_y < overlay_state->crtc_y || primary_state->crtc_y < overlay_state->crtc_y ||
......
...@@ -3236,7 +3236,7 @@ static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc, ...@@ -3236,7 +3236,7 @@ static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc,
voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
if (voltage_supported && dummy_pstate_supported) { if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) {
context->bw_ctx.bw.dcn.clk.p_state_change_support = false; context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
goto restore_dml_state; goto restore_dml_state;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment