summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-03-17 18:07:38 +0000
committerMark Brown <broonie@kernel.org>2026-03-17 18:07:38 +0000
commitc8d0beedf0da06652432354882b95c33a4cb7cfe (patch)
tree369044cede12800331e74a7e10ac7d5273cd8e18 /drivers/gpu/drm/amd
parent9d4189e68ebad418eed964185d5563a71c67756d (diff)
parent58068932402c7f5bf26489e01ae8e8bb89802d1e (diff)
regulator: fp9931: Make vin-supply mandatory
Robby Cai <robby.cai@nxp.com> says: The FP9931 regulator requires a valid "vin" supply to operate correctly. Therefore, the driver should treat "vin" as a mandatory supply. This patchset updates the binding documentation to mark vin-supply as a required property, and modifies the driver accordingly. As suggested in the reviews from Andreas and Mark, v2 switches to using devm_regulator_get() since the supply is mandatory.
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c116
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c42
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_v12_0.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v15_0.c20
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc21.c4
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c1
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c6
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c16
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c6
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h18
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c11
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c6
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c3
25 files changed, 245 insertions, 107 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 06c1913d5a3f..29b400cdd6d5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1439,7 +1439,10 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
*process_info = info;
}
- vm->process_info = *process_info;
+ if (cmpxchg(&vm->process_info, NULL, *process_info) != NULL) {
+ ret = -EINVAL;
+ goto already_acquired;
+ }
/* Validate page directory and attach eviction fence */
ret = amdgpu_bo_reserve(vm->root.bo, true);
@@ -1479,6 +1482,7 @@ validate_pd_fail:
amdgpu_bo_unreserve(vm->root.bo);
reserve_pd_fail:
vm->process_info = NULL;
+already_acquired:
if (info) {
dma_fence_put(&info->eviction_fence->base);
*process_info = NULL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 3e19b51a2763..d8296dfc5e8a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2690,8 +2690,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
break;
default:
r = amdgpu_discovery_set_ip_blocks(adev);
- if (r)
+ if (r) {
+ adev->num_ip_blocks = 0;
return r;
+ }
break;
}
@@ -3247,6 +3249,8 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
if (!adev->ip_blocks[i].status.late_initialized)
continue;
+ if (!adev->ip_blocks[i].version)
+ continue;
/* skip CG for GFX, SDMA on S0ix */
if (adev->in_s0ix &&
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
@@ -3286,6 +3290,8 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
if (!adev->ip_blocks[i].status.late_initialized)
continue;
+ if (!adev->ip_blocks[i].version)
+ continue;
/* skip PG for GFX, SDMA on S0ix */
if (adev->in_s0ix &&
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
@@ -3493,6 +3499,8 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
int i, r;
for (i = 0; i < adev->num_ip_blocks; i++) {
+ if (!adev->ip_blocks[i].version)
+ continue;
if (!adev->ip_blocks[i].version->funcs->early_fini)
continue;
@@ -3570,6 +3578,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.sw)
continue;
+ if (!adev->ip_blocks[i].version)
+ continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
amdgpu_ucode_free_bo(adev);
amdgpu_free_static_csa(&adev->virt.csa_obj);
@@ -3596,6 +3606,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.late_initialized)
continue;
+ if (!adev->ip_blocks[i].version)
+ continue;
if (adev->ip_blocks[i].version->funcs->late_fini)
adev->ip_blocks[i].version->funcs->late_fini(&adev->ip_blocks[i]);
adev->ip_blocks[i].status.late_initialized = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 77e2133de5cf..7f19554b9ad1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -83,7 +83,7 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
{
struct amdgpu_device *adev = drm_to_adev(dev);
- if (adev == NULL)
+ if (adev == NULL || !adev->num_ip_blocks)
return;
amdgpu_unregister_gpu_instance(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index dc8d2f52c7d6..e244c12ceb23 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -368,15 +368,15 @@ struct amdgpu_mode_info {
struct drm_property *plane_ctm_property;
/**
- * @shaper_lut_property: Plane property to set pre-blending shaper LUT
- * that converts color content before 3D LUT. If
- * plane_shaper_tf_property != Identity TF, AMD color module will
+ * @plane_shaper_lut_property: Plane property to set pre-blending
+ * shaper LUT that converts color content before 3D LUT.
+ * If plane_shaper_tf_property != Identity TF, AMD color module will
* combine the user LUT values with pre-defined TF into the LUT
* parameters to be programmed.
*/
struct drm_property *plane_shaper_lut_property;
/**
- * @shaper_lut_size_property: Plane property for the size of
+ * @plane_shaper_lut_size_property: Plane property for the size of
* pre-blending shaper LUT as supported by the driver (read-only).
*/
struct drm_property *plane_shaper_lut_size_property;
@@ -400,10 +400,10 @@ struct amdgpu_mode_info {
*/
struct drm_property *plane_lut3d_property;
/**
- * @plane_degamma_lut_size_property: Plane property to define the max
- * size of 3D LUT as supported by the driver (read-only). The max size
- * is the max size of one dimension and, therefore, the max number of
- * entries for 3D LUT array is the 3D LUT size cubed;
+ * @plane_lut3d_size_property: Plane property to define the max size
+ * of 3D LUT as supported by the driver (read-only). The max size is
+ * the max size of one dimension and, therefore, the max number of
+ * entries for 3D LUT array is the 3D LUT size cubed.
*/
struct drm_property *plane_lut3d_size_property;
/**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 9d67b770bcc2..7c450350847d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -446,8 +446,7 @@ static int amdgpu_userq_wait_for_last_fence(struct amdgpu_usermode_queue *queue)
return ret;
}
-static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue,
- int queue_id)
+static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
@@ -461,7 +460,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue,
uq_funcs->mqd_destroy(queue);
amdgpu_userq_fence_driver_free(queue);
/* Use interrupt-safe locking since IRQ handlers may access these XArrays */
- xa_erase_irq(&uq_mgr->userq_xa, (unsigned long)queue_id);
xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
queue->userq_mgr = NULL;
list_del(&queue->userq_va_list);
@@ -470,12 +468,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue,
up_read(&adev->reset_domain->sem);
}
-static struct amdgpu_usermode_queue *
-amdgpu_userq_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
-{
- return xa_load(&uq_mgr->userq_xa, qid);
-}
-
void
amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_eviction_fence_mgr *evf_mgr)
@@ -625,22 +617,13 @@ unref_bo:
}
static int
-amdgpu_userq_destroy(struct drm_file *filp, int queue_id)
+amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
{
- struct amdgpu_fpriv *fpriv = filp->driver_priv;
- struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
- struct amdgpu_usermode_queue *queue;
int r = 0;
cancel_delayed_work_sync(&uq_mgr->resume_work);
mutex_lock(&uq_mgr->userq_mutex);
- queue = amdgpu_userq_find(uq_mgr, queue_id);
- if (!queue) {
- drm_dbg_driver(adev_to_drm(uq_mgr->adev), "Invalid queue id to destroy\n");
- mutex_unlock(&uq_mgr->userq_mutex);
- return -EINVAL;
- }
amdgpu_userq_wait_for_last_fence(queue);
/* Cancel any pending hang detection work and cleanup */
if (queue->hang_detect_fence) {
@@ -672,7 +655,7 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id)
drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n");
queue->state = AMDGPU_USERQ_STATE_HUNG;
}
- amdgpu_userq_cleanup(queue, queue_id);
+ amdgpu_userq_cleanup(queue);
mutex_unlock(&uq_mgr->userq_mutex);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -680,6 +663,37 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id)
return r;
}
+static void amdgpu_userq_kref_destroy(struct kref *kref)
+{
+ int r;
+ struct amdgpu_usermode_queue *queue =
+ container_of(kref, struct amdgpu_usermode_queue, refcount);
+ struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
+
+ r = amdgpu_userq_destroy(uq_mgr, queue);
+ if (r)
+ drm_file_err(uq_mgr->file, "Failed to destroy usermode queue %d\n", r);
+}
+
+struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid)
+{
+ struct amdgpu_usermode_queue *queue;
+
+ xa_lock(&uq_mgr->userq_xa);
+ queue = xa_load(&uq_mgr->userq_xa, qid);
+ if (queue)
+ kref_get(&queue->refcount);
+ xa_unlock(&uq_mgr->userq_xa);
+
+ return queue;
+}
+
+void amdgpu_userq_put(struct amdgpu_usermode_queue *queue)
+{
+ if (queue)
+ kref_put(&queue->refcount, amdgpu_userq_kref_destroy);
+}
+
static int amdgpu_userq_priority_permit(struct drm_file *filp,
int priority)
{
@@ -834,6 +848,9 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
goto unlock;
}
+ /* drop this refcount during queue destroy */
+ kref_init(&queue->refcount);
+
/* Wait for mode-1 reset to complete */
down_read(&adev->reset_domain->sem);
r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));
@@ -985,7 +1002,9 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
union drm_amdgpu_userq *args = data;
- int r;
+ struct amdgpu_fpriv *fpriv = filp->driver_priv;
+ struct amdgpu_usermode_queue *queue;
+ int r = 0;
if (!amdgpu_userq_enabled(dev))
return -ENOTSUPP;
@@ -1000,11 +1019,16 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
drm_file_err(filp, "Failed to create usermode queue\n");
break;
- case AMDGPU_USERQ_OP_FREE:
- r = amdgpu_userq_destroy(filp, args->in.queue_id);
- if (r)
- drm_file_err(filp, "Failed to destroy usermode queue\n");
+ case AMDGPU_USERQ_OP_FREE: {
+ xa_lock(&fpriv->userq_mgr.userq_xa);
+ queue = __xa_erase(&fpriv->userq_mgr.userq_xa, args->in.queue_id);
+ xa_unlock(&fpriv->userq_mgr.userq_xa);
+ if (!queue)
+ return -ENOENT;
+
+ amdgpu_userq_put(queue);
break;
+ }
default:
drm_dbg_driver(dev, "Invalid user queue op specified: %d\n", args->in.op);
@@ -1023,16 +1047,23 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr)
/* Resume all the queues for this process */
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
+ queue = amdgpu_userq_get(uq_mgr, queue_id);
+ if (!queue)
+ continue;
+
if (!amdgpu_userq_buffer_vas_mapped(queue)) {
drm_file_err(uq_mgr->file,
"trying restore queue without va mapping\n");
queue->state = AMDGPU_USERQ_STATE_INVALID_VA;
+ amdgpu_userq_put(queue);
continue;
}
r = amdgpu_userq_restore_helper(queue);
if (r)
ret = r;
+
+ amdgpu_userq_put(queue);
}
if (ret)
@@ -1266,9 +1297,13 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr)
amdgpu_userq_detect_and_reset_queues(uq_mgr);
/* Try to unmap all the queues in this process ctx */
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
+ queue = amdgpu_userq_get(uq_mgr, queue_id);
+ if (!queue)
+ continue;
r = amdgpu_userq_preempt_helper(queue);
if (r)
ret = r;
+ amdgpu_userq_put(queue);
}
if (ret)
@@ -1301,16 +1336,24 @@ amdgpu_userq_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr)
int ret;
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
+ queue = amdgpu_userq_get(uq_mgr, queue_id);
+ if (!queue)
+ continue;
+
struct dma_fence *f = queue->last_fence;
- if (!f || dma_fence_is_signaled(f))
+ if (!f || dma_fence_is_signaled(f)) {
+ amdgpu_userq_put(queue);
continue;
+ }
ret = dma_fence_wait_timeout(f, true, msecs_to_jiffies(100));
if (ret <= 0) {
drm_file_err(uq_mgr->file, "Timed out waiting for fence=%llu:%llu\n",
f->context, f->seqno);
+ amdgpu_userq_put(queue);
return -ETIMEDOUT;
}
+ amdgpu_userq_put(queue);
}
return 0;
@@ -1361,20 +1404,23 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *f
void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
{
struct amdgpu_usermode_queue *queue;
- unsigned long queue_id;
+ unsigned long queue_id = 0;
+
+ for (;;) {
+ xa_lock(&userq_mgr->userq_xa);
+ queue = xa_find(&userq_mgr->userq_xa, &queue_id, ULONG_MAX,
+ XA_PRESENT);
+ if (queue)
+ __xa_erase(&userq_mgr->userq_xa, queue_id);
+ xa_unlock(&userq_mgr->userq_xa);
- cancel_delayed_work_sync(&userq_mgr->resume_work);
+ if (!queue)
+ break;
- mutex_lock(&userq_mgr->userq_mutex);
- amdgpu_userq_detect_and_reset_queues(userq_mgr);
- xa_for_each(&userq_mgr->userq_xa, queue_id, queue) {
- amdgpu_userq_wait_for_last_fence(queue);
- amdgpu_userq_unmap_helper(queue);
- amdgpu_userq_cleanup(queue, queue_id);
+ amdgpu_userq_put(queue);
}
xa_destroy(&userq_mgr->userq_xa);
- mutex_unlock(&userq_mgr->userq_mutex);
mutex_destroy(&userq_mgr->userq_mutex);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
index 5845d8959034..736c1d38297c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
@@ -74,6 +74,7 @@ struct amdgpu_usermode_queue {
struct dentry *debugfs_queue;
struct delayed_work hang_detect_work;
struct dma_fence *hang_detect_fence;
+ struct kref refcount;
struct list_head userq_va_list;
};
@@ -112,6 +113,9 @@ struct amdgpu_db_info {
struct amdgpu_userq_obj *db_obj;
};
+struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid);
+void amdgpu_userq_put(struct amdgpu_usermode_queue *queue);
+
int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *file_priv,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index 7e9cf1868cc9..5239b06b9ab0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -466,7 +466,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
struct drm_amdgpu_userq_signal *args = data;
struct drm_gem_object **gobj_write = NULL;
struct drm_gem_object **gobj_read = NULL;
- struct amdgpu_usermode_queue *queue;
+ struct amdgpu_usermode_queue *queue = NULL;
struct amdgpu_userq_fence *userq_fence;
struct drm_syncobj **syncobj = NULL;
u32 *bo_handles_write, num_write_bo_handles;
@@ -553,7 +553,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
}
/* Retrieve the user queue */
- queue = xa_load(&userq_mgr->userq_xa, args->queue_id);
+ queue = amdgpu_userq_get(userq_mgr, args->queue_id);
if (!queue) {
r = -ENOENT;
goto put_gobj_write;
@@ -648,6 +648,9 @@ free_syncobj:
free_syncobj_handles:
kfree(syncobj_handles);
+ if (queue)
+ amdgpu_userq_put(queue);
+
return r;
}
@@ -660,7 +663,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
struct drm_amdgpu_userq_wait *wait_info = data;
struct amdgpu_fpriv *fpriv = filp->driver_priv;
struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr;
- struct amdgpu_usermode_queue *waitq;
+ struct amdgpu_usermode_queue *waitq = NULL;
struct drm_gem_object **gobj_write;
struct drm_gem_object **gobj_read;
struct dma_fence **fences = NULL;
@@ -926,7 +929,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
*/
num_fences = dma_fence_dedup_array(fences, num_fences);
- waitq = xa_load(&userq_mgr->userq_xa, wait_info->waitq_id);
+ waitq = amdgpu_userq_get(userq_mgr, wait_info->waitq_id);
if (!waitq) {
r = -EINVAL;
goto free_fences;
@@ -983,32 +986,14 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
r = -EFAULT;
goto free_fences;
}
-
- kfree(fences);
- kfree(fence_info);
}
- drm_exec_fini(&exec);
- for (i = 0; i < num_read_bo_handles; i++)
- drm_gem_object_put(gobj_read[i]);
- kfree(gobj_read);
-
- for (i = 0; i < num_write_bo_handles; i++)
- drm_gem_object_put(gobj_write[i]);
- kfree(gobj_write);
-
- kfree(timeline_points);
- kfree(timeline_handles);
- kfree(syncobj_handles);
- kfree(bo_handles_write);
- kfree(bo_handles_read);
-
- return 0;
-
free_fences:
- while (num_fences-- > 0)
- dma_fence_put(fences[num_fences]);
- kfree(fences);
+ if (fences) {
+ while (num_fences-- > 0)
+ dma_fence_put(fences[num_fences]);
+ kfree(fences);
+ }
free_fence_info:
kfree(fence_info);
exec_fini:
@@ -1032,5 +1017,8 @@ free_bo_handles_write:
free_bo_handles_read:
kfree(bo_handles_read);
+ if (waitq)
+ amdgpu_userq_put(waitq);
+
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index 5bfa5d1d0b36..023c7345ea54 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -731,6 +731,9 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe)
int i;
struct amdgpu_device *adev = mes->adev;
union MESAPI_SET_HW_RESOURCES mes_set_hw_res_pkt;
+ uint32_t mes_rev = (pipe == AMDGPU_MES_SCHED_PIPE) ?
+ (mes->sched_version & AMDGPU_MES_VERSION_MASK) :
+ (mes->kiq_version & AMDGPU_MES_VERSION_MASK);
memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt));
@@ -785,7 +788,7 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe)
* handling support, other queue will not use the oversubscribe timer.
* handling mode - 0: disabled; 1: basic version; 2: basic+ version
*/
- mes_set_hw_res_pkt.oversubscription_timer = 50;
+ mes_set_hw_res_pkt.oversubscription_timer = mes_rev < 0x8b ? 0 : 50;
mes_set_hw_res_pkt.unmapped_doorbell_handling = 1;
if (amdgpu_mes_log_enable) {
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c
index 723ddae17644..73a709773e85 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c
@@ -69,12 +69,12 @@ static int psp_v15_0_0_ring_stop(struct psp_context *psp,
0x80000000, 0x80000000, false);
} else {
/* Write the ring destroy command*/
- WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64,
+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64,
GFX_CTRL_CMD_ID_DESTROY_RINGS);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) */
- ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),
+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
}
@@ -116,7 +116,7 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp,
} else {
/* Wait for sOS ready for ring creation */
- ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),
+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (ret) {
DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");
@@ -125,23 +125,23 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp,
/* Write low address of the ring to C2PMSG_69 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
- WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_69, psp_ring_reg);
+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_69, psp_ring_reg);
/* Write high address of the ring to C2PMSG_70 */
psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
- WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_70, psp_ring_reg);
+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_70, psp_ring_reg);
/* Write size of ring to C2PMSG_71 */
psp_ring_reg = ring->ring_size;
- WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_71, psp_ring_reg);
+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_71, psp_ring_reg);
/* Write the ring initialization command to C2PMSG_64 */
psp_ring_reg = ring_type;
psp_ring_reg = psp_ring_reg << 16;
- WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64, psp_ring_reg);
+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64, psp_ring_reg);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) in C2PMSG_64 */
- ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64),
+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x8000FFFF, false);
}
@@ -174,7 +174,7 @@ static uint32_t psp_v15_0_0_ring_get_wptr(struct psp_context *psp)
if (amdgpu_sriov_vf(adev))
data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102);
else
- data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67);
+ data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67);
return data;
}
@@ -188,7 +188,7 @@ static void psp_v15_0_0_ring_set_wptr(struct psp_context *psp, uint32_t value)
WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,
GFX_CTRL_CMD_ID_CONSUME_CMD);
} else
- WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67, value);
+ WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value);
}
static const struct psp_funcs psp_v15_0_0_funcs = {
diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
index 8122a5cacf07..a0ad1f8a76f0 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
@@ -858,7 +858,9 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block)
AMD_CG_SUPPORT_IH_CG |
AMD_CG_SUPPORT_BIF_MGCG |
AMD_CG_SUPPORT_BIF_LS;
- adev->pg_flags = AMD_PG_SUPPORT_VCN |
+ adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG |
+ AMD_PG_SUPPORT_VCN |
+ AMD_PG_SUPPORT_JPEG_DPG |
AMD_PG_SUPPORT_JPEG |
AMD_PG_SUPPORT_GFX_PG;
adev->external_rev_id = adev->rev_id + 0x1;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 8ea31699d38b..f5d2847e1cbb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -593,6 +593,7 @@ int pqm_update_queue_properties(struct process_queue_manager *pqm,
p->queue_size)) {
pr_debug("ring buf 0x%llx size 0x%llx not mapped on GPU\n",
p->queue_address, p->queue_size);
+ amdgpu_bo_unreserve(vm->root.bo);
return -EFAULT;
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 2ba98f384685..cd1e58b8defc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -1706,6 +1706,7 @@ __set_dm_plane_colorop_3dlut(struct drm_plane_state *plane_state,
struct dc_transfer_func *tf = &dc_plane_state->in_shaper_func;
struct drm_atomic_state *state = plane_state->state;
const struct amdgpu_device *adev = drm_to_adev(colorop->dev);
+ bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
const struct drm_device *dev = colorop->dev;
const struct drm_color_lut32 *lut3d;
uint32_t lut3d_size;
@@ -1722,7 +1723,7 @@ __set_dm_plane_colorop_3dlut(struct drm_plane_state *plane_state,
}
if (colorop_state && !colorop_state->bypass && colorop->type == DRM_COLOROP_3D_LUT) {
- if (!adev->dm.dc->caps.color.dpp.hw_3d_lut) {
+ if (!has_3dlut) {
drm_dbg(dev, "3D LUT is not supported by hardware\n");
return -EINVAL;
}
@@ -1875,6 +1876,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state,
struct drm_colorop *colorop = plane_state->color_pipeline;
struct drm_device *dev = plane_state->plane->dev;
struct amdgpu_device *adev = drm_to_adev(dev);
+ bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
int ret;
/* 1D Curve - DEGAM TF */
@@ -1907,7 +1909,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state,
if (ret)
return ret;
- if (adev->dm.dc->caps.color.dpp.hw_3d_lut) {
+ if (has_3dlut) {
/* 1D Curve & LUT - SHAPER TF & LUT */
colorop = colorop->next;
if (!colorop) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
index f25c0ede7199..d59ba82d3d7c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
@@ -60,6 +60,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr
struct drm_colorop *ops[MAX_COLOR_PIPELINE_OPS];
struct drm_device *dev = plane->dev;
struct amdgpu_device *adev = drm_to_adev(dev);
+ bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
int ret;
int i = 0;
@@ -112,7 +113,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr
i++;
- if (adev->dm.dc->caps.color.dpp.hw_3d_lut) {
+ if (has_3dlut) {
/* 1D curve - SHAPER TF */
ops[i] = kzalloc_obj(*ops[0]);
if (!ops[i]) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 130190e8a1b2..304437c2284d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -765,15 +765,15 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
dm->adev->mode_info.crtcs[crtc_index] = acrtc;
/* Don't enable DRM CRTC degamma property for
- * 1. Degamma is replaced by color pipeline.
- * 2. DCE since it doesn't support programmable degamma anywhere.
- * 3. DCN401 since pre-blending degamma LUT doesn't apply to cursor.
+ * 1. DCE since it doesn't support programmable degamma anywhere.
+ * 2. DCN401 since pre-blending degamma LUT doesn't apply to cursor.
+ * Note: DEGAMMA properties are created even if the primary plane has the
+ * COLOR_PIPELINE property. User space can use either the DEGAMMA properties
+ * or the COLOR_PIPELINE property. An atomic commit which attempts to enable
+ * both is rejected.
*/
- if (plane->color_pipeline_property)
- has_degamma = false;
- else
- has_degamma = dm->adev->dm.dc->caps.color.dpp.dcn_arch &&
- dm->adev->dm.dc->ctx->dce_version != DCN_VERSION_4_01;
+ has_degamma = dm->adev->dm.dc->caps.color.dpp.dcn_arch &&
+ dm->adev->dm.dc->ctx->dce_version != DCN_VERSION_4_01;
drm_crtc_enable_color_mgmt(&acrtc->base, has_degamma ? MAX_COLOR_LUT_ENTRIES : 0,
true, MAX_COLOR_LUT_ENTRIES);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 70587e5a8d46..127207e18dcb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1256,6 +1256,14 @@ static int amdgpu_dm_plane_atomic_check(struct drm_plane *plane,
if (ret)
return ret;
+ /* Reject commits that attempt to use both COLOR_PIPELINE and CRTC DEGAMMA_LUT */
+ if (new_plane_state->color_pipeline && new_crtc_state->degamma_lut) {
+ drm_dbg_atomic(plane->dev,
+ "[PLANE:%d:%s] COLOR_PIPELINE and CRTC DEGAMMA_LUT cannot be enabled simultaneously\n",
+ plane->base.id, plane->name);
+ return -EINVAL;
+ }
+
ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
index 3711d400773a..4c4e61bc91b5 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
@@ -38,7 +38,11 @@
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0),\
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1),\
SR(DISPCLK_FREQ_CHANGE_CNTL),\
- SR(DC_MEM_GLOBAL_PWR_REQ_CNTL)
+ SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\
+ SR(MICROSECOND_TIME_BASE_DIV),\
+ SR(MILLISECOND_TIME_BASE_DIV),\
+ SR(DCCG_GATE_DISABLE_CNTL),\
+ SR(DCCG_GATE_DISABLE_CNTL2)
#define DCCG_REG_LIST_DCN2() \
DCCG_COMMON_REG_LIST_DCN_BASE(),\
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c
index 75c69348027e..c4d4eea140f3 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c
@@ -96,6 +96,25 @@ static void dccg21_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppcl
dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
}
+/*
+ * On DCN21 S0i3 resume, BIOS programs MICROSECOND_TIME_BASE_DIV to
+ * 0x00120464 as a marker that golden init has already been done.
+ * dcn21_s0i3_golden_init_wa() reads this marker later in bios_golden_init()
+ * to decide whether to skip golden init.
+ *
+ * dccg2_init() unconditionally overwrites MICROSECOND_TIME_BASE_DIV to
+ * 0x00120264, destroying the marker before it can be read.
+ *
+ * Guard the call: if the S0i3 marker is present, skip dccg2_init() so the
+ * WA can function correctly. bios_golden_init() will handle init in that case.
+ */
+static void dccg21_init(struct dccg *dccg)
+{
+ if (dccg2_is_s0i3_golden_init_wa_done(dccg))
+ return;
+
+ dccg2_init(dccg);
+}
static const struct dccg_funcs dccg21_funcs = {
.update_dpp_dto = dccg21_update_dpp_dto,
@@ -103,7 +122,7 @@ static const struct dccg_funcs dccg21_funcs = {
.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
.otg_add_pixel = dccg2_otg_add_pixel,
.otg_drop_pixel = dccg2_otg_drop_pixel,
- .dccg_init = dccg2_init,
+ .dccg_init = dccg21_init,
.refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */
.allow_clock_gating = dccg2_allow_clock_gating,
.enable_memory_low_power = dccg2_enable_memory_low_power,
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h
index 067e49cb238e..e2381ca0be0b 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h
@@ -34,7 +34,13 @@
DCCG_SRII(DTO_PARAM, DPPCLK, 1),\
DCCG_SRII(DTO_PARAM, DPPCLK, 2),\
DCCG_SRII(DTO_PARAM, DPPCLK, 3),\
- SR(REFCLK_CNTL)
+ SR(REFCLK_CNTL),\
+ SR(DISPCLK_FREQ_CHANGE_CNTL),\
+ SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\
+ SR(MICROSECOND_TIME_BASE_DIV),\
+ SR(MILLISECOND_TIME_BASE_DIV),\
+ SR(DCCG_GATE_DISABLE_CNTL),\
+ SR(DCCG_GATE_DISABLE_CNTL2)
#define DCCG_MASK_SH_LIST_DCN301(mask_sh) \
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 0, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h
index bf659920d4cc..b5e3849ef12a 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h
@@ -64,9 +64,12 @@
SR(DSCCLK1_DTO_PARAM),\
SR(DSCCLK2_DTO_PARAM),\
SR(DSCCLK_DTO_CTRL),\
+ SR(DCCG_GATE_DISABLE_CNTL),\
SR(DCCG_GATE_DISABLE_CNTL2),\
SR(DCCG_GATE_DISABLE_CNTL3),\
- SR(HDMISTREAMCLK0_DTO_PARAM)
+ SR(HDMISTREAMCLK0_DTO_PARAM),\
+ SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\
+ SR(MICROSECOND_TIME_BASE_DIV)
#define DCCG_MASK_SH_LIST_DCN31(mask_sh) \
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h
index a609635f35db..ecbdc05f7c45 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h
@@ -70,11 +70,14 @@
SR(DSCCLK2_DTO_PARAM),\
SR(DSCCLK3_DTO_PARAM),\
SR(DSCCLK_DTO_CTRL),\
+ SR(DCCG_GATE_DISABLE_CNTL),\
SR(DCCG_GATE_DISABLE_CNTL2),\
SR(DCCG_GATE_DISABLE_CNTL3),\
SR(HDMISTREAMCLK0_DTO_PARAM),\
SR(OTG_PIXEL_RATE_DIV),\
- SR(DTBCLK_P_CNTL)
+ SR(DTBCLK_P_CNTL),\
+ SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\
+ SR(MICROSECOND_TIME_BASE_DIV)
#define DCCG_MASK_SH_LIST_DCN314_COMMON(mask_sh) \
DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 0, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index b91517b9fedc..eb198d52a115 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -72,7 +72,11 @@ void dcn401_initialize_min_clocks(struct dc *dc)
* audio corruption. Read current DISPCLK from DENTIST and request the same
* freq to ensure that the timing is valid and unchanged.
*/
- clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
+ if (dc->clk_mgr->funcs->get_dispclk_from_dentist) {
+ clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr);
+ } else {
+ clocks->dispclk_khz = dc->clk_mgr->boot_snapshot.dispclk * 1000;
+ }
}
clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
clocks->fclk_p_state_change_support = true;
diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h
index 0e4c195297a4..fe97943b9b97 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h
@@ -82,6 +82,24 @@
#define regMPASP_SMN_IH_SW_INT_CTRL 0x0142
#define regMPASP_SMN_IH_SW_INT_CTRL_BASE_IDX 0
+// addressBlock: mp_SmuMpASPPub_PcruDec
+// base address: 0x3800000
+#define regMPASP_PCRU1_MPASP_C2PMSG_64 0x4280
+#define regMPASP_PCRU1_MPASP_C2PMSG_64_BASE_IDX 3
+#define regMPASP_PCRU1_MPASP_C2PMSG_65 0x4281
+#define regMPASP_PCRU1_MPASP_C2PMSG_65_BASE_IDX 3
+#define regMPASP_PCRU1_MPASP_C2PMSG_66 0x4282
+#define regMPASP_PCRU1_MPASP_C2PMSG_66_BASE_IDX 3
+#define regMPASP_PCRU1_MPASP_C2PMSG_67 0x4283
+#define regMPASP_PCRU1_MPASP_C2PMSG_67_BASE_IDX 3
+#define regMPASP_PCRU1_MPASP_C2PMSG_68 0x4284
+#define regMPASP_PCRU1_MPASP_C2PMSG_68_BASE_IDX 3
+#define regMPASP_PCRU1_MPASP_C2PMSG_69 0x4285
+#define regMPASP_PCRU1_MPASP_C2PMSG_69_BASE_IDX 3
+#define regMPASP_PCRU1_MPASP_C2PMSG_70 0x4286
+#define regMPASP_PCRU1_MPASP_C2PMSG_70_BASE_IDX 3
+#define regMPASP_PCRU1_MPASP_C2PMSG_71 0x4287
+#define regMPASP_PCRU1_MPASP_C2PMSG_71_BASE_IDX 3
// addressBlock: mp_SmuMp1_SmnDec
// base address: 0x0
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index e030f1e186cb..a8d63d4d1f6e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2034,6 +2034,7 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu,
smu, SMU_DRIVER_TABLE_GPU_METRICS);
SmuMetricsExternal_t metrics_ext;
SmuMetrics_t *metrics = &metrics_ext.SmuMetrics;
+ uint32_t mp1_ver = amdgpu_ip_version(smu->adev, MP1_HWIP, 0);
int ret = 0;
ret = smu_cmn_get_metrics_table(smu,
@@ -2058,7 +2059,12 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu,
metrics->Vcn1ActivityPercentage);
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
- gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
+
+ if ((mp1_ver == IP_VERSION(13, 0, 0) && smu->smc_fw_version <= 0x004e1e00) ||
+ (mp1_ver == IP_VERSION(13, 0, 10) && smu->smc_fw_version <= 0x00500800))
+ gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
+ else
+ gpu_metrics->energy_accumulator = UINT_MAX;
if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD)
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
@@ -2216,7 +2222,8 @@ static int smu_v13_0_0_restore_user_od_settings(struct smu_context *smu)
user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) |
BIT(PP_OD_FEATURE_UCLK_BIT) |
BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) |
- BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ BIT(PP_OD_FEATURE_FAN_CURVE_BIT) |
+ BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
res = smu_v13_0_0_upload_overdrive_table(smu, user_od_table);
user_od_table->OverDriveTable.FeatureCtrlMask = 0;
if (res == 0)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index af0482c9caa7..5500a0f12f0e 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -2065,7 +2065,8 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu,
metrics->Vcn1ActivityPercentage);
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
- gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
+ gpu_metrics->energy_accumulator = smu->smc_fw_version <= 0x00521400 ?
+ metrics->EnergyAccumulator : UINT_MAX;
if (metrics->AverageGfxActivity <= SMU_13_0_7_BUSY_THRESHOLD)
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
@@ -2223,7 +2224,8 @@ static int smu_v13_0_7_restore_user_od_settings(struct smu_context *smu)
user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) |
BIT(PP_OD_FEATURE_UCLK_BIT) |
BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) |
- BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ BIT(PP_OD_FEATURE_FAN_CURVE_BIT) |
+ BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
res = smu_v13_0_7_upload_overdrive_table(smu, user_od_table);
user_od_table->OverDriveTable.FeatureCtrlMask = 0;
if (res == 0)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
index 9994d4369da8..73762d9b5969 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
@@ -2311,7 +2311,8 @@ static int smu_v14_0_2_restore_user_od_settings(struct smu_context *smu)
user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) |
BIT(PP_OD_FEATURE_UCLK_BIT) |
BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) |
- BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ BIT(PP_OD_FEATURE_FAN_CURVE_BIT) |
+ BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
res = smu_v14_0_2_upload_overdrive_table(smu, user_od_table);
user_od_table->OverDriveTable.FeatureCtrlMask = 0;
if (res == 0)