Merge tag 'drm-fixes-2022-11-25' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "Weekly fixes, amdgpu has not quite settled down.

  Most of the changes are small, and the non-amdgpu ones are all fine.
  There are a bunch of DP MST DSC fixes that fix some issues introduced
  in a previous larger MST rework.

  The biggest one is mainly propagating some error values properly
  instead of bool returns, and I think it just looks large but doesn't
  really change anything too much, except propagating errors that are
  required to avoid deadlocks. I've gone over it and a few others and
  they've had some decent testing over the last few weeks.

  Summary:

  amdgpu:
   - amdgpu gang submit fix
   - DCN 3.1.4 fixes
   - DP MST DSC deadlock fixes
   - HMM userptr fixes
   - Fix Aldebaran CU occupancy reporting
   - GFX11 fixes
   - PSP suspend/resume fix
   - DCE12 KASAN fix
   - DCN 3.2.x fixes
   - Rotated cursor fix
   - SMU 13.x fix
   - DELL platform suspend/resume fixes
   - VCN4 SR-IOV fix
   - Display regression fix for polled connectors

  i915:
   - Fix GVT KVM reference count handling
   - Never purge busy TTM objects
   - Fix warn in intel_display_power_*_domain() functions

  dma-buf:
   - Use dma_fence_unwrap_for_each when importing sync files
   - Fix race in dma_heap_add()

  fbcon:
   - Fix use of uninitialized memory in logo"

* tag 'drm-fixes-2022-11-25' of git://anongit.freedesktop.org/drm/drm: (30 commits)
  drm/amdgpu/vcn: re-use original vcn0 doorbell value
  drm/amdgpu: Partially revert "drm/amdgpu: update drm_display_info correctly when the edid is read"
  drm/amd/display: No display after resume from WB/CB
  drm/amdgpu: fix use-after-free during gpu recovery
  drm/amd/pm: update driver if header for smu_13_0_7
  drm/amd/display: Fix rotated cursor offset calculation
  drm/amd/display: Use new num clk levels struct for max mclk index
  drm/amd/display: Avoid setting pixel rate divider to N/A
  drm/amd/display: Use viewport height for subvp mall allocation size
  drm/amd/display: Update soc bounding box for dcn32/dcn321
  drm/amd/dc/dce120: Fix audio register mapping, stop triggering KASAN
  drm/amdgpu/psp: don't free PSP buffers on suspend
  fbcon: Use kzalloc() in fbcon_prepare_logo()
  dma-buf: fix racing conflict of dma_heap_add()
  drm/amd/amdgpu: reserve vm invalidation engine for firmware
  drm/amdgpu: Enable Aldebaran devices to report CU Occupancy
  drm/amdgpu: fix userptr HMM range handling v2
  drm/amdgpu: always register an MMU notifier for userptr
  drm/amdgpu/dm/mst: Fix uninitialized var in pre_compute_mst_dsc_configs_for_state()
  drm/amdgpu/dm/dp_mst: Don't grab mst_mgr->lock when computing DSC state
  ...
This commit is contained in:
Linus Torvalds
2022-11-25 09:20:42 -08:00
38 changed files with 487 additions and 326 deletions

View File

@@ -15,6 +15,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/dma-buf.h> #include <linux/dma-buf.h>
#include <linux/dma-fence.h> #include <linux/dma-fence.h>
#include <linux/dma-fence-unwrap.h>
#include <linux/anon_inodes.h> #include <linux/anon_inodes.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
@@ -391,8 +392,10 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
const void __user *user_data) const void __user *user_data)
{ {
struct dma_buf_import_sync_file arg; struct dma_buf_import_sync_file arg;
struct dma_fence *fence; struct dma_fence *fence, *f;
enum dma_resv_usage usage; enum dma_resv_usage usage;
struct dma_fence_unwrap iter;
unsigned int num_fences;
int ret = 0; int ret = 0;
if (copy_from_user(&arg, user_data, sizeof(arg))) if (copy_from_user(&arg, user_data, sizeof(arg)))
@@ -411,13 +414,21 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE : usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE :
DMA_RESV_USAGE_READ; DMA_RESV_USAGE_READ;
dma_resv_lock(dmabuf->resv, NULL); num_fences = 0;
dma_fence_unwrap_for_each(f, &iter, fence)
++num_fences;
ret = dma_resv_reserve_fences(dmabuf->resv, 1); if (num_fences > 0) {
if (!ret) dma_resv_lock(dmabuf->resv, NULL);
dma_resv_add_fence(dmabuf->resv, fence, usage);
dma_resv_unlock(dmabuf->resv); ret = dma_resv_reserve_fences(dmabuf->resv, num_fences);
if (!ret) {
dma_fence_unwrap_for_each(f, &iter, fence)
dma_resv_add_fence(dmabuf->resv, f, usage);
}
dma_resv_unlock(dmabuf->resv);
}
dma_fence_put(fence); dma_fence_put(fence);

View File

@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
/* check the name is unique */
mutex_lock(&heap_list_lock);
list_for_each_entry(h, &heap_list, list) {
if (!strcmp(h->name, exp_info->name)) {
mutex_unlock(&heap_list_lock);
pr_err("dma_heap: Already registered heap named %s\n",
exp_info->name);
return ERR_PTR(-EINVAL);
}
}
mutex_unlock(&heap_list_lock);
heap = kzalloc(sizeof(*heap), GFP_KERNEL); heap = kzalloc(sizeof(*heap), GFP_KERNEL);
if (!heap) if (!heap)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
err_ret = ERR_CAST(dev_ret); err_ret = ERR_CAST(dev_ret);
goto err2; goto err2;
} }
/* Add heap to the list */
mutex_lock(&heap_list_lock); mutex_lock(&heap_list_lock);
/* check the name is unique */
list_for_each_entry(h, &heap_list, list) {
if (!strcmp(h->name, exp_info->name)) {
mutex_unlock(&heap_list_lock);
pr_err("dma_heap: Already registered heap named %s\n",
exp_info->name);
err_ret = ERR_PTR(-EINVAL);
goto err3;
}
}
/* Add heap to the list */
list_add(&heap->list, &heap_list); list_add(&heap->list, &heap_list);
mutex_unlock(&heap_list_lock); mutex_unlock(&heap_list_lock);
return heap; return heap;
err3:
device_destroy(dma_heap_class, heap->heap_devt);
err2: err2:
cdev_del(&heap->heap_cdev); cdev_del(&heap->heap_cdev);
err1: err1:

View File

@@ -41,5 +41,6 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
.get_atc_vmid_pasid_mapping_info = .get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base, .set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings .program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings
}; };

View File

@@ -986,6 +986,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
struct amdkfd_process_info *process_info = mem->process_info; struct amdkfd_process_info *process_info = mem->process_info;
struct amdgpu_bo *bo = mem->bo; struct amdgpu_bo *bo = mem->bo;
struct ttm_operation_ctx ctx = { true, false }; struct ttm_operation_ctx ctx = { true, false };
struct hmm_range *range;
int ret = 0; int ret = 0;
mutex_lock(&process_info->lock); mutex_lock(&process_info->lock);
@@ -1015,7 +1016,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
return 0; return 0;
} }
ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, &range);
if (ret) { if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret); pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
goto unregister_out; goto unregister_out;
@@ -1033,7 +1034,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
amdgpu_bo_unreserve(bo); amdgpu_bo_unreserve(bo);
release_out: release_out:
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
unregister_out: unregister_out:
if (ret) if (ret)
amdgpu_mn_unregister(bo); amdgpu_mn_unregister(bo);
@@ -2370,6 +2371,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
/* Go through userptr_inval_list and update any invalid user_pages */ /* Go through userptr_inval_list and update any invalid user_pages */
list_for_each_entry(mem, &process_info->userptr_inval_list, list_for_each_entry(mem, &process_info->userptr_inval_list,
validate_list.head) { validate_list.head) {
struct hmm_range *range;
invalid = atomic_read(&mem->invalid); invalid = atomic_read(&mem->invalid);
if (!invalid) if (!invalid)
/* BO hasn't been invalidated since the last /* BO hasn't been invalidated since the last
@@ -2380,7 +2383,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
bo = mem->bo; bo = mem->bo;
/* Get updated user pages */ /* Get updated user pages */
ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages,
&range);
if (ret) { if (ret) {
pr_debug("Failed %d to get user pages\n", ret); pr_debug("Failed %d to get user pages\n", ret);
@@ -2399,7 +2403,7 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
* FIXME: Cannot ignore the return code, must hold * FIXME: Cannot ignore the return code, must hold
* notifier_lock * notifier_lock
*/ */
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
} }
/* Mark the BO as valid unless it was invalidated /* Mark the BO as valid unless it was invalidated

View File

@@ -209,6 +209,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
list_add_tail(&e->tv.head, &bucket[priority]); list_add_tail(&e->tv.head, &bucket[priority]);
e->user_pages = NULL; e->user_pages = NULL;
e->range = NULL;
} }
/* Connect the sorted buckets in the output list. */ /* Connect the sorted buckets in the output list. */

View File

@@ -26,6 +26,8 @@
#include <drm/ttm/ttm_execbuf_util.h> #include <drm/ttm/ttm_execbuf_util.h>
#include <drm/amdgpu_drm.h> #include <drm/amdgpu_drm.h>
struct hmm_range;
struct amdgpu_device; struct amdgpu_device;
struct amdgpu_bo; struct amdgpu_bo;
struct amdgpu_bo_va; struct amdgpu_bo_va;
@@ -36,6 +38,7 @@ struct amdgpu_bo_list_entry {
struct amdgpu_bo_va *bo_va; struct amdgpu_bo_va *bo_va;
uint32_t priority; uint32_t priority;
struct page **user_pages; struct page **user_pages;
struct hmm_range *range;
bool user_invalidated; bool user_invalidated;
}; };

View File

