mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-25 23:20:59 -05:00
Merge tag 'amd-drm-fixes-6.14-2025-03-12' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-6.14-2025-03-12: amdgpu: - GC 12.x DCC fix - DC DCE 6.x fix - Hibernation fix - HPD fix - Backlight fixes - Color depth fix - UAF fix in hdcp_work - VCE 2.x fix - GC 12.x PTE fix amdkfd: - Queue eviction fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250312190931.216506-1-alexander.deucher@amd.com
This commit is contained in:
@@ -2555,7 +2555,6 @@ static int amdgpu_pmops_freeze(struct device *dev)
|
||||
int r;
|
||||
|
||||
r = amdgpu_device_suspend(drm_dev, true);
|
||||
adev->in_s4 = false;
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -2567,8 +2566,13 @@ static int amdgpu_pmops_freeze(struct device *dev)
|
||||
static int amdgpu_pmops_thaw(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
return amdgpu_device_resume(drm_dev, true);
|
||||
r = amdgpu_device_resume(drm_dev, true);
|
||||
adev->in_s4 = false;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_poweroff(struct device *dev)
|
||||
@@ -2581,6 +2585,9 @@ static int amdgpu_pmops_poweroff(struct device *dev)
|
||||
static int amdgpu_pmops_restore(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
|
||||
adev->in_s4 = false;
|
||||
|
||||
return amdgpu_device_resume(drm_dev, true);
|
||||
}
|
||||
|
||||
@@ -528,8 +528,9 @@ static void gmc_v12_0_get_vm_pte(struct amdgpu_device *adev,
|
||||
|
||||
bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
coherent = bo->flags & AMDGPU_GEM_CREATE_COHERENT;
|
||||
is_system = (bo->tbo.resource->mem_type == TTM_PL_TT) ||
|
||||
(bo->tbo.resource->mem_type == AMDGPU_PL_PREEMPT);
|
||||
is_system = bo->tbo.resource &&
|
||||
(bo->tbo.resource->mem_type == TTM_PL_TT ||
|
||||
bo->tbo.resource->mem_type == AMDGPU_PL_PREEMPT);
|
||||
|
||||
if (bo && bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
|
||||
*flags |= AMDGPU_PTE_DCC;
|
||||
|
||||
@@ -284,7 +284,7 @@ static int vce_v2_0_stop(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCN);
|
||||
ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE);
|
||||
if (!ip_block)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -1230,11 +1230,13 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
|
||||
decrement_queue_count(dqm, qpd, q);
|
||||
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
retval = remove_queue_mes(dqm, q, qpd);
|
||||
if (retval) {
|
||||
int err;
|
||||
|
||||
err = remove_queue_mes(dqm, q, qpd);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to evict queue %d\n",
|
||||
q->properties.queue_id);
|
||||
goto out;
|
||||
retval = err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +245,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector);
|
||||
static void handle_hpd_rx_irq(void *param);
|
||||
|
||||
static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
int bl_idx,
|
||||
u32 user_brightness);
|
||||
|
||||
static bool
|
||||
is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
|
||||
struct drm_crtc_state *new_crtc_state);
|
||||
@@ -3371,8 +3375,19 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
|
||||
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
|
||||
/* set the backlight after a reset */
|
||||
for (i = 0; i < dm->num_of_edps; i++) {
|
||||
if (dm->backlight_dev[i])
|
||||
amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* leave display off for S4 sequence */
|
||||
if (adev->in_s4)
|
||||
return 0;
|
||||
|
||||
/* Recreate dc_state - DC invalidates it when setting power state to S3. */
|
||||
dc_state_release(dm_state->context);
|
||||
dm_state->context = dc_state_create(dm->dc, NULL);
|
||||
@@ -4906,6 +4921,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
|
||||
dm->backlight_dev[aconnector->bl_idx] =
|
||||
backlight_device_register(bl_name, aconnector->base.kdev, dm,
|
||||
&amdgpu_dm_backlight_ops, &props);
|
||||
dm->brightness[aconnector->bl_idx] = props.brightness;
|
||||
|
||||
if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
|
||||
DRM_ERROR("DM: Backlight registration failed!\n");
|
||||
@@ -4973,7 +4989,6 @@ static void setup_backlight_device(struct amdgpu_display_manager *dm,
|
||||
aconnector->bl_idx = bl_idx;
|
||||
|
||||
amdgpu_dm_update_backlight_caps(dm, bl_idx);
|
||||
dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
|
||||
dm->backlight_link[bl_idx] = link;
|
||||
dm->num_of_edps++;
|
||||
|
||||
|
||||
@@ -455,6 +455,7 @@ void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
|
||||
for (i = 0; i < hdcp_work->max_link; i++) {
|
||||
cancel_delayed_work_sync(&hdcp_work[i].callback_dwork);
|
||||
cancel_delayed_work_sync(&hdcp_work[i].watchdog_timer_dwork);
|
||||
cancel_delayed_work_sync(&hdcp_work[i].property_validate_dwork);
|
||||
}
|
||||
|
||||
sysfs_remove_bin_file(kobj, &hdcp_work[0].attr);
|
||||
|
||||
@@ -894,8 +894,16 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
int irq_type;
|
||||
int i;
|
||||
|
||||
/* First, clear all hpd and hpdrx interrupts */
|
||||
for (i = DC_IRQ_SOURCE_HPD1; i <= DC_IRQ_SOURCE_HPD6RX; i++) {
|
||||
if (!dc_interrupt_set(adev->dm.dc, i, false))
|
||||
drm_err(dev, "Failed to clear hpd(rx) source=%d on init\n",
|
||||
i);
|
||||
}
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter) {
|
||||
struct amdgpu_dm_connector *amdgpu_dm_connector;
|
||||
@@ -908,10 +916,31 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
|
||||
|
||||
dc_link = amdgpu_dm_connector->dc_link;
|
||||
|
||||
/*
|
||||
* Get a base driver irq reference for hpd ints for the lifetime
|
||||
* of dm. Note that only hpd interrupt types are registered with
|
||||
* base driver; hpd_rx types aren't. IOW, amdgpu_irq_get/put on
|
||||
* hpd_rx isn't available. DM currently controls hpd_rx
|
||||
* explicitly with dc_interrupt_set()
|
||||
*/
|
||||
if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
true);
|
||||
irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1;
|
||||
/*
|
||||
* TODO: There's a mismatch between mode_info.num_hpd
|
||||
* and what bios reports as the # of connectors with hpd
|
||||
* sources. Since the # of hpd source types registered
|
||||
* with base driver == mode_info.num_hpd, we have to
|
||||
* fallback to dc_interrupt_set for the remaining types.
|
||||
*/
|
||||
if (irq_type < adev->mode_info.num_hpd) {
|
||||
if (amdgpu_irq_get(adev, &adev->hpd_irq, irq_type))
|
||||
drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n",
|
||||
dc_link->irq_source_hpd);
|
||||
} else {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) {
|
||||
@@ -921,12 +950,6 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
/* Update reference counts for HPDs */
|
||||
for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) {
|
||||
if (amdgpu_irq_get(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1))
|
||||
drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -942,7 +965,7 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
int i;
|
||||
int irq_type;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter) {
|
||||
@@ -956,9 +979,18 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
|
||||
dc_link = amdgpu_dm_connector->dc_link;
|
||||
|
||||
if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
false);
|
||||
irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1;
|
||||
|
||||
/* TODO: See same TODO in amdgpu_dm_hpd_init() */
|
||||
if (irq_type < adev->mode_info.num_hpd) {
|
||||
if (amdgpu_irq_put(adev, &adev->hpd_irq, irq_type))
|
||||
drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n",
|
||||
dc_link->irq_source_hpd);
|
||||
} else {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) {
|
||||
@@ -968,10 +1000,4 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
/* Update reference counts for HPDs */
|
||||
for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) {
|
||||
if (amdgpu_irq_put(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1))
|
||||
drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,8 +277,11 @@ static int amdgpu_dm_plane_validate_dcc(struct amdgpu_device *adev,
|
||||
if (!dcc->enable)
|
||||
return 0;
|
||||
|
||||
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
|
||||
!dc->cap_funcs.get_dcc_compression_cap)
|
||||
if (adev->family < AMDGPU_FAMILY_GC_12_0_0 &&
|
||||
format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dc->cap_funcs.get_dcc_compression_cap)
|
||||
return -EINVAL;
|
||||
|
||||
input.format = format;
|
||||
|
||||
@@ -3389,10 +3389,13 @@ static int get_norm_pix_clk(const struct dc_crtc_timing *timing)
|
||||
break;
|
||||
case COLOR_DEPTH_121212:
|
||||
normalized_pix_clk = (pix_clk * 36) / 24;
|
||||
break;
|
||||
break;
|
||||
case COLOR_DEPTH_141414:
|
||||
normalized_pix_clk = (pix_clk * 42) / 24;
|
||||
break;
|
||||
case COLOR_DEPTH_161616:
|
||||
normalized_pix_clk = (pix_clk * 48) / 24;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
|
||||
@@ -239,6 +239,7 @@ static const struct timing_generator_funcs dce60_tg_funcs = {
|
||||
dce60_timing_generator_enable_advanced_request,
|
||||
.configure_crc = dce60_configure_crc,
|
||||
.get_crc = dce110_get_crc,
|
||||
.is_two_pixels_per_container = dce110_is_two_pixels_per_container,
|
||||
};
|
||||
|
||||
void dce60_timing_generator_construct(
|
||||
|
||||
Reference in New Issue
Block a user