mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
amd-drm-fixes-6.15-2025-04-23:
amdgpu: - P2P DMA fixes - Display reset fixes - DCN 3.5 fixes - ACPI EDID fix - LTTPR fix - mode_valid() fix -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCaAkxBQAKCRC93/aFa7yZ 2DZJAQD6PwhtXHNlkEGKSBTAz/rcELq2XlvcNt5BXl787+wR7QD+Miuc8DxTGbPh ZJ5u8t76TJAYlCiYXyOkVptKrvs38ws= =9tib -----END PGP SIGNATURE----- Merge tag 'amd-drm-fixes-6.15-2025-04-23' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes amd-drm-fixes-6.15-2025-04-23: amdgpu: - P2P DMA fixes - Display reset fixes - DCN 3.5 fixes - ACPI EDID fix - LTTPR fix - mode_valid() fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://lore.kernel.org/r/20250423183045.2886753-1-alexander.deucher@amd.com
This commit is contained in:
commit
250130d2da
|
|
@ -43,6 +43,29 @@
|
|||
#include <linux/dma-fence-array.h>
|
||||
#include <linux/pci-p2pdma.h>
|
||||
|
||||
static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops;
|
||||
|
||||
/**
|
||||
* dma_buf_attach_adev - Helper to get adev of an attachment
|
||||
*
|
||||
* @attach: attachment
|
||||
*
|
||||
* Returns:
|
||||
* A struct amdgpu_device * if the attaching device is an amdgpu device or
|
||||
* partition, NULL otherwise.
|
||||
*/
|
||||
static struct amdgpu_device *dma_buf_attach_adev(struct dma_buf_attachment *attach)
|
||||
{
|
||||
if (attach->importer_ops == &amdgpu_dma_buf_attach_ops) {
|
||||
struct drm_gem_object *obj = attach->importer_priv;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
|
||||
return amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation
|
||||
*
|
||||
|
|
@ -54,11 +77,13 @@
|
|||
static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
|
||||
struct dma_buf_attachment *attach)
|
||||
{
|
||||
struct amdgpu_device *attach_adev = dma_buf_attach_adev(attach);
|
||||
struct drm_gem_object *obj = dmabuf->priv;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
|
||||
if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
|
||||
if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) &&
|
||||
pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
|
||||
attach->peer2peer = false;
|
||||
|
||||
amdgpu_vm_bo_update_shared(bo);
|
||||
|
|
@ -77,22 +102,32 @@ static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach)
|
|||
{
|
||||
struct dma_buf *dmabuf = attach->dmabuf;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(dmabuf->priv);
|
||||
u32 domains = bo->preferred_domains;
|
||||
u32 domains = bo->allowed_domains;
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
/*
|
||||
* Try pinning into VRAM to allow P2P with RDMA NICs without ODP
|
||||
/* Try pinning into VRAM to allow P2P with RDMA NICs without ODP
|
||||
* support if all attachments can do P2P. If any attachment can't do
|
||||
* P2P just pin into GTT instead.
|
||||
*
|
||||
* To avoid with conflicting pinnings between GPUs and RDMA when move
|
||||
* notifiers are disabled, only allow pinning in VRAM when move
|
||||
* notiers are enabled.
|
||||
*/
|
||||
list_for_each_entry(attach, &dmabuf->attachments, node)
|
||||
if (!attach->peer2peer)
|
||||
domains &= ~AMDGPU_GEM_DOMAIN_VRAM;
|
||||
if (!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) {
|
||||
domains &= ~AMDGPU_GEM_DOMAIN_VRAM;
|
||||
} else {
|
||||
list_for_each_entry(attach, &dmabuf->attachments, node)
|
||||
if (!attach->peer2peer)
|
||||
domains &= ~AMDGPU_GEM_DOMAIN_VRAM;
|
||||
}
|
||||
|
||||
if (domains & AMDGPU_GEM_DOMAIN_VRAM)
|
||||
bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||
|
||||
if (WARN_ON(!domains))
|
||||
return -EINVAL;
|
||||
|
||||
return amdgpu_bo_pin(bo, domains);
|
||||
}
|
||||
|
||||
|
|
@ -470,6 +505,9 @@ bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev,
|
|||
struct drm_gem_object *obj = &bo->tbo.base;
|
||||
struct drm_gem_object *gobj;
|
||||
|
||||
if (!adev)
|
||||
return false;
|
||||
|
||||
if (obj->import_attach) {
|
||||
struct dma_buf *dma_buf = obj->import_attach->dmabuf;
|
||||
|
||||
|
|
|
|||
|
|
@ -1920,26 +1920,6 @@ static enum dmub_ips_disable_type dm_get_default_ips_mode(
|
|||
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
|
||||
case IP_VERSION(3, 5, 0):
|
||||
case IP_VERSION(3, 6, 0):
|
||||
/*
|
||||
* On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to
|
||||
* cause a hard hang. A fix exists for newer PMFW.
|
||||
*
|
||||
* As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest
|
||||
* IPS state in all cases, except for s0ix and all displays off (DPMS),
|
||||
* where IPS2 is allowed.
|
||||
*
|
||||
* When checking pmfw version, use the major and minor only.
|
||||
*/
|
||||
if ((adev->pm.fw_version & 0x00FFFF00) < 0x005D6300)
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
else if (amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(11, 5, 0))
|
||||
/*
|
||||
* Other ASICs with DCN35 that have residency issues with
|
||||
* IPS2 in idle.
|
||||
* We want them to use IPS2 only in display off cases.
|
||||
*/
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
break;
|
||||
case IP_VERSION(3, 5, 1):
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
break;
|
||||
|
|
@ -3355,16 +3335,16 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
|
|||
for (k = 0; k < dc_state->stream_count; k++) {
|
||||
bundle->stream_update.stream = dc_state->streams[k];
|
||||
|
||||
for (m = 0; m < dc_state->stream_status->plane_count; m++) {
|
||||
for (m = 0; m < dc_state->stream_status[k].plane_count; m++) {
|
||||
bundle->surface_updates[m].surface =
|
||||
dc_state->stream_status->plane_states[m];
|
||||
dc_state->stream_status[k].plane_states[m];
|
||||
bundle->surface_updates[m].surface->force_full_update =
|
||||
true;
|
||||
}
|
||||
|
||||
update_planes_and_stream_adapter(dm->dc,
|
||||
UPDATE_TYPE_FULL,
|
||||
dc_state->stream_status->plane_count,
|
||||
dc_state->stream_status[k].plane_count,
|
||||
dc_state->streams[k],
|
||||
&bundle->stream_update,
|
||||
bundle->surface_updates);
|
||||
|
|
@ -6521,12 +6501,12 @@ decide_crtc_timing_for_drm_display_mode(struct drm_display_mode *drm_mode,
|
|||
const struct drm_display_mode *native_mode,
|
||||
bool scale_enabled)
|
||||
{
|
||||
if (scale_enabled) {
|
||||
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
|
||||
} else if (native_mode->clock == drm_mode->clock &&
|
||||
native_mode->htotal == drm_mode->htotal &&
|
||||
native_mode->vtotal == drm_mode->vtotal) {
|
||||
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
|
||||
if (scale_enabled || (
|
||||
native_mode->clock == drm_mode->clock &&
|
||||
native_mode->htotal == drm_mode->htotal &&
|
||||
native_mode->vtotal == drm_mode->vtotal)) {
|
||||
if (native_mode->crtc_clock)
|
||||
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
|
||||
} else {
|
||||
/* no scaling nor amdgpu inserted, no need to patch */
|
||||
}
|
||||
|
|
@ -11043,6 +11023,9 @@ static bool should_reset_plane(struct drm_atomic_state *state,
|
|||
state->allow_modeset)
|
||||
return true;
|
||||
|
||||
if (amdgpu_in_reset(adev) && state->allow_modeset)
|
||||
return true;
|
||||
|
||||
/* Exit early if we know that we're adding or removing the plane. */
|
||||
if (old_plane_state->crtc != new_plane_state->crtc)
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -918,7 +918,7 @@ dm_helpers_probe_acpi_edid(void *data, u8 *buf, unsigned int block, size_t len)
|
|||
{
|
||||
struct drm_connector *connector = data;
|
||||
struct acpi_device *acpidev = ACPI_COMPANION(connector->dev->dev);
|
||||
unsigned char start = block * EDID_LENGTH;
|
||||
unsigned short start = block * EDID_LENGTH;
|
||||
struct edid *edid;
|
||||
int r;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = 0,
|
||||
.do_urgent_latency_adjustment = 1,
|
||||
.urgent_latency_adjustment_fabric_clock_component_us = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
|
||||
};
|
||||
|
||||
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,17 @@
|
|||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
||||
static void get_default_8b_10b_lttpr_aux_rd_interval(
|
||||
union training_aux_rd_interval *training_rd_interval)
|
||||
{
|
||||
/* LTTPR are required to program DPCD 0000Eh to 0x4 (16ms) upon AUX
|
||||
* read reply to this register. Since old sinks with DPCD rev 1.1
|
||||
* and earlier may not support this register, assume the mandatory
|
||||
* value is programmed by the LTTPR to avoid AUX timeout issues.
|
||||
*/
|
||||
training_rd_interval->raw = 0x4;
|
||||
}
|
||||
|
||||
static int32_t get_cr_training_aux_rd_interval(struct dc_link *link,
|
||||
const struct dc_link_settings *link_settings,
|
||||
enum lttpr_mode lttpr_mode)
|
||||
|
|
@ -43,17 +54,22 @@ static int32_t get_cr_training_aux_rd_interval(struct dc_link *link,
|
|||
uint32_t wait_in_micro_secs = 100;
|
||||
|
||||
memset(&training_rd_interval, 0, sizeof(training_rd_interval));
|
||||
if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
|
||||
link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
if (lttpr_mode != LTTPR_MODE_NON_TRANSPARENT)
|
||||
wait_in_micro_secs = 400;
|
||||
if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
|
||||
wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
|
||||
if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12)
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
else if (dp_is_lttpr_present(link))
|
||||
get_default_8b_10b_lttpr_aux_rd_interval(&training_rd_interval);
|
||||
|
||||
if (training_rd_interval.raw != 0) {
|
||||
if (lttpr_mode != LTTPR_MODE_NON_TRANSPARENT)
|
||||
wait_in_micro_secs = 400;
|
||||
if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
|
||||
wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
|
||||
}
|
||||
}
|
||||
return wait_in_micro_secs;
|
||||
}
|
||||
|
|
@ -71,13 +87,15 @@ static uint32_t get_eq_training_aux_rd_interval(
|
|||
DP_128B132B_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
} else if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
|
||||
link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
} else if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12)
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
else if (dp_is_lttpr_present(link))
|
||||
get_default_8b_10b_lttpr_aux_rd_interval(&training_rd_interval);
|
||||
}
|
||||
|
||||
switch (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user