@@ -328,7 +328,6 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector)
kfree(amdgpu_connector->edid); kfree(amdgpu_connector->edid);
amdgpu_connector->edid = NULL; amdgpu_connector->edid = NULL;
drm_connector_update_edid_property(connector, NULL);
} }
static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)

View File

@@ -913,7 +913,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
goto out_free_user_pages; goto out_free_user_pages;
} }
r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages); r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages, &e->range);
if (r) { if (r) {
kvfree(e->user_pages); kvfree(e->user_pages);
e->user_pages = NULL; e->user_pages = NULL;
@@ -991,9 +991,10 @@ out_free_user_pages:
if (!e->user_pages) if (!e->user_pages)
continue; continue;
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range);
kvfree(e->user_pages); kvfree(e->user_pages);
e->user_pages = NULL; e->user_pages = NULL;
e->range = NULL;
} }
mutex_unlock(&p->bo_list->bo_list_mutex); mutex_unlock(&p->bo_list->bo_list_mutex);
return r; return r;
@@ -1273,7 +1274,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo); struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range);
e->range = NULL;
} }
if (r) { if (r) {
r = -EAGAIN; r = -EAGAIN;

View File

@@ -378,6 +378,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
struct amdgpu_device *adev = drm_to_adev(dev); struct amdgpu_device *adev = drm_to_adev(dev);
struct drm_amdgpu_gem_userptr *args = data; struct drm_amdgpu_gem_userptr *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct hmm_range *range;
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
uint32_t handle; uint32_t handle;
int r; int r;
@@ -413,14 +414,13 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
if (r) if (r)
goto release_object; goto release_object;
if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) { r = amdgpu_mn_register(bo, args->addr);
r = amdgpu_mn_register(bo, args->addr); if (r)
if (r) goto release_object;
goto release_object;
}
if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages,
&range);
if (r) if (r)
goto release_object; goto release_object;
@@ -443,7 +443,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
user_pages_done: user_pages_done:
if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
release_object: release_object:
drm_gem_object_put(gobj); drm_gem_object_put(gobj);

View File

@@ -479,6 +479,12 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
unsigned i; unsigned i;
unsigned vmhub, inv_eng; unsigned vmhub, inv_eng;
if (adev->enable_mes) {
/* reserve engine 5 for firmware */
for (vmhub = 0; vmhub < AMDGPU_MAX_VMHUBS; vmhub++)
vm_inv_engs[vmhub] &= ~(1 << 5);
}
for (i = 0; i < adev->num_rings; ++i) { for (i = 0; i < adev->num_rings; ++i) {
ring = adev->rings[i]; ring = adev->rings[i];
vmhub = ring->funcs->vmhub; vmhub = ring->funcs->vmhub;

View File

@@ -169,7 +169,11 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
amdgpu_sync_free(&job->sync); amdgpu_sync_free(&job->sync);
amdgpu_sync_free(&job->sched_sync); amdgpu_sync_free(&job->sched_sync);
dma_fence_put(&job->hw_fence); /* only put the hw fence if has embedded fence */
if (!job->hw_fence.ops)
kfree(job);
else
dma_fence_put(&job->hw_fence);
} }
void amdgpu_job_set_gang_leader(struct amdgpu_job *job, void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
@@ -254,6 +258,9 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,
DRM_ERROR("Error adding fence (%d)\n", r); DRM_ERROR("Error adding fence (%d)\n", r);
} }
if (!fence && job->gang_submit)
fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit);
while (fence == NULL && vm && !job->vmid) { while (fence == NULL && vm && !job->vmid) {
r = amdgpu_vmid_grab(vm, ring, &job->sync, r = amdgpu_vmid_grab(vm, ring, &job->sync,
&job->base.s_fence->finished, &job->base.s_fence->finished,
@@ -264,9 +271,6 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,
fence = amdgpu_sync_get_fence(&job->sync); fence = amdgpu_sync_get_fence(&job->sync);
} }
if (!fence && job->gang_submit)
fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit);
return fence; return fence;
} }

View File

@@ -172,6 +172,7 @@ void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
{ {
amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr, amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr,
&mem_ctx->shared_buf); &mem_ctx->shared_buf);
mem_ctx->shared_bo = NULL;
} }
static void psp_free_shared_bufs(struct psp_context *psp) static void psp_free_shared_bufs(struct psp_context *psp)
@@ -182,6 +183,7 @@ static void psp_free_shared_bufs(struct psp_context *psp)
/* free TMR memory buffer */ /* free TMR memory buffer */
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr); amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
psp->tmr_bo = NULL;
/* free xgmi shared memory */ /* free xgmi shared memory */
psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context); psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context);
@@ -743,7 +745,7 @@ static int psp_load_toc(struct psp_context *psp,
/* Set up Trusted Memory Region */ /* Set up Trusted Memory Region */
static int psp_tmr_init(struct psp_context *psp) static int psp_tmr_init(struct psp_context *psp)
{ {
int ret; int ret = 0;
int tmr_size; int tmr_size;
void *tmr_buf; void *tmr_buf;
void **pptr; void **pptr;
@@ -770,10 +772,12 @@ static int psp_tmr_init(struct psp_context *psp)
} }
} }
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; if (!psp->tmr_bo) {
ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT, pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
AMDGPU_GEM_DOMAIN_VRAM, ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
&psp->tmr_bo, &psp->tmr_mc_addr, pptr); AMDGPU_GEM_DOMAIN_VRAM,
&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
}
return ret; return ret;
} }
@@ -2732,8 +2736,6 @@ static int psp_suspend(void *handle)
} }
out: out:
psp_free_shared_bufs(psp);
return ret; return ret;
} }

View File

@@ -643,9 +643,6 @@ struct amdgpu_ttm_tt {
struct task_struct *usertask; struct task_struct *usertask;
uint32_t userflags; uint32_t userflags;
bool bound; bool bound;
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
struct hmm_range *range;
#endif
}; };
#define ttm_to_amdgpu_ttm_tt(ptr) container_of(ptr, struct amdgpu_ttm_tt, ttm) #define ttm_to_amdgpu_ttm_tt(ptr) container_of(ptr, struct amdgpu_ttm_tt, ttm)
@@ -658,7 +655,8 @@ struct amdgpu_ttm_tt {
* Calling function must call amdgpu_ttm_tt_userptr_range_done() once and only * Calling function must call amdgpu_ttm_tt_userptr_range_done() once and only
* once afterwards to stop HMM tracking * once afterwards to stop HMM tracking
*/ */
int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages) int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages,
struct hmm_range **range)
{ {
struct ttm_tt *ttm = bo->tbo.ttm; struct ttm_tt *ttm = bo->tbo.ttm;
struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm); struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
@@ -668,16 +666,15 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
bool readonly; bool readonly;
int r = 0; int r = 0;
/* Make sure get_user_pages_done() can cleanup gracefully */
*range = NULL;
mm = bo->notifier.mm; mm = bo->notifier.mm;
if (unlikely(!mm)) { if (unlikely(!mm)) {
DRM_DEBUG_DRIVER("BO is not registered?\n"); DRM_DEBUG_DRIVER("BO is not registered?\n");
return -EFAULT; return -EFAULT;
} }
/* Another get_user_pages is running at the same time?? */
if (WARN_ON(gtt->range))
return -EFAULT;
if (!mmget_not_zero(mm)) /* Happens during process shutdown */ if (!mmget_not_zero(mm)) /* Happens during process shutdown */
return -ESRCH; return -ESRCH;
@@ -695,7 +692,7 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
readonly = amdgpu_ttm_tt_is_readonly(ttm); readonly = amdgpu_ttm_tt_is_readonly(ttm);
r = amdgpu_hmm_range_get_pages(&bo->notifier, mm, pages, start, r = amdgpu_hmm_range_get_pages(&bo->notifier, mm, pages, start,
ttm->num_pages, &gtt->range, readonly, ttm->num_pages, range, readonly,
true, NULL); true, NULL);
out_unlock: out_unlock:
mmap_read_unlock(mm); mmap_read_unlock(mm);
@@ -713,30 +710,24 @@ out_unlock:
* *
* Returns: true if pages are still valid * Returns: true if pages are still valid
*/ */
bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm) bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
struct hmm_range *range)
{ {
struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm); struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
bool r = false;
if (!gtt || !gtt->userptr) if (!gtt || !gtt->userptr || !range)
return false; return false;
DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%x\n", DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%x\n",
gtt->userptr, ttm->num_pages); gtt->userptr, ttm->num_pages);
WARN_ONCE(!gtt->range || !gtt->range->hmm_pfns, WARN_ONCE(!range->hmm_pfns, "No user pages to check\n");
"No user pages to check\n");
if (gtt->range) { /*
/* * FIXME: Must always hold notifier_lock for this, and must
* FIXME: Must always hold notifier_lock for this, and must * not ignore the return code.
* not ignore the return code. */
*/ return !amdgpu_hmm_range_get_pages_done(range);
r = amdgpu_hmm_range_get_pages_done(gtt->range);
gtt->range = NULL;
}
return !r;
} }
#endif #endif
@@ -813,20 +804,6 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev,
/* unmap the pages mapped to the device */ /* unmap the pages mapped to the device */
dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0); dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
sg_free_table(ttm->sg); sg_free_table(ttm->sg);
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
if (gtt->range) {
unsigned long i;
for (i = 0; i < ttm->num_pages; i++) {
if (ttm->pages[i] !=
hmm_pfn_to_page(gtt->range->hmm_pfns[i]))
break;
}
WARN((i == ttm->num_pages), "Missing get_user_page_done\n");
}
#endif
} }
static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev, static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev,

View File

@@ -39,6 +39,8 @@
#define AMDGPU_POISON 0xd0bed0be #define AMDGPU_POISON 0xd0bed0be
struct hmm_range;
struct amdgpu_gtt_mgr { struct amdgpu_gtt_mgr {
struct ttm_resource_manager manager; struct ttm_resource_manager manager;
struct drm_mm mm; struct drm_mm mm;
@@ -149,15 +151,19 @@ void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type); uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages); int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages,
bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm); struct hmm_range **range);
bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
struct hmm_range *range);
#else #else
static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
struct page **pages) struct page **pages,
struct hmm_range **range)
{ {
return -EPERM; return -EPERM;
} }
static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm) static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
struct hmm_range *range)
{ {
return false; return false;
} }

View File

@@ -32,7 +32,6 @@
#define RB_ENABLED (1 << 0) #define RB_ENABLED (1 << 0)
#define RB4_ENABLED (1 << 1) #define RB4_ENABLED (1 << 1)
#define MMSCH_DOORBELL_OFFSET 0x8
#define MMSCH_VF_ENGINE_STATUS__PASS 0x1 #define MMSCH_VF_ENGINE_STATUS__PASS 0x1

View File

@@ -100,7 +100,6 @@ static int vcn_v4_0_sw_init(void *handle)
struct amdgpu_ring *ring; struct amdgpu_ring *ring;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int i, r; int i, r;
int vcn_doorbell_index = 0;
r = amdgpu_vcn_sw_init(adev); r = amdgpu_vcn_sw_init(adev);
if (r) if (r)
@@ -112,12 +111,6 @@ static int vcn_v4_0_sw_init(void *handle)
if (r) if (r)
return r; return r;
if (amdgpu_sriov_vf(adev)) {
vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 - MMSCH_DOORBELL_OFFSET;
/* get DWORD offset */
vcn_doorbell_index = vcn_doorbell_index << 1;
}
for (i = 0; i < adev->vcn.num_vcn_inst; i++) { for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
volatile struct amdgpu_vcn4_fw_shared *fw_shared; volatile struct amdgpu_vcn4_fw_shared *fw_shared;
@@ -135,7 +128,7 @@ static int vcn_v4_0_sw_init(void *handle)
ring = &adev->vcn.inst[i].ring_enc[0]; ring = &adev->vcn.inst[i].ring_enc[0];
ring->use_doorbell = true; ring->use_doorbell = true;
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1; ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + i * (adev->vcn.num_enc_rings + 1) + 1;
else else
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i; ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;

View File

@@ -1372,7 +1372,44 @@ static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
}, },
}, },
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"),
},
},
{} {}
/* TODO: refactor this from a fixed table to a dynamic option */
}; };
static void retrieve_dmi_info(struct amdgpu_display_manager *dm) static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
@@ -6475,7 +6512,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
struct drm_connector_state *new_con_state; struct drm_connector_state *new_con_state;
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
struct dm_connector_state *dm_conn_state; struct dm_connector_state *dm_conn_state;
int i, j; int i, j, ret;
int vcpi, pbn_div, pbn, slot_num = 0; int vcpi, pbn_div, pbn, slot_num = 0;
for_each_new_connector_in_state(state, connector, new_con_state, i) { for_each_new_connector_in_state(state, connector, new_con_state, i) {
@@ -6522,8 +6559,11 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
dm_conn_state->pbn = pbn; dm_conn_state->pbn = pbn;
dm_conn_state->vcpi_slots = slot_num; dm_conn_state->vcpi_slots = slot_num;
drm_dp_mst_atomic_enable_dsc(state, aconnector->port, dm_conn_state->pbn, ret = drm_dp_mst_atomic_enable_dsc(state, aconnector->port,
false); dm_conn_state->pbn, false);
if (ret < 0)
return ret;
continue; continue;
} }
@@ -9537,10 +9577,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (dc_resource_is_dsc_encoding_supported(dc)) { if (dc_resource_is_dsc_encoding_supported(dc)) {
if (!pre_validate_dsc(state, &dm_state, vars)) { ret = pre_validate_dsc(state, &dm_state, vars);
ret = -EINVAL; if (ret != 0)
goto fail; goto fail;
}
} }
#endif #endif
@@ -9635,9 +9674,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
} }
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars)) { ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
if (ret) {
DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n"); DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
ret = -EINVAL;
goto fail; goto fail;
} }

View File

