mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 07:38:10 +00:00
Merge tag 'amd-drm-fixes-5.16-2021-11-03' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-fixes-5.16-2021-11-03: amdgpu: - GPU reset fix - Aldebaran fix - Yellow Carp fixes - DCN2.1 DMCUB fix - IOMMU regression fix for Picasso - DSC display fixes - BPC display calculation fixes - Other misc display fixes amdkfd: - SVM fixes - Fix gfx version for renoir Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211104024447.4535-1-alexander.deucher@amd.com
This commit is contained in:
commit
806acd3819
37 changed files with 398 additions and 252 deletions
|
@ -2398,10 +2398,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
if (!adev->gmc.xgmi.pending_reset)
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
||||
r = amdgpu_amdkfd_resume_iommu(adev);
|
||||
if (r)
|
||||
goto init_failed;
|
||||
|
||||
amdgpu_fru_get_product_info(adev);
|
||||
|
||||
init_failed:
|
||||
|
@ -4850,6 +4846,9 @@ static void amdgpu_device_recheck_guilty_jobs(
|
|||
|
||||
/* clear job's guilty and depend the folowing step to decide the real one */
|
||||
drm_sched_reset_karma(s_job);
|
||||
/* for the real bad job, it will be resubmitted twice, adding a dma_fence_get
|
||||
* to make sure fence is balanced */
|
||||
dma_fence_get(s_job->s_fence->parent);
|
||||
drm_sched_resubmit_jobs_ext(&ring->sched, 1);
|
||||
|
||||
ret = dma_fence_wait_timeout(s_job->s_fence->parent, false, ring->sched.timeout);
|
||||
|
@ -4885,6 +4884,7 @@ static void amdgpu_device_recheck_guilty_jobs(
|
|||
|
||||
/* got the hw fence, signal finished fence */
|
||||
atomic_dec(ring->sched.score);
|
||||
dma_fence_put(s_job->s_fence->parent);
|
||||
dma_fence_get(&s_job->s_fence->finished);
|
||||
dma_fence_signal(&s_job->s_fence->finished);
|
||||
dma_fence_put(&s_job->s_fence->finished);
|
||||
|
|
|
@ -1423,6 +1423,8 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
|
|||
struct drm_amdgpu_info_firmware fw_info;
|
||||
struct drm_amdgpu_query_fw query_fw;
|
||||
struct atom_context *ctx = adev->mode_info.atom_context;
|
||||
uint8_t smu_minor, smu_debug;
|
||||
uint16_t smu_major;
|
||||
int ret, i;
|
||||
|
||||
static const char *ta_fw_name[TA_FW_TYPE_MAX_INDEX] = {
|
||||
|
@ -1568,8 +1570,11 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
|
|||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
smu_major = (fw_info.ver >> 16) & 0xffff;
|
||||
smu_minor = (fw_info.ver >> 8) & 0xff;
|
||||
smu_debug = (fw_info.ver >> 0) & 0xff;
|
||||
seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x (%d.%d.%d)\n",
|
||||
fw_info.feature, fw_info.ver, smu_major, smu_minor, smu_debug);
|
||||
|
||||
/* SDMA */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_SDMA;
|
||||
|
|
|
@ -8316,11 +8316,8 @@ static void gfx_v10_cntl_power_gating(struct amdgpu_device *adev, bool enable)
|
|||
if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) {
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(10, 3, 1):
|
||||
data = 0x4E20 & RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK_Vangogh;
|
||||
WREG32_SOC15(GC, 0, mmRLC_PG_DELAY_3, data);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 3):
|
||||
data = 0x1388 & RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK_Vangogh;
|
||||
data = 0x4E20 & RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK_Vangogh;
|
||||
WREG32_SOC15(GC, 0, mmRLC_PG_DELAY_3, data);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -54,15 +54,17 @@ int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
|
|||
seg_size = REG_GET_FIELD(
|
||||
RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_SIZE_ALDE),
|
||||
MC_VM_XGMI_LFB_SIZE, PF_LFB_SIZE) << 24;
|
||||
max_region =
|
||||
REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL_ALDE, PF_MAX_REGION);
|
||||
} else {
|
||||
xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL);
|
||||
seg_size = REG_GET_FIELD(
|
||||
RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_SIZE),
|
||||
MC_VM_XGMI_LFB_SIZE, PF_LFB_SIZE) << 24;
|
||||
max_region =
|
||||
REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION);
|
||||
}
|
||||
|
||||
max_region =
|
||||
REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION);
|
||||
|
||||
|
||||
switch (adev->asic_type) {
|
||||
|
@ -89,9 +91,15 @@ int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
|
|||
if (adev->gmc.xgmi.num_physical_nodes > max_num_physical_nodes)
|
||||
return -EINVAL;
|
||||
|
||||
adev->gmc.xgmi.physical_node_id =
|
||||
REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL,
|
||||
PF_LFB_REGION);
|
||||
if (adev->asic_type == CHIP_ALDEBARAN) {
|
||||
adev->gmc.xgmi.physical_node_id =
|
||||
REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL_ALDE,
|
||||
PF_LFB_REGION);
|
||||
} else {
|
||||
adev->gmc.xgmi.physical_node_id =
|
||||
REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL,
|
||||
PF_LFB_REGION);
|
||||
}
|
||||
|
||||
if (adev->gmc.xgmi.physical_node_id > max_physical_node_id)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -406,7 +406,7 @@ static const struct kfd_device_info aldebaran_device_info = {
|
|||
static const struct kfd_device_info renoir_device_info = {
|
||||
.asic_family = CHIP_RENOIR,
|
||||
.asic_name = "renoir",
|
||||
.gfx_target_version = 90002,
|
||||
.gfx_target_version = 90012,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
|
@ -281,6 +281,19 @@ static unsigned long svm_migrate_successful_pages(struct migrate_vma *migrate)
|
|||
return cpages;
|
||||
}
|
||||
|
||||
static unsigned long svm_migrate_unsuccessful_pages(struct migrate_vma *migrate)
|
||||
{
|
||||
unsigned long upages = 0;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < migrate->npages; i++) {
|
||||
if (migrate->src[i] & MIGRATE_PFN_VALID &&
|
||||
!(migrate->src[i] & MIGRATE_PFN_MIGRATE))
|
||||
upages++;
|
||||
}
|
||||
return upages;
|
||||
}
|
||||
|
||||
static int
|
||||
svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct migrate_vma *migrate, struct dma_fence **mfence,
|
||||
|
@ -634,10 +647,11 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
|||
struct vm_area_struct *vma, uint64_t start, uint64_t end)
|
||||
{
|
||||
uint64_t npages = (end - start) >> PAGE_SHIFT;
|
||||
unsigned long upages = npages;
|
||||
unsigned long cpages = 0;
|
||||
struct kfd_process_device *pdd;
|
||||
struct dma_fence *mfence = NULL;
|
||||
struct migrate_vma migrate;
|
||||
unsigned long cpages = 0;
|
||||
dma_addr_t *scratch;
|
||||
size_t size;
|
||||
void *buf;
|
||||
|
@ -671,6 +685,7 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
|||
if (!cpages) {
|
||||
pr_debug("failed collect migrate device pages [0x%lx 0x%lx]\n",
|
||||
prange->start, prange->last);
|
||||
upages = svm_migrate_unsuccessful_pages(&migrate);
|
||||
goto out_free;
|
||||
}
|
||||
if (cpages != npages)
|
||||
|
@ -683,8 +698,9 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
|||
scratch, npages);
|
||||
migrate_vma_pages(&migrate);
|
||||
|
||||
pr_debug("successful/cpages/npages 0x%lx/0x%lx/0x%lx\n",
|
||||
svm_migrate_successful_pages(&migrate), cpages, migrate.npages);
|
||||
upages = svm_migrate_unsuccessful_pages(&migrate);
|
||||
pr_debug("unsuccessful/cpages/npages 0x%lx/0x%lx/0x%lx\n",
|
||||
upages, cpages, migrate.npages);
|
||||
|
||||
svm_migrate_copy_done(adev, mfence);
|
||||
migrate_vma_finalize(&migrate);
|
||||
|
@ -698,9 +714,9 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
|||
if (pdd)
|
||||
WRITE_ONCE(pdd->page_out, pdd->page_out + cpages);
|
||||
|
||||
return cpages;
|
||||
return upages;
|
||||
}
|
||||
return r;
|
||||
return r ? r : upages;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -720,7 +736,7 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm)
|
|||
unsigned long addr;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
unsigned long cpages = 0;
|
||||
unsigned long upages = 0;
|
||||
long r = 0;
|
||||
|
||||
if (!prange->actual_loc) {
|
||||
|
@ -756,12 +772,12 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm)
|
|||
pr_debug("failed %ld to migrate\n", r);
|
||||
break;
|
||||
} else {
|
||||
cpages += r;
|
||||
upages += r;
|
||||
}
|
||||
addr = next;
|
||||
}
|
||||
|
||||
if (cpages) {
|
||||
if (!upages) {
|
||||
svm_range_vram_node_free(prange);
|
||||
prange->actual_loc = 0;
|
||||
}
|
||||
|
@ -784,7 +800,7 @@ static int
|
|||
svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
int r;
|
||||
int r, retries = 3;
|
||||
|
||||
/*
|
||||
* TODO: for both devices with PCIe large bar or on same xgmi hive, skip
|
||||
|
@ -793,9 +809,14 @@ svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
|||
|
||||
pr_debug("from gpu 0x%x to gpu 0x%x\n", prange->actual_loc, best_loc);
|
||||
|
||||
r = svm_migrate_vram_to_ram(prange, mm);
|
||||
if (r)
|
||||
return r;
|
||||
do {
|
||||
r = svm_migrate_vram_to_ram(prange, mm);
|
||||
if (r)
|
||||
return r;
|
||||
} while (prange->actual_loc && --retries);
|
||||
|
||||
if (prange->actual_loc)
|
||||
return -EDEADLK;
|
||||
|
||||
return svm_migrate_ram_to_vram(prange, best_loc, mm);
|
||||
}
|
||||
|
|
|
@ -2261,7 +2261,7 @@ svm_range_from_addr(struct svm_range_list *svms, unsigned long addr,
|
|||
* migration if actual loc is not best location, then update GPU page table
|
||||
* mapping to the best location.
|
||||
*
|
||||
* If vm fault gpu is range preferred loc, the best_loc is preferred loc.
|
||||
* If the preferred loc is accessible by faulting GPU, use preferred loc.
|
||||
* If vm fault gpu idx is on range ACCESSIBLE bitmap, best_loc is vm fault gpu
|
||||
* If vm fault gpu idx is on range ACCESSIBLE_IN_PLACE bitmap, then
|
||||
* if range actual loc is cpu, best_loc is cpu
|
||||
|
@ -2278,7 +2278,7 @@ svm_range_best_restore_location(struct svm_range *prange,
|
|||
struct amdgpu_device *adev,
|
||||
int32_t *gpuidx)
|
||||
{
|
||||
struct amdgpu_device *bo_adev;
|
||||
struct amdgpu_device *bo_adev, *preferred_adev;
|
||||
struct kfd_process *p;
|
||||
uint32_t gpuid;
|
||||
int r;
|
||||
|
@ -2291,8 +2291,16 @@ svm_range_best_restore_location(struct svm_range *prange,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (prange->preferred_loc == gpuid)
|
||||
if (prange->preferred_loc == gpuid ||
|
||||
prange->preferred_loc == KFD_IOCTL_SVM_LOCATION_SYSMEM) {
|
||||
return prange->preferred_loc;
|
||||
} else if (prange->preferred_loc != KFD_IOCTL_SVM_LOCATION_UNDEFINED) {
|
||||
preferred_adev = svm_range_get_adev_by_id(prange,
|
||||
prange->preferred_loc);
|
||||
if (amdgpu_xgmi_same_hive(adev, preferred_adev))
|
||||
return prange->preferred_loc;
|
||||
/* fall through */
|
||||
}
|
||||
|
||||
if (test_bit(*gpuidx, prange->bitmap_access))
|
||||
return gpuid;
|
||||
|
@ -2313,7 +2321,8 @@ svm_range_best_restore_location(struct svm_range *prange,
|
|||
|
||||
static int
|
||||
svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
||||
unsigned long *start, unsigned long *last)
|
||||
unsigned long *start, unsigned long *last,
|
||||
bool *is_heap_stack)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
struct interval_tree_node *node;
|
||||
|
@ -2324,6 +2333,12 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
|||
pr_debug("VMA does not exist in address [0x%llx]\n", addr);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
*is_heap_stack = (vma->vm_start <= vma->vm_mm->brk &&
|
||||
vma->vm_end >= vma->vm_mm->start_brk) ||
|
||||
(vma->vm_start <= vma->vm_mm->start_stack &&
|
||||
vma->vm_end >= vma->vm_mm->start_stack);
|
||||
|
||||
start_limit = max(vma->vm_start >> PAGE_SHIFT,
|
||||
(unsigned long)ALIGN_DOWN(addr, 2UL << 8));
|
||||
end_limit = min(vma->vm_end >> PAGE_SHIFT,
|
||||
|
@ -2353,9 +2368,9 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
|||
*start = start_limit;
|
||||
*last = end_limit - 1;
|
||||
|
||||
pr_debug("vma start: 0x%lx start: 0x%lx vma end: 0x%lx last: 0x%lx\n",
|
||||
vma->vm_start >> PAGE_SHIFT, *start,
|
||||
vma->vm_end >> PAGE_SHIFT, *last);
|
||||
pr_debug("vma [0x%lx 0x%lx] range [0x%lx 0x%lx] is_heap_stack %d\n",
|
||||
vma->vm_start >> PAGE_SHIFT, vma->vm_end >> PAGE_SHIFT,
|
||||
*start, *last, *is_heap_stack);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2420,11 +2435,13 @@ svm_range *svm_range_create_unregistered_range(struct amdgpu_device *adev,
|
|||
struct svm_range *prange = NULL;
|
||||
unsigned long start, last;
|
||||
uint32_t gpuid, gpuidx;
|
||||
bool is_heap_stack;
|
||||
uint64_t bo_s = 0;
|
||||
uint64_t bo_l = 0;
|
||||
int r;
|
||||
|
||||
if (svm_range_get_range_boundaries(p, addr, &start, &last))
|
||||
if (svm_range_get_range_boundaries(p, addr, &start, &last,
|
||||
&is_heap_stack))
|
||||
return NULL;
|
||||
|
||||
r = svm_range_check_vm(p, start, last, &bo_s, &bo_l);
|
||||
|
@ -2451,6 +2468,9 @@ svm_range *svm_range_create_unregistered_range(struct amdgpu_device *adev,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (is_heap_stack)
|
||||
prange->preferred_loc = KFD_IOCTL_SVM_LOCATION_SYSMEM;
|
||||
|
||||
svm_range_add_to_svms(prange);
|
||||
svm_range_add_notifier_locked(mm, prange);
|
||||
|
||||
|
@ -3076,6 +3096,8 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
|
|||
struct svm_range *prange =
|
||||
list_first_entry(&svm_bo->range_list,
|
||||
struct svm_range, svm_bo_list);
|
||||
int retries = 3;
|
||||
|
||||
list_del_init(&prange->svm_bo_list);
|
||||
spin_unlock(&svm_bo->list_lock);
|
||||
|
||||
|
@ -3083,7 +3105,11 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
|
|||
prange->start, prange->last);
|
||||
|
||||
mutex_lock(&prange->migrate_mutex);
|
||||
svm_migrate_vram_to_ram(prange, svm_bo->eviction_fence->mm);
|
||||
do {
|
||||
svm_migrate_vram_to_ram(prange,
|
||||
svm_bo->eviction_fence->mm);
|
||||
} while (prange->actual_loc && --retries);
|
||||
WARN(prange->actual_loc, "Migration failed during eviction");
|
||||
|
||||
mutex_lock(&prange->lock);
|
||||
prange->svm_bo = NULL;
|
||||
|
|
|
@ -1410,7 +1410,15 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
switch (adev->ip_versions[DCE_HWIP][0]) {
|
||||
case IP_VERSION(2, 1, 0):
|
||||
init_data.flags.gpu_vm_support = true;
|
||||
init_data.flags.disable_dmcu = true;
|
||||
switch (adev->dm.dmcub_fw_version) {
|
||||
case 0: /* development */
|
||||
case 0x1: /* linux-firmware.git hash 6d9f399 */
|
||||
case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */
|
||||
init_data.flags.disable_dmcu = false;
|
||||
break;
|
||||
default:
|
||||
init_data.flags.disable_dmcu = true;
|
||||
}
|
||||
break;
|
||||
case IP_VERSION(1, 0, 0):
|
||||
case IP_VERSION(1, 0, 1):
|
||||
|
@ -7241,8 +7249,8 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
|
|||
struct drm_connector_state *new_con_state;
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct dm_connector_state *dm_conn_state;
|
||||
int i, j, clock;
|
||||
int vcpi, pbn_div, pbn = 0;
|
||||
int i, j;
|
||||
int vcpi, pbn_div, pbn, slot_num = 0;
|
||||
|
||||
for_each_new_connector_in_state(state, connector, new_con_state, i) {
|
||||
|
||||
|
@ -7270,17 +7278,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
|
|||
if (!stream)
|
||||
continue;
|
||||
|
||||
if (stream->timing.flags.DSC != 1) {
|
||||
drm_dp_mst_atomic_enable_dsc(state,
|
||||
aconnector->port,
|
||||
dm_conn_state->pbn,
|
||||
0,
|
||||
false);
|
||||
continue;
|
||||
}
|
||||
|
||||
pbn_div = dm_mst_get_pbn_divider(stream->link);
|
||||
clock = stream->timing.pix_clk_100hz / 10;
|
||||
/* pbn is calculated by compute_mst_dsc_configs_for_state*/
|
||||
for (j = 0; j < dc_state->stream_count; j++) {
|
||||
if (vars[j].aconnector == aconnector) {
|
||||
|
@ -7289,6 +7287,23 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
if (j == dc_state->stream_count)
|
||||
continue;
|
||||
|
||||
slot_num = DIV_ROUND_UP(pbn, pbn_div);
|
||||
|
||||
if (stream->timing.flags.DSC != 1) {
|
||||
dm_conn_state->pbn = pbn;
|
||||
dm_conn_state->vcpi_slots = slot_num;
|
||||
|
||||
drm_dp_mst_atomic_enable_dsc(state,
|
||||
aconnector->port,
|
||||
dm_conn_state->pbn,
|
||||
0,
|
||||
false);
|
||||
continue;
|
||||
}
|
||||
|
||||
vcpi = drm_dp_mst_atomic_enable_dsc(state,
|
||||
aconnector->port,
|
||||
pbn, pbn_div,
|
||||
|
|
|
@ -534,13 +534,14 @@ static int kbps_to_peak_pbn(int kbps)
|
|||
|
||||
static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params,
|
||||
struct dsc_mst_fairness_vars *vars,
|
||||
int count)
|
||||
int count,
|
||||
int k)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
memset(¶ms[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg));
|
||||
if (vars[i].dsc_enabled && dc_dsc_compute_config(
|
||||
if (vars[i + k].dsc_enabled && dc_dsc_compute_config(
|
||||
params[i].sink->ctx->dc->res_pool->dscs[0],
|
||||
¶ms[i].sink->dsc_caps.dsc_dec_caps,
|
||||
params[i].sink->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
|
@ -553,7 +554,7 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
|
|||
if (params[i].bpp_overwrite)
|
||||
params[i].timing->dsc_cfg.bits_per_pixel = params[i].bpp_overwrite;
|
||||
else
|
||||
params[i].timing->dsc_cfg.bits_per_pixel = vars[i].bpp_x16;
|
||||
params[i].timing->dsc_cfg.bits_per_pixel = vars[i + k].bpp_x16;
|
||||
|
||||
if (params[i].num_slices_h)
|
||||
params[i].timing->dsc_cfg.num_slices_h = params[i].num_slices_h;
|
||||
|
@ -586,7 +587,8 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
|
|||
struct dc_link *dc_link,
|
||||
struct dsc_mst_fairness_params *params,
|
||||
struct dsc_mst_fairness_vars *vars,
|
||||
int count)
|
||||
int count,
|
||||
int k)
|
||||
{
|
||||
int i;
|
||||
bool bpp_increased[MAX_PIPES];
|
||||
|
@ -601,8 +603,9 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
|
|||
pbn_per_timeslot = dm_mst_get_pbn_divider(dc_link);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (vars[i].dsc_enabled) {
|
||||
initial_slack[i] = kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i].pbn;
|
||||
if (vars[i + k].dsc_enabled) {
|
||||
initial_slack[i] =
|
||||
kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i + k].pbn;
|
||||
bpp_increased[i] = false;
|
||||
remaining_to_increase += 1;
|
||||
} else {
|
||||
|
@ -629,7 +632,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
|
|||
link_timeslots_used = 0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
link_timeslots_used += DIV_ROUND_UP(vars[i].pbn, pbn_per_timeslot);
|
||||
link_timeslots_used += DIV_ROUND_UP(vars[i + k].pbn, pbn_per_timeslot);
|
||||
|
||||
fair_pbn_alloc = (63 - link_timeslots_used) / remaining_to_increase * pbn_per_timeslot;
|
||||
|
||||
|
@ -682,7 +685,8 @@ static void try_disable_dsc(struct drm_atomic_state *state,
|
|||
struct dc_link *dc_link,
|
||||
struct dsc_mst_fairness_params *params,
|
||||
struct dsc_mst_fairness_vars *vars,
|
||||
int count)
|
||||
int count,
|
||||
int k)
|
||||
{
|
||||
int i;
|
||||
bool tried[MAX_PIPES];
|
||||
|
@ -692,8 +696,8 @@ static void try_disable_dsc(struct drm_atomic_state *state,
|
|||
int remaining_to_try = 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (vars[i].dsc_enabled
|
||||
&& vars[i].bpp_x16 == params[i].bw_range.max_target_bpp_x16
|
||||
if (vars[i + k].dsc_enabled
|
||||
&& vars[i + k].bpp_x16 == params[i].bw_range.max_target_bpp_x16
|
||||
&& params[i].clock_force_enable == DSC_CLK_FORCE_DEFAULT) {
|
||||
kbps_increase[i] = params[i].bw_range.stream_kbps - params[i].bw_range.max_kbps;
|
||||
tried[i] = false;
|
||||
|
@ -748,9 +752,10 @@ static void try_disable_dsc(struct drm_atomic_state *state,
|
|||
static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state,
|
||||
struct dc_link *dc_link,
|
||||
struct dsc_mst_fairness_vars *vars)
|
||||
struct dsc_mst_fairness_vars *vars,
|
||||
int *link_vars_start_index)
|
||||
{
|
||||
int i;
|
||||
int i, k;
|
||||
struct dc_stream_state *stream;
|
||||
struct dsc_mst_fairness_params params[MAX_PIPES];
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
|
@ -768,11 +773,17 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
if (stream->link != dc_link)
|
||||
continue;
|
||||
|
||||
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
|
||||
if (!aconnector)
|
||||
continue;
|
||||
|
||||
if (!aconnector->port)
|
||||
continue;
|
||||
|
||||
stream->timing.flags.DSC = 0;
|
||||
|
||||
params[count].timing = &stream->timing;
|
||||
params[count].sink = stream->sink;
|
||||
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
|
||||
params[count].aconnector = aconnector;
|
||||
params[count].port = aconnector->port;
|
||||
params[count].clock_force_enable = aconnector->dsc_settings.dsc_force_enable;
|
||||
|
@ -794,44 +805,55 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
ASSERT(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* k is start index of vars for current phy link used by mst hub */
|
||||
k = *link_vars_start_index;
|
||||
/* set vars start index for next mst hub phy link */
|
||||
*link_vars_start_index += count;
|
||||
|
||||
/* Try no compression */
|
||||
for (i = 0; i < count; i++) {
|
||||
vars[i].aconnector = params[i].aconnector;
|
||||
vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
|
||||
vars[i].dsc_enabled = false;
|
||||
vars[i].bpp_x16 = 0;
|
||||
vars[i + k].aconnector = params[i].aconnector;
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
|
||||
vars[i + k].dsc_enabled = false;
|
||||
vars[i + k].bpp_x16 = 0;
|
||||
if (drm_dp_atomic_find_vcpi_slots(state,
|
||||
params[i].port->mgr,
|
||||
params[i].port,
|
||||
vars[i].pbn,
|
||||
vars[i + k].pbn,
|
||||
dm_mst_get_pbn_divider(dc_link)) < 0)
|
||||
return false;
|
||||
}
|
||||
if (!drm_dp_mst_atomic_check(state) && !debugfs_overwrite) {
|
||||
set_dsc_configs_from_fairness_vars(params, vars, count);
|
||||
set_dsc_configs_from_fairness_vars(params, vars, count, k);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Try max compression */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) {
|
||||
vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps);
|
||||
vars[i].dsc_enabled = true;
|
||||
vars[i].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps);
|
||||
vars[i + k].dsc_enabled = true;
|
||||
vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
|
||||
if (drm_dp_atomic_find_vcpi_slots(state,
|
||||
params[i].port->mgr,
|
||||
params[i].port,
|
||||
vars[i].pbn,
|
||||
vars[i + k].pbn,
|
||||
dm_mst_get_pbn_divider(dc_link)) < 0)
|
||||
return false;
|
||||
} else {
|
||||
vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
|
||||
vars[i].dsc_enabled = false;
|
||||
vars[i].bpp_x16 = 0;
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
|
||||
vars[i + k].dsc_enabled = false;
|
||||
vars[i + k].bpp_x16 = 0;
|
||||
if (drm_dp_atomic_find_vcpi_slots(state,
|
||||
params[i].port->mgr,
|
||||
params[i].port,
|
||||
vars[i].pbn,
|
||||
vars[i + k].pbn,
|
||||
dm_mst_get_pbn_divider(dc_link)) < 0)
|
||||
return false;
|
||||
}
|
||||
|
@ -840,15 +862,76 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
return false;
|
||||
|
||||
/* Optimize degree of compression */
|
||||
increase_dsc_bpp(state, dc_link, params, vars, count);
|
||||
increase_dsc_bpp(state, dc_link, params, vars, count, k);
|
||||
|
||||
try_disable_dsc(state, dc_link, params, vars, count);
|
||||
try_disable_dsc(state, dc_link, params, vars, count, k);
|
||||
|
||||
set_dsc_configs_from_fairness_vars(params, vars, count);
|
||||
set_dsc_configs_from_fairness_vars(params, vars, count, k);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_dsc_need_re_compute(
|
||||
struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state,
|
||||
struct dc_link *dc_link)
|
||||
{
|
||||
int i;
|
||||
bool is_dsc_need_re_compute = false;
|
||||
|
||||
/* only check phy used by mst branch */
|
||||
if (dc_link->type != dc_connection_mst_branch)
|
||||
return false;
|
||||
|
||||
/* check if there is mode change in new request */
|
||||
for (i = 0; i < dc_state->stream_count; i++) {
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct dc_stream_state *stream;
|
||||
struct drm_crtc_state *new_crtc_state;
|
||||
struct drm_connector_state *new_conn_state;
|
||||
|
||||
stream = dc_state->streams[i];
|
||||
|
||||
if (!stream)
|
||||
continue;
|
||||
|
||||
/* check if stream using the same link for mst */
|
||||
if (stream->link != dc_link)
|
||||
continue;
|
||||
|
||||
aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context;
|
||||
if (!aconnector)
|
||||
continue;
|
||||
|
||||
new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base);
|
||||
|
||||
if (!new_conn_state)
|
||||
continue;
|
||||
|
||||
if (IS_ERR(new_conn_state))
|
||||
continue;
|
||||
|
||||
if (!new_conn_state->crtc)
|
||||
continue;
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
|
||||
|
||||
if (!new_crtc_state)
|
||||
continue;
|
||||
|
||||
if (IS_ERR(new_crtc_state))
|
||||
continue;
|
||||
|
||||
if (new_crtc_state->enable && new_crtc_state->active) {
|
||||
if (new_crtc_state->mode_changed || new_crtc_state->active_changed ||
|
||||
new_crtc_state->connectors_changed)
|
||||
is_dsc_need_re_compute = true;
|
||||
}
|
||||
}
|
||||
|
||||
return is_dsc_need_re_compute;
|
||||
}
|
||||
|
||||
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state,
|
||||
struct dsc_mst_fairness_vars *vars)
|
||||
|
@ -857,6 +940,7 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
|||
struct dc_stream_state *stream;
|
||||
bool computed_streams[MAX_PIPES];
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
int link_vars_start_index = 0;
|
||||
|
||||
for (i = 0; i < dc_state->stream_count; i++)
|
||||
computed_streams[i] = false;
|
||||
|
@ -881,8 +965,12 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
|||
if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK)
|
||||
return false;
|
||||
|
||||
if (!is_dsc_need_re_compute(state, dc_state, stream->link))
|
||||
continue;
|
||||
|
||||
mutex_lock(&aconnector->mst_mgr.lock);
|
||||
if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars)) {
|
||||
if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link,
|
||||
vars, &link_vars_start_index)) {
|
||||
mutex_unlock(&aconnector->mst_mgr.lock);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1085,6 +1085,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
|||
struct dc_stream_state *old_stream =
|
||||
dc->current_state->res_ctx.pipe_ctx[i].stream;
|
||||
bool should_disable = true;
|
||||
bool pipe_split_change =
|
||||
context->res_ctx.pipe_ctx[i].top_pipe != dc->current_state->res_ctx.pipe_ctx[i].top_pipe;
|
||||
|
||||
for (j = 0; j < context->stream_count; j++) {
|
||||
if (old_stream == context->streams[j]) {
|
||||
|
@ -1092,6 +1094,9 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!should_disable && pipe_split_change)
|
||||
should_disable = true;
|
||||
|
||||
if (should_disable && old_stream) {
|
||||
dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
|
||||
disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
|
||||
|
@ -3603,7 +3608,8 @@ bool dc_enable_dmub_notifications(struct dc *dc)
|
|||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* YELLOW_CARP B0 USB4 DPIA needs dmub notifications for interrupts */
|
||||
if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
|
||||
dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0)
|
||||
dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 &&
|
||||
!dc->debug.dpia_debug.bits.disable_dpia)
|
||||
return true;
|
||||
#endif
|
||||
/* dmub aux needs dmub notifications to be enabled */
|
||||
|
|
|
@ -4279,6 +4279,8 @@ void core_link_enable_stream(
|
|||
*/
|
||||
if (status != DC_FAIL_DP_LINK_TRAINING ||
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
|
||||
if (false == stream->link->link_status.link_active)
|
||||
disable_link(stream->link, pipe_ctx->stream->signal);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5329,6 +5329,14 @@ bool dc_link_dp_set_test_pattern(
|
|||
return false;
|
||||
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE)
|
||||
core_link_write_dpcd(link,
|
||||
DP_LINK_SQUARE_PATTERN,
|
||||
p_custom_pattern,
|
||||
1);
|
||||
|
||||
#endif
|
||||
/* tell receiver that we are sending qualification
|
||||
* pattern DP 1.2 or later - DP receiver's link quality
|
||||
* pattern is set using DPCD LINK_QUAL_LANEx_SET
|
||||
|
|
|
@ -236,6 +236,23 @@ static struct link_encoder *get_link_enc_used_by_link(
|
|||
|
||||
return link_enc;
|
||||
}
|
||||
/* Clear all link encoder assignments. */
|
||||
static void clear_enc_assignments(struct dc_state *state)
|
||||
{
|
||||
int i;
|
||||
enum engine_id eng_id;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid = false;
|
||||
eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id;
|
||||
stream = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream;
|
||||
if (eng_id != ENGINE_ID_UNKNOWN)
|
||||
state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_id - ENGINE_ID_DIGA] = eng_id;
|
||||
if (stream)
|
||||
stream->link_enc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void link_enc_cfg_init(
|
||||
struct dc *dc,
|
||||
|
@ -250,6 +267,8 @@ void link_enc_cfg_init(
|
|||
state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN;
|
||||
}
|
||||
|
||||
clear_enc_assignments(state);
|
||||
|
||||
state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
|
||||
}
|
||||
|
||||
|
@ -265,6 +284,9 @@ void link_enc_cfg_link_encs_assign(
|
|||
|
||||
ASSERT(state->stream_count == stream_count);
|
||||
|
||||
if (stream_count == 0)
|
||||
clear_enc_assignments(state);
|
||||
|
||||
/* Release DIG link encoder resources before running assignment algorithm. */
|
||||
for (i = 0; i < stream_count; i++)
|
||||
dc->res_pool->funcs->link_enc_unassign(state, streams[i]);
|
||||
|
|
|
@ -47,7 +47,7 @@ struct aux_payload;
|
|||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.159"
|
||||
#define DC_VER "3.2.160"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
@ -675,6 +675,7 @@ struct dc_debug_options {
|
|||
#endif
|
||||
union mem_low_power_enable_options enable_mem_low_power;
|
||||
union root_clock_optimization_options root_clock_optimization;
|
||||
bool hpo_optimization;
|
||||
bool force_vblank_alignment;
|
||||
|
||||
/* Enable dmub aux for legacy ddc */
|
||||
|
|
|
@ -898,6 +898,9 @@ struct dpcd_usb4_dp_tunneling_info {
|
|||
#ifndef DP_DFP_CAPABILITY_EXTENSION_SUPPORT
|
||||
#define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0A3
|
||||
#endif
|
||||
#ifndef DP_LINK_SQUARE_PATTERN
|
||||
#define DP_LINK_SQUARE_PATTERN 0x10F
|
||||
#endif
|
||||
#ifndef DP_DSC_CONFIGURATION
|
||||
#define DP_DSC_CONFIGURATION 0x161
|
||||
#endif
|
||||
|
|
|
@ -671,6 +671,7 @@ struct dce_hwseq_registers {
|
|||
uint32_t MC_VM_FB_LOCATION_BASE;
|
||||
uint32_t MC_VM_FB_LOCATION_TOP;
|
||||
uint32_t MC_VM_FB_OFFSET;
|
||||
uint32_t HPO_TOP_HW_CONTROL;
|
||||
};
|
||||
/* set field name */
|
||||
#define HWS_SF(blk_name, reg_name, field_name, post_fix)\
|
||||
|
@ -1152,7 +1153,8 @@ struct dce_hwseq_registers {
|
|||
type DOMAIN_PGFSM_PWR_STATUS;\
|
||||
type HPO_HDMISTREAMCLK_G_GATE_DIS;\
|
||||
type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE;\
|
||||
type I2C_LIGHT_SLEEP_FORCE;
|
||||
type I2C_LIGHT_SLEEP_FORCE;\
|
||||
type HPO_IO_EN;
|
||||
|
||||
struct dce_hwseq_shift {
|
||||
HWSEQ_REG_FIELD_LIST(uint8_t)
|
||||
|
|
|
@ -1244,6 +1244,12 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
|
|||
#endif
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dc->hwseq->funcs.setup_hpo_hw_control && is_dp_128b_132b_signal(pipe_ctx))
|
||||
dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, false);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
|
||||
|
|
|
@ -231,7 +231,7 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
|
|||
|
||||
if (!s->blank_en)
|
||||
DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh"
|
||||
"% 8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh"
|
||||
" %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh"
|
||||
" %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n",
|
||||
pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start,
|
||||
dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler,
|
||||
|
|
|
@ -2397,6 +2397,9 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
* BY this, it is logic clean to separate stream and link
|
||||
*/
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
|
||||
pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
|
||||
pipe_ctx->stream->ctx->dc->hwseq, true);
|
||||
setup_dp_hpo_stream(pipe_ctx, true);
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->enable_stream(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
|
|
|
@ -1381,13 +1381,11 @@ int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id)
|
|||
|
||||
}
|
||||
|
||||
static void mpc3_mpc_init(struct mpc *mpc)
|
||||
static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc)
|
||||
{
|
||||
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
|
||||
int mpcc_id;
|
||||
|
||||
mpc1_mpc_init(mpc);
|
||||
|
||||
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
|
||||
if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) {
|
||||
REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3);
|
||||
|
@ -1405,7 +1403,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {
|
|||
.read_mpcc_state = mpc1_read_mpcc_state,
|
||||
.insert_plane = mpc1_insert_plane,
|
||||
.remove_mpcc = mpc1_remove_mpcc,
|
||||
.mpc_init = mpc3_mpc_init,
|
||||
.mpc_init = mpc1_mpc_init,
|
||||
.mpc_init_single_inst = mpc1_mpc_init_single_inst,
|
||||
.update_blending = mpc2_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
|
@ -1432,6 +1430,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {
|
|||
.power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
|
||||
.get_mpc_out_mux = mpc1_get_mpc_out_mux,
|
||||
.set_bg_color = mpc1_set_bg_color,
|
||||
.set_mpc_mem_lp_mode = mpc3_set_mpc_mem_lp_mode,
|
||||
};
|
||||
|
||||
void dcn30_mpc_construct(struct dcn30_mpc *mpc30,
|
||||
|
|
|
@ -2128,10 +2128,10 @@ static noinline void dcn30_calculate_wm_and_dlg_fp(
|
|||
int pipe_cnt,
|
||||
int vlevel)
|
||||
{
|
||||
int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
|
||||
int i, pipe_idx;
|
||||
double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||
bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] !=
|
||||
dm_dram_clock_change_unsupported;
|
||||
double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb];
|
||||
bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported;
|
||||
|
||||
if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
|
||||
dcfclk = context->bw_ctx.dml.soc.min_dcfclk;
|
||||
|
@ -2207,6 +2207,7 @@ static noinline void dcn30_calculate_wm_and_dlg_fp(
|
|||
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;
|
||||
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;
|
||||
}
|
||||
|
||||
context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
|
|
|
@ -66,6 +66,45 @@
|
|||
#define FN(reg_name, field_name) \
|
||||
hws->shifts->field_name, hws->masks->field_name
|
||||
|
||||
static void enable_memory_low_power(struct dc *dc)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
int i;
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.dmcu) {
|
||||
// Force ERAM to shutdown if DMCU is not enabled
|
||||
if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
|
||||
REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// Set default OPTC memory power states
|
||||
if (dc->debug.enable_mem_low_power.bits.optc) {
|
||||
// Shutdown when unassigned and light sleep in VBLANK
|
||||
REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
|
||||
}
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.vga) {
|
||||
// Power down VGA memory
|
||||
REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
|
||||
}
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.mpc)
|
||||
dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);
|
||||
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
|
||||
// Power down VPGs
|
||||
for (i = 0; i < dc->res_pool->stream_enc_count; i++)
|
||||
dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
|
||||
dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void dcn31_init_hw(struct dc *dc)
|
||||
{
|
||||
struct abm **abms = dc->res_pool->multiple_abms;
|
||||
|
@ -108,35 +147,7 @@ void dcn31_init_hw(struct dc *dc)
|
|||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.dmcu) {
|
||||
// Force ERAM to shutdown if DMCU is not enabled
|
||||
if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
|
||||
REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// Set default OPTC memory power states
|
||||
if (dc->debug.enable_mem_low_power.bits.optc) {
|
||||
// Shutdown when unassigned and light sleep in VBLANK
|
||||
REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
|
||||
}
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.vga) {
|
||||
// Power down VGA memory
|
||||
REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
|
||||
// Power down VPGs
|
||||
for (i = 0; i < dc->res_pool->stream_enc_count; i++)
|
||||
dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DP2_0)
|
||||
for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
|
||||
dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
enable_memory_low_power(dc);
|
||||
|
||||
if (dc->ctx->dc_bios->fw_info_valid) {
|
||||
res_pool->ref_clocks.xtalin_clock_inKhz =
|
||||
|
@ -264,6 +275,9 @@ void dcn31_init_hw(struct dc *dc)
|
|||
if (dc->debug.enable_mem_low_power.bits.i2c)
|
||||
REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
|
||||
|
||||
if (hws->funcs.setup_hpo_hw_control)
|
||||
hws->funcs.setup_hpo_hw_control(hws, false);
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
|
||||
|
@ -597,3 +611,9 @@ void dcn31_reset_hw_ctx_wrap(
|
|||
/* New dc_state in the process of being applied to hardware. */
|
||||
dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_TRANSIENT;
|
||||
}
|
||||
|
||||
void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
|
||||
{
|
||||
if (hws->ctx->dc->debug.hpo_optimization)
|
||||
REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);
|
||||
}
|
||||
|
|
|
@ -54,5 +54,6 @@ void dcn31_reset_hw_ctx_wrap(
|
|||
bool dcn31_is_abm_supported(struct dc *dc,
|
||||
struct dc_state *context, struct dc_stream_state *stream);
|
||||
void dcn31_init_pipes(struct dc *dc, struct dc_state *context);
|
||||
void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
|
||||
|
||||
#endif /* __DC_HWSS_DCN31_H__ */
|
||||
|
|
|
@ -137,6 +137,7 @@ static const struct hwseq_private_funcs dcn31_private_funcs = {
|
|||
.dccg_init = dcn20_dccg_init,
|
||||
.set_blend_lut = dcn30_set_blend_lut,
|
||||
.set_shaper_3dlut = dcn20_set_shaper_3dlut,
|
||||
.setup_hpo_hw_control = dcn31_setup_hpo_hw_control,
|
||||
};
|
||||
|
||||
void dcn31_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
@ -860,7 +860,8 @@ static const struct dccg_mask dccg_mask = {
|
|||
SR(D6VGA_CONTROL), \
|
||||
SR(DC_IP_REQUEST_CNTL), \
|
||||
SR(AZALIA_AUDIO_DTO), \
|
||||
SR(AZALIA_CONTROLLER_CLOCK_GATING)
|
||||
SR(AZALIA_CONTROLLER_CLOCK_GATING), \
|
||||
SR(HPO_TOP_HW_CONTROL)
|
||||
|
||||
static const struct dce_hwseq_registers hwseq_reg = {
|
||||
HWSEQ_DCN31_REG_LIST()
|
||||
|
@ -898,7 +899,8 @@ static const struct dce_hwseq_registers hwseq_reg = {
|
|||
HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
|
||||
HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
|
||||
HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh), \
|
||||
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
|
||||
HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh), \
|
||||
HWS_SF(, HPO_TOP_HW_CONTROL, HPO_IO_EN, mask_sh)
|
||||
|
||||
static const struct dce_hwseq_shift hwseq_shift = {
|
||||
HWSEQ_DCN31_MASK_SH_LIST(__SHIFT)
|
||||
|
|
|
@ -3576,16 +3576,9 @@ static double TruncToValidBPP(
|
|||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
} else {
|
||||
if (Output == dm_hdmi) {
|
||||
NonDSCBPP0 = 24;
|
||||
NonDSCBPP1 = 24;
|
||||
NonDSCBPP2 = 24;
|
||||
}
|
||||
else {
|
||||
NonDSCBPP0 = 16;
|
||||
NonDSCBPP1 = 20;
|
||||
NonDSCBPP2 = 24;
|
||||
}
|
||||
NonDSCBPP0 = 16;
|
||||
NonDSCBPP1 = 20;
|
||||
NonDSCBPP2 = 24;
|
||||
|
||||
if (Format == dm_n422) {
|
||||
MinDSCBPP = 7;
|
||||
|
|
|
@ -3892,15 +3892,11 @@ static double TruncToValidBPP(
|
|||
MinDSCBPP = 8;
|
||||
MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
|
||||
} else {
|
||||
if (Output == dm_hdmi) {
|
||||
NonDSCBPP0 = 24;
|
||||
NonDSCBPP1 = 24;
|
||||
NonDSCBPP2 = 24;
|
||||
} else {
|
||||
NonDSCBPP0 = 16;
|
||||
NonDSCBPP1 = 20;
|
||||
NonDSCBPP2 = 24;
|
||||
}
|
||||
|
||||
NonDSCBPP0 = 16;
|
||||
NonDSCBPP1 = 20;
|
||||
NonDSCBPP2 = 24;
|
||||
|
||||
if (Format == dm_n422) {
|
||||
MinDSCBPP = 7;
|
||||
MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
|
||||
|
|
|
@ -367,6 +367,7 @@ struct mpc_funcs {
|
|||
void (*set_bg_color)(struct mpc *mpc,
|
||||
struct tg_color *bg_color,
|
||||
int mpcc_id);
|
||||
void (*set_mpc_mem_lp_mode)(struct mpc *mpc);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -143,6 +143,7 @@ struct hwseq_private_funcs {
|
|||
const struct dc_plane_state *plane_state);
|
||||
void (*PLAT_58856_wa)(struct dc_state *context,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
|
||||
};
|
||||
|
||||
struct dce_hwseq {
|
||||
|
|
|
@ -238,6 +238,7 @@ struct dmub_srv_hw_params {
|
|||
bool load_inst_const;
|
||||
bool skip_panel_power_sequence;
|
||||
bool disable_z10;
|
||||
bool power_optimization;
|
||||
bool dpia_supported;
|
||||
bool disable_dpia;
|
||||
};
|
||||
|
|
|
@ -46,10 +46,10 @@
|
|||
|
||||
/* Firmware versioning. */
|
||||
#ifdef DMUB_EXPOSE_VERSION
|
||||
#define DMUB_FW_VERSION_GIT_HASH 0x9525efb5
|
||||
#define DMUB_FW_VERSION_GIT_HASH 0x1d82d23e
|
||||
#define DMUB_FW_VERSION_MAJOR 0
|
||||
#define DMUB_FW_VERSION_MINOR 0
|
||||
#define DMUB_FW_VERSION_REVISION 90
|
||||
#define DMUB_FW_VERSION_REVISION 91
|
||||
#define DMUB_FW_VERSION_TEST 0
|
||||
#define DMUB_FW_VERSION_VBIOS 0
|
||||
#define DMUB_FW_VERSION_HOTFIX 0
|
||||
|
|
|
@ -340,6 +340,7 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu
|
|||
boot_options.bits.z10_disable = params->disable_z10;
|
||||
boot_options.bits.dpia_supported = params->dpia_supported;
|
||||
boot_options.bits.enable_dpia = params->disable_dpia ? 0 : 1;
|
||||
boot_options.bits.power_optimization = params->power_optimization;
|
||||
|
||||
boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0;
|
||||
|
||||
|
|
|
@ -2094,6 +2094,10 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
|
|||
} else if (DEVICE_ATTR_IS(pp_dpm_dclk)) {
|
||||
if (!(asic_type == CHIP_VANGOGH || asic_type == CHIP_SIENNA_CICHLID))
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
} else if (DEVICE_ATTR_IS(pp_power_profile_mode)) {
|
||||
if (!adev->powerplay.pp_funcs->get_power_profile_mode ||
|
||||
amdgpu_dpm_get_power_profile_mode(adev, NULL) == -EOPNOTSUPP)
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
switch (asic_type) {
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#define PPSMC_MSG_PowerUpVcn 0x07 ///< Power up VCN; VCN is power gated by default
|
||||
#define PPSMC_MSG_SetHardMinVcn 0x08 ///< For wireless display
|
||||
#define PPSMC_MSG_SetSoftMinGfxclk 0x09 ///< Set SoftMin for GFXCLK, argument is frequency in MHz
|
||||
#define PPSMC_MSG_ActiveProcessNotify 0x0A ///< Set active work load type
|
||||
#define PPSMC_MSG_ActiveProcessNotify 0x0A ///< Deprecated (Not to be used)
|
||||
#define PPSMC_MSG_ForcePowerDownGfx 0x0B ///< Force power down GFX, i.e. enter GFXOFF
|
||||
#define PPSMC_MSG_PrepareMp1ForUnload 0x0C ///< Prepare PMFW for GFX driver unload
|
||||
#define PPSMC_MSG_SetDriverDramAddrHigh 0x0D ///< Set high 32 bits of DRAM address for Driver table transfer
|
||||
|
@ -63,7 +63,7 @@
|
|||
#define PPSMC_MSG_SetHardMinSocclkByFreq 0x13 ///< Set hard min for SOC CLK
|
||||
#define PPSMC_MSG_SetSoftMinFclk 0x14 ///< Set hard min for FCLK
|
||||
#define PPSMC_MSG_SetSoftMinVcn 0x15 ///< Set soft min for VCN clocks (VCLK and DCLK)
|
||||
#define PPSMC_MSG_SPARE0 0x16 ///< Spared
|
||||
#define PPSMC_MSG_SPARE 0x16 ///< Spare
|
||||
#define PPSMC_MSG_GetGfxclkFrequency 0x17 ///< Get GFX clock frequency
|
||||
#define PPSMC_MSG_GetFclkFrequency 0x18 ///< Get FCLK frequency
|
||||
#define PPSMC_MSG_AllowGfxOff 0x19 ///< Inform PMFW of allowing GFXOFF entry
|
||||
|
|
|
@ -875,34 +875,30 @@ pp_dpm_get_vce_clock_state(void *handle, unsigned idx)
|
|||
static int pp_get_power_profile_mode(void *handle, char *buf)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr = handle;
|
||||
int ret;
|
||||
|
||||
if (!hwmgr || !hwmgr->pm_en || !buf)
|
||||
if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->get_power_profile_mode)
|
||||
return -EOPNOTSUPP;
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (hwmgr->hwmgr_func->get_power_profile_mode == NULL) {
|
||||
pr_info_ratelimited("%s was not implemented.\n", __func__);
|
||||
return snprintf(buf, PAGE_SIZE, "\n");
|
||||
}
|
||||
|
||||
return hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf);
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
ret = hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf);
|
||||
mutex_unlock(&hwmgr->smu_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr = handle;
|
||||
int ret = -EINVAL;
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (!hwmgr || !hwmgr->pm_en)
|
||||
if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->set_power_profile_mode)
|
||||
return ret;
|
||||
|
||||
if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) {
|
||||
pr_info_ratelimited("%s was not implemented.\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
pr_debug("power profile setting is for manual dpm mode only.\n");
|
||||
return ret;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
|
|
|
@ -2534,13 +2534,15 @@ static int smu_get_power_profile_mode(void *handle, char *buf)
|
|||
struct smu_context *smu = handle;
|
||||
int ret = 0;
|
||||
|
||||
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
|
||||
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||
|
||||
!smu->ppt_funcs->get_power_profile_mode)
|
||||
return -EOPNOTSUPP;
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
|
||||
if (smu->ppt_funcs->get_power_profile_mode)
|
||||
ret = smu->ppt_funcs->get_power_profile_mode(smu, buf);
|
||||
ret = smu->ppt_funcs->get_power_profile_mode(smu, buf);
|
||||
|
||||
mutex_unlock(&smu->mutex);
|
||||
|
||||
|
@ -2554,7 +2556,8 @@ static int smu_set_power_profile_mode(void *handle,
|
|||
struct smu_context *smu = handle;
|
||||
int ret = 0;
|
||||
|
||||
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
|
||||
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||
|
||||
!smu->ppt_funcs->set_power_profile_mode)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
|
|
|
@ -64,7 +64,6 @@ static struct cmn2asic_msg_mapping yellow_carp_message_map[SMU_MSG_MAX_COUNT] =
|
|||
MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 1),
|
||||
MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 1),
|
||||
MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 1),
|
||||
MSG_MAP(ActiveProcessNotify, PPSMC_MSG_ActiveProcessNotify, 1),
|
||||
MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1),
|
||||
MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1),
|
||||
MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1),
|
||||
|
@ -135,14 +134,6 @@ static struct cmn2asic_mapping yellow_carp_table_map[SMU_TABLE_COUNT] = {
|
|||
TAB_MAP_VALID(CUSTOM_DPM),
|
||||
TAB_MAP_VALID(DPMCLOCKS),
|
||||
};
|
||||
|
||||
static struct cmn2asic_mapping yellow_carp_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
|
||||
};
|
||||
|
||||
static int yellow_carp_init_smc_tables(struct smu_context *smu)
|
||||
{
|
||||
|
@ -543,81 +534,6 @@ static int yellow_carp_set_watermarks_table(struct smu_context *smu,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int yellow_carp_get_power_profile_mode(struct smu_context *smu,
|
||||
char *buf)
|
||||
{
|
||||
static const char *profile_name[] = {
|
||||
"BOOTUP_DEFAULT",
|
||||
"3D_FULL_SCREEN",
|
||||
"POWER_SAVING",
|
||||
"VIDEO",
|
||||
"VR",
|
||||
"COMPUTE",
|
||||
"CUSTOM"};
|
||||
uint32_t i, size = 0;
|
||||
int16_t workload_type = 0;
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
|
||||
/*
|
||||
* Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT.
|
||||
* Not all profile modes are supported on yellow carp.
|
||||
*/
|
||||
workload_type = smu_cmn_to_asic_specific_index(smu,
|
||||
CMN2ASIC_MAPPING_WORKLOAD,
|
||||
i);
|
||||
|
||||
if (workload_type < 0)
|
||||
continue;
|
||||
|
||||
size += sysfs_emit_at(buf, size, "%2d %14s%s\n",
|
||||
i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int yellow_carp_set_power_profile_mode(struct smu_context *smu,
|
||||
long *input, uint32_t size)
|
||||
{
|
||||
int workload_type, ret;
|
||||
uint32_t profile_mode = input[size];
|
||||
|
||||
if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
|
||||
dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||
|
||||
profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)
|
||||
return 0;
|
||||
|
||||
/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
|
||||
workload_type = smu_cmn_to_asic_specific_index(smu,
|
||||
CMN2ASIC_MAPPING_WORKLOAD,
|
||||
profile_mode);
|
||||
if (workload_type < 0) {
|
||||
dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on YELLOWCARP\n",
|
||||
profile_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
|
||||
1 << workload_type,
|
||||
NULL);
|
||||
if (ret) {
|
||||
dev_err_once(smu->adev->dev, "Fail to set workload type %d\n",
|
||||
workload_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
smu->power_profile_mode = profile_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t yellow_carp_get_gpu_metrics(struct smu_context *smu,
|
||||
void **table)
|
||||
{
|
||||
|
@ -1238,8 +1154,6 @@ static const struct pptable_funcs yellow_carp_ppt_funcs = {
|
|||
.read_sensor = yellow_carp_read_sensor,
|
||||
.is_dpm_running = yellow_carp_is_dpm_running,
|
||||
.set_watermarks_table = yellow_carp_set_watermarks_table,
|
||||
.get_power_profile_mode = yellow_carp_get_power_profile_mode,
|
||||
.set_power_profile_mode = yellow_carp_set_power_profile_mode,
|
||||
.get_gpu_metrics = yellow_carp_get_gpu_metrics,
|
||||
.get_enabled_mask = smu_cmn_get_enabled_32_bits_mask,
|
||||
.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
|
||||
|
@ -1261,6 +1175,5 @@ void yellow_carp_set_ppt_funcs(struct smu_context *smu)
|
|||
smu->message_map = yellow_carp_message_map;
|
||||
smu->feature_map = yellow_carp_feature_mask_map;
|
||||
smu->table_map = yellow_carp_table_map;
|
||||
smu->workload_map = yellow_carp_workload_map;
|
||||
smu->is_apu = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue