mirror of
https://github.com/torvalds/linux.git
synced 2026-01-25 07:47:50 +00:00
Merge tag 'amd-drm-fixes-6.15-2025-05-14' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-6.15-2025-05-14: amdgpu: - Fix CSA unmap - Fix MALL size reporting on GFX11.5 - AUX fix - DCN 3.5 fix - VRR fix - DP MST fix - DML 2.1 fixes - Silence DP AUX spam - DCN 4.0.1 cursor fix - VCN 4.0.5 fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://lore.kernel.org/r/20250514185117.758496-1-alexander.deucher@amd.com
This commit is contained in:
@@ -109,7 +109,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct drm_exec exec;
|
||||
int r;
|
||||
|
||||
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
|
||||
drm_exec_init(&exec, 0, 0);
|
||||
drm_exec_until_all_locked(&exec) {
|
||||
r = amdgpu_vm_lock_pd(vm, &exec, 0);
|
||||
if (likely(!r))
|
||||
|
||||
@@ -752,6 +752,18 @@ static int gmc_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
|
||||
adev->gmc.vram_type = vram_type;
|
||||
adev->gmc.vram_vendor = vram_vendor;
|
||||
|
||||
/* The mall_size is already calculated as mall_size_per_umc * num_umc.
|
||||
* However, for gfx1151, which features a 2-to-1 UMC mapping,
|
||||
* the result must be multiplied by 2 to determine the actual mall size.
|
||||
*/
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(11, 5, 1):
|
||||
adev->gmc.mall_size *= 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
|
||||
@@ -1023,6 +1023,10 @@ static int vcn_v4_0_5_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
|
||||
ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |
|
||||
VCN_RB1_DB_CTRL__EN_MASK);
|
||||
|
||||
/* Keeping one read-back to ensure all register writes are done, otherwise
|
||||
* it may introduce race conditions */
|
||||
RREG32_SOC15(VCN, inst_idx, regVCN_RB1_DB_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1205,6 +1209,10 @@ static int vcn_v4_0_5_start(struct amdgpu_vcn_inst *vinst)
|
||||
WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp);
|
||||
fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
|
||||
|
||||
/* Keeping one read-back to ensure all register writes are done, otherwise
|
||||
* it may introduce race conditions */
|
||||
RREG32_SOC15(VCN, i, regVCN_RB_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -372,6 +372,8 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev,
|
||||
static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
|
||||
struct dm_crtc_state *new_state)
|
||||
{
|
||||
if (new_state->stream->adjust.timing_adjust_pending)
|
||||
return true;
|
||||
if (new_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED)
|
||||
return true;
|
||||
else if (amdgpu_dm_crtc_vrr_active(old_state) != amdgpu_dm_crtc_vrr_active(new_state))
|
||||
@@ -12763,7 +12765,8 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(
|
||||
/* The reply is stored in the top nibble of the command. */
|
||||
payload->reply[0] = (adev->dm.dmub_notify->aux_reply.command >> 4) & 0xF;
|
||||
|
||||
if (!payload->write && p_notify->aux_reply.length)
|
||||
/*write req may receive a byte indicating partially written number as well*/
|
||||
if (p_notify->aux_reply.length)
|
||||
memcpy(payload->data, p_notify->aux_reply.data,
|
||||
p_notify->aux_reply.length);
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
enum aux_return_code_type operation_result;
|
||||
struct amdgpu_device *adev;
|
||||
struct ddc_service *ddc;
|
||||
uint8_t copy[16];
|
||||
|
||||
if (WARN_ON(msg->size > 16))
|
||||
return -E2BIG;
|
||||
@@ -77,6 +78,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
(msg->request & DP_AUX_I2C_WRITE_STATUS_UPDATE) != 0;
|
||||
payload.defer_delay = 0;
|
||||
|
||||
if (payload.write) {
|
||||
memcpy(copy, msg->buffer, msg->size);
|
||||
payload.data = copy;
|
||||
}
|
||||
|
||||
result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
|
||||
&operation_result);
|
||||
|
||||
@@ -100,9 +106,9 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
*/
|
||||
if (payload.write && result >= 0) {
|
||||
if (result) {
|
||||
/*one byte indicating partially written bytes. Force 0 to retry*/
|
||||
drm_info(adev_to_drm(adev), "amdgpu: AUX partially written\n");
|
||||
result = 0;
|
||||
/*one byte indicating partially written bytes*/
|
||||
drm_dbg_dp(adev_to_drm(adev), "amdgpu: AUX partially written\n");
|
||||
result = payload.data[0];
|
||||
} else if (!payload.reply[0])
|
||||
/*I2C_ACK|AUX_ACK*/
|
||||
result = msg->size;
|
||||
@@ -127,11 +133,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
break;
|
||||
}
|
||||
|
||||
drm_info(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result);
|
||||
drm_dbg_dp(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result);
|
||||
}
|
||||
|
||||
if (payload.reply[0])
|
||||
drm_info(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.",
|
||||
drm_dbg_dp(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.",
|
||||
payload.reply[0]);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -439,9 +439,12 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
* Don't adjust DRR while there's bandwidth optimizations pending to
|
||||
* avoid conflicting with firmware updates.
|
||||
*/
|
||||
if (dc->ctx->dce_version > DCE_VERSION_MAX)
|
||||
if (dc->optimized_required || dc->wm_optimized_required)
|
||||
if (dc->ctx->dce_version > DCE_VERSION_MAX) {
|
||||
if (dc->optimized_required || dc->wm_optimized_required) {
|
||||
stream->adjust.timing_adjust_pending = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
dc_exit_ips_for_hw_access(dc);
|
||||
|
||||
@@ -3168,7 +3171,8 @@ static void copy_stream_update_to_stream(struct dc *dc,
|
||||
|
||||
if (update->crtc_timing_adjust) {
|
||||
if (stream->adjust.v_total_min != update->crtc_timing_adjust->v_total_min ||
|
||||
stream->adjust.v_total_max != update->crtc_timing_adjust->v_total_max)
|
||||
stream->adjust.v_total_max != update->crtc_timing_adjust->v_total_max ||
|
||||
stream->adjust.timing_adjust_pending)
|
||||
update->crtc_timing_adjust->timing_adjust_pending = true;
|
||||
stream->adjust = *update->crtc_timing_adjust;
|
||||
update->crtc_timing_adjust->timing_adjust_pending = false;
|
||||
|
||||
@@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
|
||||
.dcn_downspread_percent = 0.5,
|
||||
.gpuvm_min_page_size_bytes = 4096,
|
||||
.hostvm_min_page_size_bytes = 4096,
|
||||
.do_urgent_latency_adjustment = 1,
|
||||
.do_urgent_latency_adjustment = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_component_us = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
|
||||
};
|
||||
|
||||
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)
|
||||
|
||||
@@ -910,7 +910,7 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
|
||||
}
|
||||
|
||||
//TODO : Could be possibly moved to a common helper layer.
|
||||
static bool dml21_wrapper_get_plane_id(const struct dc_state *context, const struct dc_plane_state *plane, unsigned int *plane_id)
|
||||
static bool dml21_wrapper_get_plane_id(const struct dc_state *context, unsigned int stream_id, const struct dc_plane_state *plane, unsigned int *plane_id)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
@@ -918,10 +918,12 @@ static bool dml21_wrapper_get_plane_id(const struct dc_state *context, const str
|
||||
return false;
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
for (j = 0; j < context->stream_status[i].plane_count; j++) {
|
||||
if (context->stream_status[i].plane_states[j] == plane) {
|
||||
*plane_id = (i << 16) | j;
|
||||
return true;
|
||||
if (context->streams[i]->stream_id == stream_id) {
|
||||
for (j = 0; j < context->stream_status[i].plane_count; j++) {
|
||||
if (context->stream_status[i].plane_states[j] == plane) {
|
||||
*plane_id = (i << 16) | j;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -944,14 +946,14 @@ static unsigned int map_stream_to_dml21_display_cfg(const struct dml2_context *d
|
||||
return location;
|
||||
}
|
||||
|
||||
static unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx,
|
||||
static unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id,
|
||||
const struct dc_plane_state *plane, const struct dc_state *context)
|
||||
{
|
||||
unsigned int plane_id;
|
||||
int i = 0;
|
||||
int location = -1;
|
||||
|
||||
if (!dml21_wrapper_get_plane_id(context, plane, &plane_id)) {
|
||||
if (!dml21_wrapper_get_plane_id(context, stream_id, plane, &plane_id)) {
|
||||
ASSERT(false);
|
||||
return -1;
|
||||
}
|
||||
@@ -1037,7 +1039,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
|
||||
dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
|
||||
} else {
|
||||
for (plane_index = 0; plane_index < context->stream_status[stream_index].plane_count; plane_index++) {
|
||||
disp_cfg_plane_location = map_plane_to_dml21_display_cfg(dml_ctx, context->stream_status[stream_index].plane_states[plane_index], context);
|
||||
disp_cfg_plane_location = map_plane_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], context);
|
||||
|
||||
if (disp_cfg_plane_location < 0)
|
||||
disp_cfg_plane_location = dml_dispcfg->num_planes++;
|
||||
@@ -1048,7 +1050,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
|
||||
populate_dml21_plane_config_from_plane_state(dml_ctx, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->stream_status[stream_index].plane_states[plane_index], context, stream_index);
|
||||
dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
|
||||
|
||||
if (dml21_wrapper_get_plane_id(context, context->stream_status[stream_index].plane_states[plane_index], &dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
|
||||
if (dml21_wrapper_get_plane_id(context, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], &dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
|
||||
dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true;
|
||||
|
||||
/* apply forced pstate policy */
|
||||
|
||||
@@ -120,10 +120,11 @@ void dpp401_set_cursor_attributes(
|
||||
enum dc_cursor_color_format color_format = cursor_attributes->color_format;
|
||||
int cur_rom_en = 0;
|
||||
|
||||
// DCN4 should always do Cursor degamma for Cursor Color modes
|
||||
if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA ||
|
||||
color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) {
|
||||
cur_rom_en = 1;
|
||||
if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) {
|
||||
cur_rom_en = 1;
|
||||
}
|
||||
}
|
||||
|
||||
REG_UPDATE_3(CURSOR0_CONTROL,
|
||||
|
||||
@@ -1980,9 +1980,9 @@ void dcn401_program_pipe(
|
||||
dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->hubp_regs.det_size);
|
||||
}
|
||||
|
||||
if (pipe_ctx->update_flags.raw ||
|
||||
(pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.raw) ||
|
||||
pipe_ctx->stream->update_flags.raw)
|
||||
if (pipe_ctx->plane_state && (pipe_ctx->update_flags.raw ||
|
||||
pipe_ctx->plane_state->update_flags.raw ||
|
||||
pipe_ctx->stream->update_flags.raw))
|
||||
dc->hwss.update_dchubp_dpp(dc, pipe_ctx, context);
|
||||
|
||||
if (pipe_ctx->plane_state && (pipe_ctx->update_flags.bits.enable ||
|
||||
|
||||
@@ -148,6 +148,7 @@ void link_blank_dp_stream(struct dc_link *link, bool hw_init)
|
||||
void link_set_all_streams_dpms_off_for_link(struct dc_link *link)
|
||||
{
|
||||
struct pipe_ctx *pipes[MAX_PIPES];
|
||||
struct dc_stream_state *streams[MAX_PIPES];
|
||||
struct dc_state *state = link->dc->current_state;
|
||||
uint8_t count;
|
||||
int i;
|
||||
@@ -160,10 +161,18 @@ void link_set_all_streams_dpms_off_for_link(struct dc_link *link)
|
||||
|
||||
link_get_master_pipes_with_dpms_on(link, state, &count, pipes);
|
||||
|
||||
/* The subsequent call to dc_commit_updates_for_stream for a full update
|
||||
* will release the current state and swap to a new state. Releasing the
|
||||
* current state results in the stream pointers in the pipe_ctx structs
|
||||
* to be zero'd. Hence, cache all streams prior to dc_commit_updates_for_stream.
|
||||
*/
|
||||
for (i = 0; i < count; i++)
|
||||
streams[i] = pipes[i]->stream;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
stream_update.stream = pipes[i]->stream;
|
||||
stream_update.stream = streams[i];
|
||||
dc_commit_updates_for_stream(link->ctx->dc, NULL, 0,
|
||||
pipes[i]->stream, &stream_update,
|
||||
streams[i], &stream_update,
|
||||
state);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user