@@ -703,13 +703,13 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
return dsc_config.bits_per_pixel; return dsc_config.bits_per_pixel;
} }
static bool increase_dsc_bpp(struct drm_atomic_state *state, static int increase_dsc_bpp(struct drm_atomic_state *state,
struct drm_dp_mst_topology_state *mst_state, struct drm_dp_mst_topology_state *mst_state,
struct dc_link *dc_link, struct dc_link *dc_link,
struct dsc_mst_fairness_params *params, struct dsc_mst_fairness_params *params,
struct dsc_mst_fairness_vars *vars, struct dsc_mst_fairness_vars *vars,
int count, int count,
int k) int k)
{ {
int i; int i;
bool bpp_increased[MAX_PIPES]; bool bpp_increased[MAX_PIPES];
@@ -719,6 +719,7 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state,
int remaining_to_increase = 0; int remaining_to_increase = 0;
int link_timeslots_used; int link_timeslots_used;
int fair_pbn_alloc; int fair_pbn_alloc;
int ret = 0;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (vars[i + k].dsc_enabled) { if (vars[i + k].dsc_enabled) {
@@ -757,52 +758,60 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state,
if (initial_slack[next_index] > fair_pbn_alloc) { if (initial_slack[next_index] > fair_pbn_alloc) {
vars[next_index].pbn += fair_pbn_alloc; vars[next_index].pbn += fair_pbn_alloc;
if (drm_dp_atomic_find_time_slots(state, ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr, params[next_index].port->mgr,
params[next_index].port, params[next_index].port,
vars[next_index].pbn) < 0) vars[next_index].pbn);
return false; if (ret < 0)
if (!drm_dp_mst_atomic_check(state)) { return ret;
ret = drm_dp_mst_atomic_check(state);
if (ret == 0) {
vars[next_index].bpp_x16 = bpp_x16_from_pbn(params[next_index], vars[next_index].pbn); vars[next_index].bpp_x16 = bpp_x16_from_pbn(params[next_index], vars[next_index].pbn);
} else { } else {
vars[next_index].pbn -= fair_pbn_alloc; vars[next_index].pbn -= fair_pbn_alloc;
if (drm_dp_atomic_find_time_slots(state, ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr, params[next_index].port->mgr,
params[next_index].port, params[next_index].port,
vars[next_index].pbn) < 0) vars[next_index].pbn);
return false; if (ret < 0)
return ret;
} }
} else { } else {
vars[next_index].pbn += initial_slack[next_index]; vars[next_index].pbn += initial_slack[next_index];
if (drm_dp_atomic_find_time_slots(state, ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr, params[next_index].port->mgr,
params[next_index].port, params[next_index].port,
vars[next_index].pbn) < 0) vars[next_index].pbn);
return false; if (ret < 0)
if (!drm_dp_mst_atomic_check(state)) { return ret;
ret = drm_dp_mst_atomic_check(state);
if (ret == 0) {
vars[next_index].bpp_x16 = params[next_index].bw_range.max_target_bpp_x16; vars[next_index].bpp_x16 = params[next_index].bw_range.max_target_bpp_x16;
} else { } else {
vars[next_index].pbn -= initial_slack[next_index]; vars[next_index].pbn -= initial_slack[next_index];
if (drm_dp_atomic_find_time_slots(state, ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr, params[next_index].port->mgr,
params[next_index].port, params[next_index].port,
vars[next_index].pbn) < 0) vars[next_index].pbn);
return false; if (ret < 0)
return ret;
} }
} }
bpp_increased[next_index] = true; bpp_increased[next_index] = true;
remaining_to_increase--; remaining_to_increase--;
} }
return true; return 0;
} }
static bool try_disable_dsc(struct drm_atomic_state *state, static int try_disable_dsc(struct drm_atomic_state *state,
struct dc_link *dc_link, struct dc_link *dc_link,
struct dsc_mst_fairness_params *params, struct dsc_mst_fairness_params *params,
struct dsc_mst_fairness_vars *vars, struct dsc_mst_fairness_vars *vars,
int count, int count,
int k) int k)
{ {
int i; int i;
bool tried[MAX_PIPES]; bool tried[MAX_PIPES];
@@ -810,6 +819,7 @@ static bool try_disable_dsc(struct drm_atomic_state *state,
int max_kbps_increase; int max_kbps_increase;
int next_index; int next_index;
int remaining_to_try = 0; int remaining_to_try = 0;
int ret;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (vars[i + k].dsc_enabled if (vars[i + k].dsc_enabled
@@ -840,49 +850,52 @@ static bool try_disable_dsc(struct drm_atomic_state *state,
break; break;
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps); vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps);
if (drm_dp_atomic_find_time_slots(state, ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr, params[next_index].port->mgr,
params[next_index].port, params[next_index].port,
vars[next_index].pbn) < 0) vars[next_index].pbn);
return false; if (ret < 0)
return ret;
if (!drm_dp_mst_atomic_check(state)) { ret = drm_dp_mst_atomic_check(state);
if (ret == 0) {
vars[next_index].dsc_enabled = false; vars[next_index].dsc_enabled = false;
vars[next_index].bpp_x16 = 0; vars[next_index].bpp_x16 = 0;
} else { } else {
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps); vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps);
if (drm_dp_atomic_find_time_slots(state, ret = drm_dp_atomic_find_time_slots(state,
params[next_index].port->mgr, params[next_index].port->mgr,
params[next_index].port, params[next_index].port,
vars[next_index].pbn) < 0) vars[next_index].pbn);
return false; if (ret < 0)
return ret;
} }
tried[next_index] = true; tried[next_index] = true;
remaining_to_try--; remaining_to_try--;
} }
return true; return 0;
} }
static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
struct dc_state *dc_state, struct dc_state *dc_state,
struct dc_link *dc_link, struct dc_link *dc_link,
struct dsc_mst_fairness_vars *vars, struct dsc_mst_fairness_vars *vars,
struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_mgr *mgr,
int *link_vars_start_index) int *link_vars_start_index)
{ {
struct dc_stream_state *stream; struct dc_stream_state *stream;
struct dsc_mst_fairness_params params[MAX_PIPES]; struct dsc_mst_fairness_params params[MAX_PIPES];
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
struct drm_dp_mst_topology_state *mst_state = drm_atomic_get_mst_topology_state(state, mgr); struct drm_dp_mst_topology_state *mst_state = drm_atomic_get_mst_topology_state(state, mgr);
int count = 0; int count = 0;
int i, k; int i, k, ret;
bool debugfs_overwrite = false; bool debugfs_overwrite = false;
memset(params, 0, sizeof(params)); memset(params, 0, sizeof(params));
if (IS_ERR(mst_state)) if (IS_ERR(mst_state))
return false; return PTR_ERR(mst_state);
mst_state->pbn_div = dm_mst_get_pbn_divider(dc_link); mst_state->pbn_div = dm_mst_get_pbn_divider(dc_link);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -933,7 +946,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
if (count == 0) { if (count == 0) {
ASSERT(0); ASSERT(0);
return true; return 0;
} }
/* k is start index of vars for current phy link used by mst hub */ /* k is start index of vars for current phy link used by mst hub */
@@ -947,13 +960,17 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
vars[i + k].dsc_enabled = false; vars[i + k].dsc_enabled = false;
vars[i + k].bpp_x16 = 0; vars[i + k].bpp_x16 = 0;
if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port,
vars[i + k].pbn) < 0) vars[i + k].pbn);
return false; if (ret < 0)
return ret;
} }
if (!drm_dp_mst_atomic_check(state) && !debugfs_overwrite) { ret = drm_dp_mst_atomic_check(state);
if (ret == 0 && !debugfs_overwrite) {
set_dsc_configs_from_fairness_vars(params, vars, count, k); set_dsc_configs_from_fairness_vars(params, vars, count, k);
return true; return 0;
} else if (ret != -ENOSPC) {
return ret;
} }
/* Try max compression */ /* Try max compression */
@@ -962,31 +979,36 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps);
vars[i + k].dsc_enabled = true; vars[i + k].dsc_enabled = true;
vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
params[i].port, vars[i + k].pbn) < 0) params[i].port, vars[i + k].pbn);
return false; if (ret < 0)
return ret;
} else { } else {
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
vars[i + k].dsc_enabled = false; vars[i + k].dsc_enabled = false;
vars[i + k].bpp_x16 = 0; vars[i + k].bpp_x16 = 0;
if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
params[i].port, vars[i + k].pbn) < 0) params[i].port, vars[i + k].pbn);
return false; if (ret < 0)
return ret;
} }
} }
if (drm_dp_mst_atomic_check(state)) ret = drm_dp_mst_atomic_check(state);
return false; if (ret != 0)
return ret;
/* Optimize degree of compression */ /* Optimize degree of compression */
if (!increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k)) ret = increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k);
return false; if (ret < 0)
return ret;
if (!try_disable_dsc(state, dc_link, params, vars, count, k)) ret = try_disable_dsc(state, dc_link, params, vars, count, k);
return false; if (ret < 0)
return ret;
set_dsc_configs_from_fairness_vars(params, vars, count, k); set_dsc_configs_from_fairness_vars(params, vars, count, k);
return true; return 0;
} }
static bool is_dsc_need_re_compute( static bool is_dsc_need_re_compute(
@@ -1087,15 +1109,17 @@ static bool is_dsc_need_re_compute(
return is_dsc_need_re_compute; return is_dsc_need_re_compute;
} }
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
struct dc_state *dc_state, struct dc_state *dc_state,
struct dsc_mst_fairness_vars *vars) struct dsc_mst_fairness_vars *vars)
{ {
int i, j; int i, j;
struct dc_stream_state *stream; struct dc_stream_state *stream;
bool computed_streams[MAX_PIPES]; bool computed_streams[MAX_PIPES];
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
struct drm_dp_mst_topology_mgr *mst_mgr;
int link_vars_start_index = 0; int link_vars_start_index = 0;
int ret = 0;
for (i = 0; i < dc_state->stream_count; i++) for (i = 0; i < dc_state->stream_count; i++)
computed_streams[i] = false; computed_streams[i] = false;
@@ -1108,7 +1132,7 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
if (!aconnector || !aconnector->dc_sink) if (!aconnector || !aconnector->dc_sink || !aconnector->port)
continue; continue;
if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported) if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported)
@@ -1118,19 +1142,16 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
continue; continue;
if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK)
return false; return -EINVAL;
if (!is_dsc_need_re_compute(state, dc_state, stream->link)) if (!is_dsc_need_re_compute(state, dc_state, stream->link))
continue; continue;
mutex_lock(&aconnector->mst_mgr.lock); mst_mgr = aconnector->port->mgr;
if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, ret = compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, mst_mgr,
&aconnector->mst_mgr, &link_vars_start_index);
&link_vars_start_index)) { if (ret != 0)
mutex_unlock(&aconnector->mst_mgr.lock); return ret;
return false;
}
mutex_unlock(&aconnector->mst_mgr.lock);
for (j = 0; j < dc_state->stream_count; j++) { for (j = 0; j < dc_state->stream_count; j++) {
if (dc_state->streams[j]->link == stream->link) if (dc_state->streams[j]->link == stream->link)
@@ -1143,22 +1164,23 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
if (stream->timing.flags.DSC == 1) if (stream->timing.flags.DSC == 1)
if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK) if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK)
return false; return -EINVAL;
} }
return true; return ret;
} }
static bool static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, struct dc_state *dc_state,
struct dc_state *dc_state, struct dsc_mst_fairness_vars *vars)
struct dsc_mst_fairness_vars *vars)
{ {
int i, j; int i, j;
struct dc_stream_state *stream; struct dc_stream_state *stream;
bool computed_streams[MAX_PIPES]; bool computed_streams[MAX_PIPES];
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
struct drm_dp_mst_topology_mgr *mst_mgr;
int link_vars_start_index = 0; int link_vars_start_index = 0;
int ret = 0;
for (i = 0; i < dc_state->stream_count; i++) for (i = 0; i < dc_state->stream_count; i++)
computed_streams[i] = false; computed_streams[i] = false;
@@ -1171,7 +1193,7 @@ static bool
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
if (!aconnector || !aconnector->dc_sink) if (!aconnector || !aconnector->dc_sink || !aconnector->port)
continue; continue;
if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported) if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported)
@@ -1183,14 +1205,11 @@ static bool
if (!is_dsc_need_re_compute(state, dc_state, stream->link)) if (!is_dsc_need_re_compute(state, dc_state, stream->link))
continue; continue;
mutex_lock(&aconnector->mst_mgr.lock); mst_mgr = aconnector->port->mgr;
if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, ret = compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, mst_mgr,
&aconnector->mst_mgr, &link_vars_start_index);
&link_vars_start_index)) { if (ret != 0)
mutex_unlock(&aconnector->mst_mgr.lock); return ret;
return false;
}
mutex_unlock(&aconnector->mst_mgr.lock);
for (j = 0; j < dc_state->stream_count; j++) { for (j = 0; j < dc_state->stream_count; j++) {
if (dc_state->streams[j]->link == stream->link) if (dc_state->streams[j]->link == stream->link)
@@ -1198,7 +1217,7 @@ static bool
} }
} }
return true; return ret;
} }
static int find_crtc_index_in_state_by_stream(struct drm_atomic_state *state, static int find_crtc_index_in_state_by_stream(struct drm_atomic_state *state,
@@ -1253,9 +1272,9 @@ static bool is_dsc_precompute_needed(struct drm_atomic_state *state)
return ret; return ret;
} }
bool pre_validate_dsc(struct drm_atomic_state *state, int pre_validate_dsc(struct drm_atomic_state *state,
struct dm_atomic_state **dm_state_ptr, struct dm_atomic_state **dm_state_ptr,
struct dsc_mst_fairness_vars *vars) struct dsc_mst_fairness_vars *vars)
{ {
int i; int i;
struct dm_atomic_state *dm_state; struct dm_atomic_state *dm_state;
@@ -1264,11 +1283,12 @@ bool pre_validate_dsc(struct drm_atomic_state *state,
if (!is_dsc_precompute_needed(state)) { if (!is_dsc_precompute_needed(state)) {
DRM_INFO_ONCE("DSC precompute is not needed.\n"); DRM_INFO_ONCE("DSC precompute is not needed.\n");
return true; return 0;
} }
if (dm_atomic_get_state(state, dm_state_ptr)) { ret = dm_atomic_get_state(state, dm_state_ptr);
if (ret != 0) {
DRM_INFO_ONCE("dm_atomic_get_state() failed\n"); DRM_INFO_ONCE("dm_atomic_get_state() failed\n");
return false; return ret;
} }
dm_state = *dm_state_ptr; dm_state = *dm_state_ptr;
@@ -1280,7 +1300,7 @@ bool pre_validate_dsc(struct drm_atomic_state *state,
local_dc_state = kmemdup(dm_state->context, sizeof(struct dc_state), GFP_KERNEL); local_dc_state = kmemdup(dm_state->context, sizeof(struct dc_state), GFP_KERNEL);
if (!local_dc_state) if (!local_dc_state)
return false; return -ENOMEM;
for (i = 0; i < local_dc_state->stream_count; i++) { for (i = 0; i < local_dc_state->stream_count; i++) {
struct dc_stream_state *stream = dm_state->context->streams[i]; struct dc_stream_state *stream = dm_state->context->streams[i];
@@ -1316,9 +1336,9 @@ bool pre_validate_dsc(struct drm_atomic_state *state,
if (ret != 0) if (ret != 0)
goto clean_exit; goto clean_exit;
if (!pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars)) { ret = pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars);
if (ret != 0) {
DRM_INFO_ONCE("pre_compute_mst_dsc_configs_for_state() failed\n"); DRM_INFO_ONCE("pre_compute_mst_dsc_configs_for_state() failed\n");
ret = -EINVAL;
goto clean_exit; goto clean_exit;
} }
@@ -1349,7 +1369,7 @@ clean_exit:
kfree(local_dc_state); kfree(local_dc_state);
return (ret == 0); return ret;
} }
static unsigned int kbps_from_pbn(unsigned int pbn) static unsigned int kbps_from_pbn(unsigned int pbn)
@@ -1392,6 +1412,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0; unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
unsigned int max_compressed_bw_in_kbps = 0; unsigned int max_compressed_bw_in_kbps = 0;
struct dc_dsc_bw_range bw_range = {0}; struct dc_dsc_bw_range bw_range = {0};
struct drm_dp_mst_topology_mgr *mst_mgr;
/* /*
* check if the mode could be supported if DSC pass-through is supported * check if the mode could be supported if DSC pass-through is supported
@@ -1400,7 +1421,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
*/ */
if (is_dsc_common_config_possible(stream, &bw_range) && if (is_dsc_common_config_possible(stream, &bw_range) &&
aconnector->port->passthrough_aux) { aconnector->port->passthrough_aux) {
mutex_lock(&aconnector->mst_mgr.lock); mst_mgr = aconnector->port->mgr;
mutex_lock(&mst_mgr->lock);
cur_link_settings = stream->link->verified_link_cap; cur_link_settings = stream->link->verified_link_cap;
@@ -1413,7 +1435,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps, end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps,
down_link_bw_in_kbps); down_link_bw_in_kbps);
mutex_unlock(&aconnector->mst_mgr.lock); mutex_unlock(&mst_mgr->lock);
/* /*
* use the maximum dsc compression bandwidth as the required * use the maximum dsc compression bandwidth as the required

View File

@@ -53,15 +53,15 @@ struct dsc_mst_fairness_vars {
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
}; };
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
struct dc_state *dc_state, struct dc_state *dc_state,
struct dsc_mst_fairness_vars *vars); struct dsc_mst_fairness_vars *vars);
bool needs_dsc_aux_workaround(struct dc_link *link); bool needs_dsc_aux_workaround(struct dc_link *link);
bool pre_validate_dsc(struct drm_atomic_state *state, int pre_validate_dsc(struct drm_atomic_state *state,
struct dm_atomic_state **dm_state_ptr, struct dm_atomic_state **dm_state_ptr,
struct dsc_mst_fairness_vars *vars); struct dsc_mst_fairness_vars *vars);
enum dc_status dm_dp_mst_is_port_support_mode( enum dc_status dm_dp_mst_is_port_support_mode(
struct amdgpu_dm_connector *aconnector, struct amdgpu_dm_connector *aconnector,

View File

@@ -123,9 +123,10 @@ static int dcn314_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr,
uint32_t result; uint32_t result;
result = dcn314_smu_wait_for_response(clk_mgr, 10, 200000); result = dcn314_smu_wait_for_response(clk_mgr, 10, 200000);
ASSERT(result == VBIOSSMC_Result_OK);
smu_print("SMU response after wait: %d\n", result); if (result != VBIOSSMC_Result_OK)
smu_print("SMU Response was not OK. SMU response after wait received is: %d\n",
result);
if (result == VBIOSSMC_Status_BUSY) if (result == VBIOSSMC_Status_BUSY)
return -1; return -1;
@@ -216,6 +217,12 @@ int dcn314_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int request
VBIOSSMC_MSG_SetHardMinDcfclkByFreq, VBIOSSMC_MSG_SetHardMinDcfclkByFreq,
khz_to_mhz_ceil(requested_dcfclk_khz)); khz_to_mhz_ceil(requested_dcfclk_khz));
#ifdef DBG
smu_print("actual_dcfclk_set_mhz %d is set to : %d\n",
actual_dcfclk_set_mhz,
actual_dcfclk_set_mhz * 1000);
#endif
return actual_dcfclk_set_mhz * 1000; return actual_dcfclk_set_mhz * 1000;
} }

View File

@@ -359,7 +359,8 @@ static const struct dce_audio_registers audio_regs[] = {
audio_regs(2), audio_regs(2),
audio_regs(3), audio_regs(3),
audio_regs(4), audio_regs(4),
audio_regs(5) audio_regs(5),
audio_regs(6),
}; };
#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\

View File

@@ -436,34 +436,48 @@ void dpp1_set_cursor_position(
uint32_t height) uint32_t height)
{ {
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; int x_pos = pos->x - param->viewport.x;
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; int y_pos = pos->y - param->viewport.y;
int x_hotspot = pos->x_hotspot;
int y_hotspot = pos->y_hotspot;
int src_x_offset = x_pos - pos->x_hotspot;
int src_y_offset = y_pos - pos->y_hotspot;
int cursor_height = (int)height;
int cursor_width = (int)width;
uint32_t cur_en = pos->enable ? 1 : 0; uint32_t cur_en = pos->enable ? 1 : 0;
// Cursor width/height and hotspots need to be rotated for offset calculation // Transform cursor width / height and hotspots for offset calculations
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
swap(width, height); swap(cursor_height, cursor_width);
swap(x_hotspot, y_hotspot);
if (param->rotation == ROTATION_ANGLE_90) { if (param->rotation == ROTATION_ANGLE_90) {
src_x_offset = pos->x - pos->y_hotspot - param->viewport.x; // hotspot = (-y, x)
src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; src_x_offset = x_pos - (cursor_width - x_hotspot);
src_y_offset = y_pos - y_hotspot;
} else if (param->rotation == ROTATION_ANGLE_270) {
// hotspot = (y, -x)
src_x_offset = x_pos - x_hotspot;
src_y_offset = y_pos - (cursor_height - y_hotspot);
} }
} else if (param->rotation == ROTATION_ANGLE_180) { } else if (param->rotation == ROTATION_ANGLE_180) {
// hotspot = (-x, -y)
if (!param->mirror) if (!param->mirror)
src_x_offset = pos->x - param->viewport.x; src_x_offset = x_pos - (cursor_width - x_hotspot);
src_y_offset = pos->y - param->viewport.y; src_y_offset = y_pos - (cursor_height - y_hotspot);
} }
if (src_x_offset >= (int)param->viewport.width) if (src_x_offset >= (int)param->viewport.width)
cur_en = 0; /* not visible beyond right edge*/ cur_en = 0; /* not visible beyond right edge*/
if (src_x_offset + (int)width <= 0) if (src_x_offset + cursor_width <= 0)
cur_en = 0; /* not visible beyond left edge*/ cur_en = 0; /* not visible beyond left edge*/
if (src_y_offset >= (int)param->viewport.height) if (src_y_offset >= (int)param->viewport.height)
cur_en = 0; /* not visible beyond bottom edge*/ cur_en = 0; /* not visible beyond bottom edge*/
if (src_y_offset + (int)height <= 0) if (src_y_offset + cursor_height <= 0)
cur_en = 0; /* not visible beyond top edge*/ cur_en = 0; /* not visible beyond top edge*/
REG_UPDATE(CURSOR0_CONTROL, REG_UPDATE(CURSOR0_CONTROL,

View File

@@ -1179,10 +1179,12 @@ void hubp1_cursor_set_position(
const struct dc_cursor_mi_param *param) const struct dc_cursor_mi_param *param)
{ {
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; int x_pos = pos->x - param->viewport.x;
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; int y_pos = pos->y - param->viewport.y;
int x_hotspot = pos->x_hotspot; int x_hotspot = pos->x_hotspot;
int y_hotspot = pos->y_hotspot; int y_hotspot = pos->y_hotspot;
int src_x_offset = x_pos - pos->x_hotspot;
int src_y_offset = y_pos - pos->y_hotspot;
int cursor_height = (int)hubp->curs_attr.height; int cursor_height = (int)hubp->curs_attr.height;
int cursor_width = (int)hubp->curs_attr.width; int cursor_width = (int)hubp->curs_attr.width;
uint32_t dst_x_offset; uint32_t dst_x_offset;
@@ -1200,18 +1202,26 @@ void hubp1_cursor_set_position(
if (hubp->curs_attr.address.quad_part == 0) if (hubp->curs_attr.address.quad_part == 0)
return; return;
// Rotated cursor width/height and hotspots tweaks for offset calculation // Transform cursor width / height and hotspots for offset calculations
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
swap(cursor_height, cursor_width); swap(cursor_height, cursor_width);
swap(x_hotspot, y_hotspot);
if (param->rotation == ROTATION_ANGLE_90) { if (param->rotation == ROTATION_ANGLE_90) {
src_x_offset = pos->x - pos->y_hotspot - param->viewport.x; // hotspot = (-y, x)
src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; src_x_offset = x_pos - (cursor_width - x_hotspot);
src_y_offset = y_pos - y_hotspot;
} else if (param->rotation == ROTATION_ANGLE_270) {
// hotspot = (y, -x)
src_x_offset = x_pos - x_hotspot;
src_y_offset = y_pos - (cursor_height - y_hotspot);
} }
} else if (param->rotation == ROTATION_ANGLE_180) { } else if (param->rotation == ROTATION_ANGLE_180) {
// hotspot = (-x, -y)
if (!param->mirror) if (!param->mirror)
src_x_offset = pos->x - param->viewport.x; src_x_offset = x_pos - (cursor_width - x_hotspot);
src_y_offset = pos->y - param->viewport.y; src_y_offset = y_pos - (cursor_height - y_hotspot);
} }
dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
@@ -1248,8 +1258,8 @@ void hubp1_cursor_set_position(
CURSOR_Y_POSITION, pos->y); CURSOR_Y_POSITION, pos->y);
REG_SET_2(CURSOR_HOT_SPOT, 0, REG_SET_2(CURSOR_HOT_SPOT, 0,
CURSOR_HOT_SPOT_X, x_hotspot, CURSOR_HOT_SPOT_X, pos->x_hotspot,
CURSOR_HOT_SPOT_Y, y_hotspot); CURSOR_HOT_SPOT_Y, pos->y_hotspot);
REG_SET(CURSOR_DST_OFFSET, 0, REG_SET(CURSOR_DST_OFFSET, 0,
CURSOR_DST_X_OFFSET, dst_x_offset); CURSOR_DST_X_OFFSET, dst_x_offset);

View File

@@ -973,10 +973,12 @@ void hubp2_cursor_set_position(
const struct dc_cursor_mi_param *param) const struct dc_cursor_mi_param *param)
{ {
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; int x_pos = pos->x - param->viewport.x;
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; int y_pos = pos->y - param->viewport.y;
int x_hotspot = pos->x_hotspot; int x_hotspot = pos->x_hotspot;
int y_hotspot = pos->y_hotspot; int y_hotspot = pos->y_hotspot;
int src_x_offset = x_pos - pos->x_hotspot;
int src_y_offset = y_pos - pos->y_hotspot;
int cursor_height = (int)hubp->curs_attr.height; int cursor_height = (int)hubp->curs_attr.height;
int cursor_width = (int)hubp->curs_attr.width; int cursor_width = (int)hubp->curs_attr.width;
uint32_t dst_x_offset; uint32_t dst_x_offset;
@@ -994,18 +996,26 @@ void hubp2_cursor_set_position(
if (hubp->curs_attr.address.quad_part == 0) if (hubp->curs_attr.address.quad_part == 0)
return; return;
// Rotated cursor width/height and hotspots tweaks for offset calculation // Transform cursor width / height and hotspots for offset calculations
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
swap(cursor_height, cursor_width); swap(cursor_height, cursor_width);
swap(x_hotspot, y_hotspot);
if (param->rotation == ROTATION_ANGLE_90) { if (param->rotation == ROTATION_ANGLE_90) {
src_x_offset = pos->x - pos->y_hotspot - param->viewport.x; // hotspot = (-y, x)
src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; src_x_offset = x_pos - (cursor_width - x_hotspot);
src_y_offset = y_pos - y_hotspot;
} else if (param->rotation == ROTATION_ANGLE_270) {
// hotspot = (y, -x)
src_x_offset = x_pos - x_hotspot;
src_y_offset = y_pos - (cursor_height - y_hotspot);
} }
} else if (param->rotation == ROTATION_ANGLE_180) { } else if (param->rotation == ROTATION_ANGLE_180) {
// hotspot = (-x, -y)
if (!param->mirror) if (!param->mirror)
src_x_offset = pos->x - param->viewport.x; src_x_offset = x_pos - (cursor_width - x_hotspot);
src_y_offset = pos->y - param->viewport.y; src_y_offset = y_pos - (cursor_height - y_hotspot);
} }
dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
@@ -1042,8 +1052,8 @@ void hubp2_cursor_set_position(
CURSOR_Y_POSITION, pos->y); CURSOR_Y_POSITION, pos->y);
REG_SET_2(CURSOR_HOT_SPOT, 0, REG_SET_2(CURSOR_HOT_SPOT, 0,
CURSOR_HOT_SPOT_X, x_hotspot, CURSOR_HOT_SPOT_X, pos->x_hotspot,
CURSOR_HOT_SPOT_Y, y_hotspot); CURSOR_HOT_SPOT_Y, pos->y_hotspot);
REG_SET(CURSOR_DST_OFFSET, 0, REG_SET(CURSOR_DST_OFFSET, 0,
CURSOR_DST_X_OFFSET, dst_x_offset); CURSOR_DST_X_OFFSET, dst_x_offset);
@@ -1052,8 +1062,8 @@ void hubp2_cursor_set_position(
hubp->pos.cur_ctl.bits.cur_enable = cur_en; hubp->pos.cur_ctl.bits.cur_enable = cur_en;
hubp->pos.position.bits.x_pos = pos->x; hubp->pos.position.bits.x_pos = pos->x;
hubp->pos.position.bits.y_pos = pos->y; hubp->pos.position.bits.y_pos = pos->y;
hubp->pos.hot_spot.bits.x_hot = x_hotspot; hubp->pos.hot_spot.bits.x_hot = pos->x_hotspot;
hubp->pos.hot_spot.bits.y_hot = y_hotspot; hubp->pos.hot_spot.bits.y_hot = pos->y_hotspot;
hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset; hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset;
/* Cursor Rectangle Cache /* Cursor Rectangle Cache
* Cursor bitmaps have different hotspot values * Cursor bitmaps have different hotspot values

View File

@@ -96,6 +96,13 @@ static void dccg314_set_pixel_rate_div(
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA; enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
// Don't program 0xF into the register field. Not valid since
// K1 / K2 field is only 1 / 2 bits wide
if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
BREAK_TO_DEBUGGER();
return;
}
dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2); dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 && k2 == cur_k2)) if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 && k2 == cur_k2))
return; return;

View File

@@ -348,10 +348,8 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
odm_combine_factor = get_odm_config(pipe_ctx, NULL); odm_combine_factor = get_odm_config(pipe_ctx, NULL);
if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
return odm_combine_factor;
if (is_dp_128b_132b_signal(pipe_ctx)) { if (is_dp_128b_132b_signal(pipe_ctx)) {
*k1_div = PIXEL_RATE_DIV_BY_1;
*k2_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_1;
} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) { } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
*k1_div = PIXEL_RATE_DIV_BY_1; *k1_div = PIXEL_RATE_DIV_BY_1;
@@ -359,7 +357,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
*k2_div = PIXEL_RATE_DIV_BY_2; *k2_div = PIXEL_RATE_DIV_BY_2;
else else
*k2_div = PIXEL_RATE_DIV_BY_4; *k2_div = PIXEL_RATE_DIV_BY_4;
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { } else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
if (two_pix_per_container) { if (two_pix_per_container) {
*k1_div = PIXEL_RATE_DIV_BY_1; *k1_div = PIXEL_RATE_DIV_BY_1;
*k2_div = PIXEL_RATE_DIV_BY_2; *k2_div = PIXEL_RATE_DIV_BY_2;

View File

@@ -96,8 +96,10 @@ static void dccg32_set_pixel_rate_div(
// Don't program 0xF into the register field. Not valid since // Don't program 0xF into the register field. Not valid since
// K1 / K2 field is only 1 / 2 bits wide // K1 / K2 field is only 1 / 2 bits wide
if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
BREAK_TO_DEBUGGER();
return; return;
}
dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2); dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
if (k1 == cur_k1 && k2 == cur_k2) if (k1 == cur_k1 && k2 == cur_k2)

View File

@@ -1171,10 +1171,8 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
odm_combine_factor = get_odm_config(pipe_ctx, NULL); odm_combine_factor = get_odm_config(pipe_ctx, NULL);
if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
return odm_combine_factor;
if (is_dp_128b_132b_signal(pipe_ctx)) { if (is_dp_128b_132b_signal(pipe_ctx)) {
*k1_div = PIXEL_RATE_DIV_BY_1;
*k2_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_1;
} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) { } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
*k1_div = PIXEL_RATE_DIV_BY_1; *k1_div = PIXEL_RATE_DIV_BY_1;

View File

@@ -111,7 +111,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
mall_alloc_width_blk_aligned = full_vp_width_blk_aligned; mall_alloc_width_blk_aligned = full_vp_width_blk_aligned;
/* mall_alloc_height_blk_aligned_l/c = CEILING(sub_vp_height_l/c - 1, blk_height_l/c) + blk_height_l/c */ /* mall_alloc_height_blk_aligned_l/c = CEILING(sub_vp_height_l/c - 1, blk_height_l/c) + blk_height_l/c */
mall_alloc_height_blk_aligned = (pipe->stream->timing.v_addressable - 1 + mblk_height - 1) / mall_alloc_height_blk_aligned = (pipe->plane_res.scl_data.viewport.height - 1 + mblk_height - 1) /
mblk_height * mblk_height + mblk_height; mblk_height * mblk_height + mblk_height;
/* full_mblk_width_ub_l/c = mall_alloc_width_blk_aligned_l/c; /* full_mblk_width_ub_l/c = mall_alloc_width_blk_aligned_l/c;

View File

@@ -157,7 +157,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
.dispclk_dppclk_vco_speed_mhz = 4300.0, .dispclk_dppclk_vco_speed_mhz = 4300.0,
.do_urgent_latency_adjustment = true, .do_urgent_latency_adjustment = true,
.urgent_latency_adjustment_fabric_clock_component_us = 1.0, .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
}; };
void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr) void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
@@ -211,7 +211,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
/* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */ /* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */
if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) { if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) {
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true;
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 38; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50;
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us;
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
@@ -221,7 +221,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16; clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16;
clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38; clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50;
clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16; clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16;
clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9; clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;
clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16; clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16;
@@ -1910,7 +1910,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] == if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] ==
dm_dram_clock_change_unsupported) { dm_dram_clock_change_unsupported) {
int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1; int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1;
min_dram_speed_mts = min_dram_speed_mts =
dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16; dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;

View File

@@ -126,9 +126,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
.sr_enter_plus_exit_z8_time_us = 320, .sr_enter_plus_exit_z8_time_us = 320,
.writeback_latency_us = 12.0, .writeback_latency_us = 12.0,
.round_trip_ping_latency_dcfclk_cycles = 263, .round_trip_ping_latency_dcfclk_cycles = 263,
.urgent_latency_pixel_data_only_us = 9.35, .urgent_latency_pixel_data_only_us = 4,
.urgent_latency_pixel_mixed_with_vm_data_us = 9.35, .urgent_latency_pixel_mixed_with_vm_data_us = 4,
.urgent_latency_vm_data_only_us = 9.35, .urgent_latency_vm_data_only_us = 4,
.fclk_change_latency_us = 20, .fclk_change_latency_us = 20,
.usr_retraining_latency_us = 2, .usr_retraining_latency_us = 2,
.smn_latency_us = 2, .smn_latency_us = 2,
@@ -156,7 +156,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
.dispclk_dppclk_vco_speed_mhz = 4300.0, .dispclk_dppclk_vco_speed_mhz = 4300.0,
.do_urgent_latency_adjustment = true, .do_urgent_latency_adjustment = true,
.urgent_latency_adjustment_fabric_clock_component_us = 1.0, .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
}; };
static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry) static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry)

View File

@@ -25,10 +25,10 @@
// *** IMPORTANT *** // *** IMPORTANT ***
// PMFW TEAM: Always increment the interface version on any change to this file // PMFW TEAM: Always increment the interface version on any change to this file
#define SMU13_DRIVER_IF_VERSION 0x2C #define SMU13_DRIVER_IF_VERSION 0x35
//Increment this version if SkuTable_t or BoardTable_t change //Increment this version if SkuTable_t or BoardTable_t change
#define PPTABLE_VERSION 0x20 #define PPTABLE_VERSION 0x27
#define NUM_GFXCLK_DPM_LEVELS 16 #define NUM_GFXCLK_DPM_LEVELS 16
#define NUM_SOCCLK_DPM_LEVELS 8 #define NUM_SOCCLK_DPM_LEVELS 8
@@ -96,7 +96,7 @@
#define FEATURE_MEM_TEMP_READ_BIT 47 #define FEATURE_MEM_TEMP_READ_BIT 47
#define FEATURE_ATHUB_MMHUB_PG_BIT 48 #define FEATURE_ATHUB_MMHUB_PG_BIT 48
#define FEATURE_SOC_PCC_BIT 49 #define FEATURE_SOC_PCC_BIT 49
#define FEATURE_SPARE_50_BIT 50 #define FEATURE_EDC_PWRBRK_BIT 50
#define FEATURE_SPARE_51_BIT 51 #define FEATURE_SPARE_51_BIT 51
#define FEATURE_SPARE_52_BIT 52 #define FEATURE_SPARE_52_BIT 52
#define FEATURE_SPARE_53_BIT 53 #define FEATURE_SPARE_53_BIT 53
@@ -282,15 +282,15 @@ typedef enum {
} I2cControllerPort_e; } I2cControllerPort_e;
typedef enum { typedef enum {
I2C_CONTROLLER_NAME_VR_GFX = 0, I2C_CONTROLLER_NAME_VR_GFX = 0,
I2C_CONTROLLER_NAME_VR_SOC, I2C_CONTROLLER_NAME_VR_SOC,
I2C_CONTROLLER_NAME_VR_VMEMP, I2C_CONTROLLER_NAME_VR_VMEMP,
I2C_CONTROLLER_NAME_VR_VDDIO, I2C_CONTROLLER_NAME_VR_VDDIO,
I2C_CONTROLLER_NAME_LIQUID0, I2C_CONTROLLER_NAME_LIQUID0,
I2C_CONTROLLER_NAME_LIQUID1, I2C_CONTROLLER_NAME_LIQUID1,
I2C_CONTROLLER_NAME_PLX, I2C_CONTROLLER_NAME_PLX,
I2C_CONTROLLER_NAME_OTHER, I2C_CONTROLLER_NAME_FAN_INTAKE,
I2C_CONTROLLER_NAME_COUNT, I2C_CONTROLLER_NAME_COUNT,
} I2cControllerName_e; } I2cControllerName_e;
typedef enum { typedef enum {
@@ -302,6 +302,7 @@ typedef enum {
I2C_CONTROLLER_THROTTLER_LIQUID0, I2C_CONTROLLER_THROTTLER_LIQUID0,
I2C_CONTROLLER_THROTTLER_LIQUID1, I2C_CONTROLLER_THROTTLER_LIQUID1,
I2C_CONTROLLER_THROTTLER_PLX, I2C_CONTROLLER_THROTTLER_PLX,
I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
I2C_CONTROLLER_THROTTLER_INA3221, I2C_CONTROLLER_THROTTLER_INA3221,
I2C_CONTROLLER_THROTTLER_COUNT, I2C_CONTROLLER_THROTTLER_COUNT,
} I2cControllerThrottler_e; } I2cControllerThrottler_e;
@@ -309,8 +310,9 @@ typedef enum {
typedef enum { typedef enum {
I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5, I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
I2C_CONTROLLER_PROTOCOL_VR_IR35217, I2C_CONTROLLER_PROTOCOL_VR_IR35217,
I2C_CONTROLLER_PROTOCOL_TMP_TMP102A, I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
I2C_CONTROLLER_PROTOCOL_INA3221, I2C_CONTROLLER_PROTOCOL_INA3221,
I2C_CONTROLLER_PROTOCOL_TMP_MAX6604,
I2C_CONTROLLER_PROTOCOL_COUNT, I2C_CONTROLLER_PROTOCOL_COUNT,
} I2cControllerProtocol_e; } I2cControllerProtocol_e;
@@ -690,6 +692,9 @@ typedef struct {
#define PP_OD_FEATURE_UCLK_BIT 8 #define PP_OD_FEATURE_UCLK_BIT 8
#define PP_OD_FEATURE_ZERO_FAN_BIT 9 #define PP_OD_FEATURE_ZERO_FAN_BIT 9
#define PP_OD_FEATURE_TEMPERATURE_BIT 10 #define PP_OD_FEATURE_TEMPERATURE_BIT 10
#define PP_OD_FEATURE_POWER_FEATURE_CTRL_BIT 11
#define PP_OD_FEATURE_ASIC_TDC_BIT 12
#define PP_OD_FEATURE_COUNT 13
typedef enum { typedef enum {
PP_OD_POWER_FEATURE_ALWAYS_ENABLED, PP_OD_POWER_FEATURE_ALWAYS_ENABLED,
@@ -697,6 +702,11 @@ typedef enum {
PP_OD_POWER_FEATURE_ALWAYS_DISABLED, PP_OD_POWER_FEATURE_ALWAYS_DISABLED,
} PP_OD_POWER_FEATURE_e; } PP_OD_POWER_FEATURE_e;
typedef enum {
FAN_MODE_AUTO = 0,
FAN_MODE_MANUAL_LINEAR,
} FanMode_e;
typedef struct { typedef struct {
uint32_t FeatureCtrlMask; uint32_t FeatureCtrlMask;
@@ -708,8 +718,8 @@ typedef struct {
uint8_t RuntimePwrSavingFeaturesCtrl; uint8_t RuntimePwrSavingFeaturesCtrl;
//Frequency changes //Frequency changes
int16_t GfxclkFmin; // MHz int16_t GfxclkFmin; // MHz
int16_t GfxclkFmax; // MHz int16_t GfxclkFmax; // MHz
uint16_t UclkFmin; // MHz uint16_t UclkFmin; // MHz
uint16_t UclkFmax; // MHz uint16_t UclkFmax; // MHz
@@ -730,7 +740,12 @@ typedef struct {
uint8_t MaxOpTemp; uint8_t MaxOpTemp;
uint8_t Padding[4]; uint8_t Padding[4];
uint32_t Spare[12]; uint16_t GfxVoltageFullCtrlMode;
uint16_t GfxclkFullCtrlMode;
uint16_t UclkFullCtrlMode;
int16_t AsicTdc;
uint32_t Spare[10];
uint32_t MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround uint32_t MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround
} OverDriveTable_t; } OverDriveTable_t;
@@ -748,8 +763,8 @@ typedef struct {
uint8_t IdlePwrSavingFeaturesCtrl; uint8_t IdlePwrSavingFeaturesCtrl;
uint8_t RuntimePwrSavingFeaturesCtrl; uint8_t RuntimePwrSavingFeaturesCtrl;
uint16_t GfxclkFmin; // MHz int16_t GfxclkFmin; // MHz
uint16_t GfxclkFmax; // MHz int16_t GfxclkFmax; // MHz
uint16_t UclkFmin; // MHz uint16_t UclkFmin; // MHz
uint16_t UclkFmax; // MHz uint16_t UclkFmax; // MHz
@@ -769,7 +784,12 @@ typedef struct {
uint8_t MaxOpTemp; uint8_t MaxOpTemp;
uint8_t Padding[4]; uint8_t Padding[4];
uint32_t Spare[12]; uint16_t GfxVoltageFullCtrlMode;
uint16_t GfxclkFullCtrlMode;
uint16_t UclkFullCtrlMode;
int16_t AsicTdc;
uint32_t Spare[10];
} OverDriveLimits_t; } OverDriveLimits_t;
@@ -903,7 +923,8 @@ typedef struct {
uint16_t FanStartTempMin; uint16_t FanStartTempMin;
uint16_t FanStartTempMax; uint16_t FanStartTempMax;
uint32_t Spare[12]; uint16_t PowerMinPpt0[POWER_SOURCE_COUNT];
uint32_t Spare[11];
} MsgLimits_t; } MsgLimits_t;
@@ -1086,11 +1107,13 @@ typedef struct {
uint32_t GfxoffSpare[15]; uint32_t GfxoffSpare[15];
// GFX GPO // GFX GPO
float DfllBtcMasterScalerM; uint32_t DfllBtcMasterScalerM;
int32_t DfllBtcMasterScalerB; int32_t DfllBtcMasterScalerB;
float DfllBtcSlaveScalerM; uint32_t DfllBtcSlaveScalerM;
int32_t DfllBtcSlaveScalerB; int32_t DfllBtcSlaveScalerB;
uint32_t GfxGpoSpare[12]; uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
uint32_t GfxGpoSpare[10];
// GFX DCS // GFX DCS
@@ -1106,7 +1129,10 @@ typedef struct {
uint16_t DcsTimeout; //This is the amount of time SMU FW waits for RLC to put GFX into GFXOFF before reverting to the fallback mechanism of throttling GFXCLK to Fmin. uint16_t DcsTimeout; //This is the amount of time SMU FW waits for RLC to put GFX into GFXOFF before reverting to the fallback mechanism of throttling GFXCLK to Fmin.
uint32_t DcsSpare[16]; uint32_t DcsSpare[14];
// UCLK section
uint16_t ShadowFreqTableUclk[NUM_UCLK_DPM_LEVELS]; // In MHz
// UCLK section // UCLK section
uint8_t UseStrobeModeOptimizations; //Set to indicate that FW should use strobe mode optimizations uint8_t UseStrobeModeOptimizations; //Set to indicate that FW should use strobe mode optimizations
@@ -1163,13 +1189,14 @@ typedef struct {
uint16_t IntakeTempHighIntakeAcousticLimit; uint16_t IntakeTempHighIntakeAcousticLimit;
uint16_t IntakeTempAcouticLimitReleaseRate; uint16_t IntakeTempAcouticLimitReleaseRate;
uint16_t FanStalledTempLimitOffset; int16_t FanAbnormalTempLimitOffset;
uint16_t FanStalledTriggerRpm; uint16_t FanStalledTriggerRpm;
uint16_t FanAbnormalTriggerRpm; uint16_t FanAbnormalTriggerRpmCoeff;
uint16_t FanPadding; uint16_t FanAbnormalDetectionEnable;
uint32_t FanSpare[14];
uint8_t FanIntakeSensorSupport;
uint8_t FanIntakePadding[3];
uint32_t FanSpare[13];
// SECTION: VDD_GFX AVFS // SECTION: VDD_GFX AVFS
uint8_t OverrideGfxAvfsFuses; uint8_t OverrideGfxAvfsFuses;
@@ -1193,7 +1220,6 @@ typedef struct {
uint32_t dGbV_dT_vmin; uint32_t dGbV_dT_vmin;
uint32_t dGbV_dT_vmax; uint32_t dGbV_dT_vmax;
//Unused: PMFW-9370
uint32_t V2F_vmin_range_low; uint32_t V2F_vmin_range_low;
uint32_t V2F_vmin_range_high; uint32_t V2F_vmin_range_high;
uint32_t V2F_vmax_range_low; uint32_t V2F_vmax_range_low;
@@ -1238,8 +1264,21 @@ typedef struct {
// SECTION: Advanced Options // SECTION: Advanced Options
uint32_t DebugOverrides; uint32_t DebugOverrides;
// Section: Total Board Power idle vs active coefficients
uint8_t TotalBoardPowerSupport;
uint8_t TotalBoardPowerPadding[3];
int16_t TotalIdleBoardPowerM;
int16_t TotalIdleBoardPowerB;
int16_t TotalBoardPowerM;
int16_t TotalBoardPowerB;
QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
// SECTION: Sku Reserved // SECTION: Sku Reserved
uint32_t Spare[64]; uint32_t Spare[43];
// Padding for MMHUB - do not modify this // Padding for MMHUB - do not modify this
uint32_t MmHubPadding[8]; uint32_t MmHubPadding[8];
@@ -1304,7 +1343,8 @@ typedef struct {
// SECTION: Clock Spread Spectrum // SECTION: Clock Spread Spectrum
// UCLK Spread Spectrum // UCLK Spread Spectrum
uint16_t UclkSpreadPadding; uint8_t UclkTrainingModeSpreadPercent; // Q4.4
uint8_t UclkSpreadPadding;
uint16_t UclkSpreadFreq; // kHz uint16_t UclkSpreadFreq; // kHz
// UCLK Spread Spectrum // UCLK Spread Spectrum
@@ -1317,11 +1357,7 @@ typedef struct {
// Section: Memory Config // Section: Memory Config
uint8_t DramWidth; // Width of interface to the channel for each DRAM module. See DRAM_BIT_WIDTH_TYPE_e uint8_t DramWidth; // Width of interface to the channel for each DRAM module. See DRAM_BIT_WIDTH_TYPE_e
uint8_t PaddingMem1[3]; uint8_t PaddingMem1[7];
// Section: Total Board Power
uint16_t TotalBoardPower; //Only needed for TCP Estimated case, where TCP = TGP+Total Board Power
uint16_t BoardPowerPadding;
// SECTION: UMC feature flags // SECTION: UMC feature flags
uint8_t HsrEnabled; uint8_t HsrEnabled;
@@ -1423,8 +1459,11 @@ typedef struct {
uint16_t Vcn1ActivityPercentage ; uint16_t Vcn1ActivityPercentage ;
uint32_t EnergyAccumulator; uint32_t EnergyAccumulator;
uint16_t AverageSocketPower ; uint16_t AverageSocketPower;
uint16_t AverageTotalBoardPower;
uint16_t AvgTemperature[TEMP_COUNT]; uint16_t AvgTemperature[TEMP_COUNT];
uint16_t AvgTemperatureFanIntake;
uint8_t PcieRate ; uint8_t PcieRate ;
uint8_t PcieWidth ; uint8_t PcieWidth ;
@@ -1592,5 +1631,7 @@ typedef struct {
#define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5 #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5
#define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6 #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6
#define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7 #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7
#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
#endif #endif

View File

@@ -31,7 +31,7 @@
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x35
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D
#define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms #define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms

View File

@@ -5186,7 +5186,7 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm
mst_state = drm_atomic_get_mst_topology_state(state, mgr); mst_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(mst_state)) if (IS_ERR(mst_state))
return -EINVAL; return PTR_ERR(mst_state);
list_for_each_entry(pos, &mst_state->payloads, next) { list_for_each_entry(pos, &mst_state->payloads, next) {

View File

@@ -2434,7 +2434,7 @@ intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port)
{ {
const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port); const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_io == POWER_DOMAIN_INVALID) if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID))
return POWER_DOMAIN_PORT_DDI_IO_A; return POWER_DOMAIN_PORT_DDI_IO_A;
return domains->ddi_io + (int)(port - domains->port_start); return domains->ddi_io + (int)(port - domains->port_start);
@@ -2445,7 +2445,7 @@ intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port po
{ {
const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port); const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_lanes == POWER_DOMAIN_INVALID) if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID))
return POWER_DOMAIN_PORT_DDI_LANES_A; return POWER_DOMAIN_PORT_DDI_LANES_A;
return domains->ddi_lanes + (int)(port - domains->port_start); return domains->ddi_lanes + (int)(port - domains->port_start);
@@ -2471,7 +2471,7 @@ intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch
{ {
const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch); const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID) if (drm_WARN_ON(&i915->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID))
return POWER_DOMAIN_AUX_A; return POWER_DOMAIN_AUX_A;
return domains->aux_legacy_usbc + (int)(aux_ch - domains->aux_ch_start); return domains->aux_legacy_usbc + (int)(aux_ch - domains->aux_ch_start);
@@ -2482,7 +2482,7 @@ intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch au
{ {
const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch); const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_tbt == POWER_DOMAIN_INVALID) if (drm_WARN_ON(&i915->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID))
return POWER_DOMAIN_AUX_TBT1; return POWER_DOMAIN_AUX_TBT1;
return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start); return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start);

View File

@@ -612,6 +612,10 @@ static int i915_ttm_truncate(struct drm_i915_gem_object *obj)
WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED); WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED);
err = ttm_bo_wait(bo, true, false);
if (err)
return err;
err = i915_ttm_move_notify(bo); err = i915_ttm_move_notify(bo);
if (err) if (err)
return err; return err;

View File

@@ -664,8 +664,6 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
return -ESRCH; return -ESRCH;
} }
kvm_get_kvm(vgpu->vfio_device.kvm);
if (__kvmgt_vgpu_exist(vgpu)) if (__kvmgt_vgpu_exist(vgpu))
return -EEXIST; return -EEXIST;
@@ -676,6 +674,7 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
vgpu->track_node.track_write = kvmgt_page_track_write; vgpu->track_node.track_write = kvmgt_page_track_write;
vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot; vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
kvm_get_kvm(vgpu->vfio_device.kvm);
kvm_page_track_register_notifier(vgpu->vfio_device.kvm, kvm_page_track_register_notifier(vgpu->vfio_device.kvm,
&vgpu->track_node); &vgpu->track_node);
@@ -715,15 +714,14 @@ static void intel_vgpu_close_device(struct vfio_device *vfio_dev)
kvm_page_track_unregister_notifier(vgpu->vfio_device.kvm, kvm_page_track_unregister_notifier(vgpu->vfio_device.kvm,
&vgpu->track_node); &vgpu->track_node);
kvm_put_kvm(vgpu->vfio_device.kvm);
kvmgt_protect_table_destroy(vgpu); kvmgt_protect_table_destroy(vgpu);
gvt_cache_destroy(vgpu); gvt_cache_destroy(vgpu);
intel_vgpu_release_msi_eventfd_ctx(vgpu); intel_vgpu_release_msi_eventfd_ctx(vgpu);
vgpu->attached = false; vgpu->attached = false;
if (vgpu->vfio_device.kvm)
kvm_put_kvm(vgpu->vfio_device.kvm);
} }
static u64 intel_vgpu_get_bar_addr(struct intel_vgpu *vgpu, int bar) static u64 intel_vgpu_get_bar_addr(struct intel_vgpu *vgpu, int bar)

View File

@@ -577,7 +577,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
if (scr_readw(r) != vc->vc_video_erase_char) if (scr_readw(r) != vc->vc_video_erase_char)
break; break;
if (r != q && new_rows >= rows + logo_lines) { if (r != q && new_rows >= rows + logo_lines) {
save = kmalloc(array3_size(logo_lines, new_cols, 2), save = kzalloc(array3_size(logo_lines, new_cols, 2),
GFP_KERNEL); GFP_KERNEL);
if (save) { if (save) {
int i = min(cols, new_cols); int i = min(cols, new_cols);