mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
amd-drm-next-6.12-2024-09-06:
amdgpu: - IPS updates - Post divider fix - DML2 updates - Misc static checker fixes - DCN 3.5 fixes - Replay fixes - DMCUB updates - SWSMU fixes - DP MST fixes - Add debug flag for per queue resets - devcoredump updates - SR-IOV fixes - MES fixes - Always allocate cleared VRAM for GEM - Pipe reset for GC 9.4.3 - ODM policy fixes - Per queue reset support for GC 10 - Per queue reset support for GC 11 - Per queue reset support for GC 12 - Display flickering fixes - MPO fixes - Display sharpening updates amdkfd: - SVM fix for IH for APUs -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZttuyQAKCRC93/aFa7yZ 2M+ZAP0SLph+CJPIcGGF5vMjA7a0ytjDOus9XcTzNYwtJ9cUjwEAve4X1AIbsEIp 2Hl3NaqyOtCn9yX011vebztJsNvnGAc= =gUTi -----END PGP SIGNATURE----- Merge tag 'amd-drm-next-6.12-2024-09-06' of https://gitlab.freedesktop.org/agd5f/linux into drm-next amd-drm-next-6.12-2024-09-06: amdgpu: - IPS updates - Post divider fix - DML2 updates - Misc static checker fixes - DCN 3.5 fixes - Replay fixes - DMCUB updates - SWSMU fixes - DP MST fixes - Add debug flag for per queue resets - devcoredump updates - SR-IOV fixes - MES fixes - Always allocate cleared VRAM for GEM - Pipe reset for GC 9.4.3 - ODM policy fixes - Per queue reset support for GC 10 - Per queue reset support for GC 11 - Per queue reset support for GC 12 - Display flickering fixes - MPO fixes - Display sharpening updates amdkfd: - SVM fix for IH for APUs Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906211008.3072097-1-alexander.deucher@amd.com
This commit is contained in:
commit
741d73f587
@ -179,4 +179,4 @@ IP Blocks
|
||||
:doc: IP Blocks
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/include/amd_shared.h
|
||||
:identifiers: amd_ip_block_type amd_ip_funcs
|
||||
:identifiers: amd_ip_block_type amd_ip_funcs DC_DEBUG_MASK
|
||||
|
@ -1164,6 +1164,7 @@ struct amdgpu_device {
|
||||
bool debug_disable_soft_recovery;
|
||||
bool debug_use_vram_fw_buf;
|
||||
bool debug_enable_ras_aca;
|
||||
bool debug_exp_resets;
|
||||
|
||||
bool enforce_isolation[MAX_XCP];
|
||||
/* Added this mutex for cleaner shader isolation between GFX and compute processes */
|
||||
|
@ -1151,6 +1151,10 @@ uint64_t kgd_gfx_v9_hqd_get_pq_addr(struct amdgpu_device *adev,
|
||||
uint32_t low, high;
|
||||
uint64_t queue_addr = 0;
|
||||
|
||||
if (!adev->debug_exp_resets &&
|
||||
!adev->gfx.num_gfx_rings)
|
||||
return 0;
|
||||
|
||||
kgd_gfx_v9_acquire_queue(adev, pipe_id, queue_id, inst);
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, inst);
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
||||
#include "atom.h"
|
||||
|
||||
#ifndef CONFIG_DEV_COREDUMP
|
||||
void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
|
||||
bool vram_lost, struct amdgpu_job *job)
|
||||
{
|
||||
}
|
||||
#else
|
||||
@ -315,7 +315,9 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
|
||||
}
|
||||
}
|
||||
|
||||
if (coredump->reset_vram_lost)
|
||||
if (coredump->skip_vram_check)
|
||||
drm_printf(&p, "VRAM lost check is skipped!\n");
|
||||
else if (coredump->reset_vram_lost)
|
||||
drm_printf(&p, "VRAM is lost due to GPU reset!\n");
|
||||
|
||||
return count - iter.remain;
|
||||
@ -326,12 +328,11 @@ static void amdgpu_devcoredump_free(void *data)
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
|
||||
bool vram_lost, struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_coredump_info *coredump;
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct amdgpu_job *job = reset_context->job;
|
||||
struct amdgpu_coredump_info *coredump;
|
||||
struct drm_sched_job *s_job;
|
||||
|
||||
coredump = kzalloc(sizeof(*coredump), GFP_NOWAIT);
|
||||
@ -341,11 +342,12 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost,
|
||||
return;
|
||||
}
|
||||
|
||||
coredump->skip_vram_check = skip_vram_check;
|
||||
coredump->reset_vram_lost = vram_lost;
|
||||
|
||||
if (reset_context->job && reset_context->job->vm) {
|
||||
if (job && job->vm) {
|
||||
struct amdgpu_vm *vm = job->vm;
|
||||
struct amdgpu_task_info *ti;
|
||||
struct amdgpu_vm *vm = reset_context->job->vm;
|
||||
|
||||
ti = amdgpu_vm_get_task_info_vm(vm);
|
||||
if (ti) {
|
||||
|
@ -26,7 +26,6 @@
|
||||
#define __AMDGPU_DEV_COREDUMP_H__
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
|
||||
@ -36,12 +35,12 @@ struct amdgpu_coredump_info {
|
||||
struct amdgpu_device *adev;
|
||||
struct amdgpu_task_info reset_task_info;
|
||||
struct timespec64 reset_time;
|
||||
bool skip_vram_check;
|
||||
bool reset_vram_lost;
|
||||
struct amdgpu_ring *ring;
|
||||
};
|
||||
#endif
|
||||
|
||||
void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost,
|
||||
struct amdgpu_reset_context *reset_context);
|
||||
|
||||
void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
|
||||
bool vram_lost, struct amdgpu_job *job);
|
||||
#endif
|
||||
|
@ -4531,6 +4531,9 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
||||
{
|
||||
dev_info(adev->dev, "amdgpu: finishing device.\n");
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
if (adev->mman.initialized)
|
||||
drain_workqueue(adev->mman.bdev.wq);
|
||||
adev->shutdown = true;
|
||||
|
||||
/* make sure IB test finished before entering exclusive mode
|
||||
@ -4551,9 +4554,6 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
||||
}
|
||||
amdgpu_fence_driver_hw_fini(adev);
|
||||
|
||||
if (adev->mman.initialized)
|
||||
drain_workqueue(adev->mman.bdev.wq);
|
||||
|
||||
if (adev->pm.sysfs_initialized)
|
||||
amdgpu_pm_sysfs_fini(adev);
|
||||
if (adev->ucode_sysfs_en)
|
||||
@ -5489,7 +5489,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
vram_lost = amdgpu_device_check_vram_lost(tmp_adev);
|
||||
|
||||
if (!test_bit(AMDGPU_SKIP_COREDUMP, &reset_context->flags))
|
||||
amdgpu_coredump(tmp_adev, vram_lost, reset_context);
|
||||
amdgpu_coredump(tmp_adev, false, vram_lost, reset_context->job);
|
||||
|
||||
if (vram_lost) {
|
||||
DRM_INFO("VRAM is lost due to GPU reset!\n");
|
||||
|
@ -131,6 +131,7 @@ enum AMDGPU_DEBUG_MASK {
|
||||
AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY = BIT(2),
|
||||
AMDGPU_DEBUG_USE_VRAM_FW_BUF = BIT(3),
|
||||
AMDGPU_DEBUG_ENABLE_RAS_ACA = BIT(4),
|
||||
AMDGPU_DEBUG_ENABLE_EXP_RESETS = BIT(5),
|
||||
};
|
||||
|
||||
unsigned int amdgpu_vram_limit = UINT_MAX;
|
||||
@ -2199,6 +2200,11 @@ static void amdgpu_init_debug_options(struct amdgpu_device *adev)
|
||||
pr_info("debug: enable RAS ACA\n");
|
||||
adev->debug_enable_ras_aca = true;
|
||||
}
|
||||
|
||||
if (amdgpu_debug_mask & AMDGPU_DEBUG_ENABLE_EXP_RESETS) {
|
||||
pr_info("debug: enable experimental reset features\n");
|
||||
adev->debug_exp_resets = true;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned long flags)
|
||||
|
@ -348,6 +348,9 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* always clear VRAM */
|
||||
flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED;
|
||||
|
||||
/* create a gem object to contain this object in */
|
||||
if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
|
||||
AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
|
||||
|
@ -660,7 +660,7 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev, int xcc_id)
|
||||
uint64_t queue_mask = 0;
|
||||
int r, i, j;
|
||||
|
||||
if (adev->enable_mes)
|
||||
if (adev->mes.enable_legacy_queue_map)
|
||||
return amdgpu_gfx_mes_enable_kcq(adev, xcc_id);
|
||||
|
||||
if (!kiq->pmf || !kiq->pmf->kiq_map_queues || !kiq->pmf->kiq_set_resources)
|
||||
@ -722,7 +722,7 @@ int amdgpu_gfx_enable_kgq(struct amdgpu_device *adev, int xcc_id)
|
||||
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
|
||||
if (adev->enable_mes) {
|
||||
if (adev->mes.enable_legacy_queue_map) {
|
||||
for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
|
||||
j = i + xcc_id * adev->gfx.num_gfx_rings;
|
||||
r = amdgpu_mes_map_legacy_queue(adev,
|
||||
|
@ -30,6 +30,60 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_trace.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_dev_coredump.h"
|
||||
#include "amdgpu_xgmi.h"
|
||||
|
||||
static void amdgpu_job_do_core_dump(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
int i;
|
||||
|
||||
dev_info(adev->dev, "Dumping IP State\n");
|
||||
for (i = 0; i < adev->num_ip_blocks; i++)
|
||||
if (adev->ip_blocks[i].version->funcs->dump_ip_state)
|
||||
adev->ip_blocks[i].version->funcs
|
||||
->dump_ip_state((void *)adev);
|
||||
dev_info(adev->dev, "Dumping IP State Completed\n");
|
||||
|
||||
amdgpu_coredump(adev, true, false, job);
|
||||
}
|
||||
|
||||
static void amdgpu_job_core_dump(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct list_head device_list, *device_list_handle = NULL;
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
struct amdgpu_hive_info *hive = NULL;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive)
|
||||
mutex_lock(&hive->hive_lock);
|
||||
/*
|
||||
* Reuse the logic in amdgpu_device_gpu_recover() to build list of
|
||||
* devices for code dump
|
||||
*/
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1) && hive) {
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
if (!list_is_first(&adev->reset_list, &device_list))
|
||||
list_rotate_to_front(&adev->reset_list, &device_list);
|
||||
device_list_handle = &device_list;
|
||||
} else {
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
device_list_handle = &device_list;
|
||||
}
|
||||
|
||||
/* Do the coredump for each device */
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list)
|
||||
amdgpu_job_do_core_dump(tmp_adev, job);
|
||||
|
||||
if (hive) {
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
}
|
||||
}
|
||||
|
||||
static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
||||
{
|
||||
@ -48,9 +102,14 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
||||
return DRM_GPU_SCHED_STAT_ENODEV;
|
||||
}
|
||||
|
||||
|
||||
adev->job_hang = true;
|
||||
|
||||
/*
|
||||
* Do the coredump immediately after a job timeout to get a very
|
||||
* close dump/snapshot/representation of GPU's current error status
|
||||
*/
|
||||
amdgpu_job_core_dump(adev, job);
|
||||
|
||||
if (amdgpu_gpu_recovery &&
|
||||
amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) {
|
||||
dev_err(adev->dev, "ring %s timeout, but soft recovered\n",
|
||||
@ -101,6 +160,12 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
||||
reset_context.src = AMDGPU_RESET_SRC_JOB;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
|
||||
/*
|
||||
* To avoid an unnecessary extra coredump, as we have already
|
||||
* got the very close representation of GPU's error status
|
||||
*/
|
||||
set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);
|
||||
|
||||
r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context);
|
||||
if (r)
|
||||
dev_err(adev->dev, "GPU Recovery Failed: %d\n", r);
|
||||
|
@ -826,6 +826,24 @@ int amdgpu_mes_reset_hw_queue(struct amdgpu_device *adev, int queue_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_mes_reset_hw_queue_mmio(struct amdgpu_device *adev, int queue_type,
|
||||
int me_id, int pipe_id, int queue_id, int vmid)
|
||||
{
|
||||
struct mes_reset_queue_input queue_input;
|
||||
int r;
|
||||
|
||||
queue_input.use_mmio = true;
|
||||
queue_input.me_id = me_id;
|
||||
queue_input.pipe_id = pipe_id;
|
||||
queue_input.queue_id = queue_id;
|
||||
queue_input.vmid = vmid;
|
||||
r = adev->mes.funcs->reset_hw_queue(&adev->mes, &queue_input);
|
||||
if (r)
|
||||
DRM_ERROR("failed to reset hardware queue by mmio, queue id = %d\n",
|
||||
queue_id);
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring)
|
||||
{
|
||||
@ -873,7 +891,8 @@ int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
|
||||
|
||||
int amdgpu_mes_reset_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring,
|
||||
unsigned int vmid)
|
||||
unsigned int vmid,
|
||||
bool use_mmio)
|
||||
{
|
||||
struct mes_reset_legacy_queue_input queue_input;
|
||||
int r;
|
||||
@ -882,11 +901,13 @@ int amdgpu_mes_reset_legacy_queue(struct amdgpu_device *adev,
|
||||
|
||||
queue_input.queue_type = ring->funcs->type;
|
||||
queue_input.doorbell_offset = ring->doorbell_index;
|
||||
queue_input.me_id = ring->me;
|
||||
queue_input.pipe_id = ring->pipe;
|
||||
queue_input.queue_id = ring->queue;
|
||||
queue_input.mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj);
|
||||
queue_input.wptr_addr = ring->wptr_gpu_addr;
|
||||
queue_input.vmid = vmid;
|
||||
queue_input.use_mmio = use_mmio;
|
||||
|
||||
r = adev->mes.funcs->reset_legacy_queue(&adev->mes, &queue_input);
|
||||
if (r)
|
||||
|
@ -75,6 +75,7 @@ struct amdgpu_mes {
|
||||
|
||||
uint32_t sched_version;
|
||||
uint32_t kiq_version;
|
||||
bool enable_legacy_queue_map;
|
||||
|
||||
uint32_t total_max_queue;
|
||||
uint32_t max_doorbell_slices;
|
||||
@ -251,6 +252,13 @@ struct mes_remove_queue_input {
|
||||
struct mes_reset_queue_input {
|
||||
uint32_t doorbell_offset;
|
||||
uint64_t gang_context_addr;
|
||||
bool use_mmio;
|
||||
uint32_t queue_type;
|
||||
uint32_t me_id;
|
||||
uint32_t pipe_id;
|
||||
uint32_t queue_id;
|
||||
uint32_t xcc_id;
|
||||
uint32_t vmid;
|
||||
};
|
||||
|
||||
struct mes_map_legacy_queue_input {
|
||||
@ -287,6 +295,8 @@ struct mes_resume_gang_input {
|
||||
struct mes_reset_legacy_queue_input {
|
||||
uint32_t queue_type;
|
||||
uint32_t doorbell_offset;
|
||||
bool use_mmio;
|
||||
uint32_t me_id;
|
||||
uint32_t pipe_id;
|
||||
uint32_t queue_id;
|
||||
uint64_t mqd_addr;
|
||||
@ -396,6 +406,8 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
|
||||
int *queue_id);
|
||||
int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id);
|
||||
int amdgpu_mes_reset_hw_queue(struct amdgpu_device *adev, int queue_id);
|
||||
int amdgpu_mes_reset_hw_queue_mmio(struct amdgpu_device *adev, int queue_type,
|
||||
int me_id, int pipe_id, int queue_id, int vmid);
|
||||
|
||||
int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring);
|
||||
@ -405,7 +417,8 @@ int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
|
||||
u64 gpu_addr, u64 seq);
|
||||
int amdgpu_mes_reset_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring,
|
||||
unsigned int vmid);
|
||||
unsigned int vmid,
|
||||
bool use_mmio);
|
||||
|
||||
uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg);
|
||||
int amdgpu_mes_wreg(struct amdgpu_device *adev,
|
||||
|
@ -6692,13 +6692,13 @@ static int gfx_v10_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v10_0_gfx_init_queue(struct amdgpu_ring *ring)
|
||||
static int gfx_v10_0_kgq_init_queue(struct amdgpu_ring *ring, bool reset)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct v10_gfx_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.gfx_ring[0];
|
||||
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
if (!reset && !amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
nv_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
@ -6750,7 +6750,7 @@ static int gfx_v10_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
|
||||
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v10_0_gfx_init_queue(ring);
|
||||
r = gfx_v10_0_kgq_init_queue(ring, false);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
@ -7030,13 +7030,13 @@ static int gfx_v10_0_kiq_init_queue(struct amdgpu_ring *ring)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v10_0_kcq_init_queue(struct amdgpu_ring *ring)
|
||||
static int gfx_v10_0_kcq_init_queue(struct amdgpu_ring *ring, bool restore)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct v10_compute_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.compute_ring[0];
|
||||
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
if (!restore && !amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
nv_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
@ -7098,7 +7098,7 @@ static int gfx_v10_0_kcq_resume(struct amdgpu_device *adev)
|
||||
goto done;
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v10_0_kcq_init_queue(ring);
|
||||
r = gfx_v10_0_kcq_init_queue(ring, false);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
@ -8949,7 +8949,9 @@ static void gfx_v10_0_ring_soft_recovery(struct amdgpu_ring *ring,
|
||||
value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
WREG32_SOC15(GC, 0, mmSQ_CMD, value);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -9416,6 +9418,156 @@ static void gfx_v10_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
|
||||
amdgpu_ring_write(ring, ring->funcs->nop);
|
||||
}
|
||||
|
||||
static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_ring *kiq_ring = &kiq->ring;
|
||||
unsigned long flags;
|
||||
u32 tmp;
|
||||
u64 addr;
|
||||
int r;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
|
||||
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
|
||||
if (amdgpu_ring_alloc(kiq_ring, 5 + 7 + 7 + kiq->pmf->map_queues_size)) {
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
addr = amdgpu_bo_gpu_offset(ring->mqd_obj) +
|
||||
offsetof(struct v10_gfx_mqd, cp_gfx_hqd_active);
|
||||
tmp = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
|
||||
if (ring->pipe == 0)
|
||||
tmp = REG_SET_FIELD(tmp, CP_VMID_RESET, PIPE0_QUEUES, 1 << ring->queue);
|
||||
else
|
||||
tmp = REG_SET_FIELD(tmp, CP_VMID_RESET, PIPE1_QUEUES, 1 << ring->queue);
|
||||
|
||||
gfx_v10_0_ring_emit_wreg(kiq_ring,
|
||||
SOC15_REG_OFFSET(GC, 0, mmCP_VMID_RESET), tmp);
|
||||
gfx_v10_0_wait_reg_mem(kiq_ring, 0, 1, 0,
|
||||
lower_32_bits(addr), upper_32_bits(addr),
|
||||
0, 1, 0x20);
|
||||
gfx_v10_0_ring_emit_reg_wait(kiq_ring,
|
||||
SOC15_REG_OFFSET(GC, 0, mmCP_VMID_RESET), 0, 0xffffffff);
|
||||
kiq->pmf->kiq_map_queues(kiq_ring, ring);
|
||||
amdgpu_ring_commit(kiq_ring);
|
||||
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
r = amdgpu_ring_test_ring(kiq_ring);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_bo_reserve(ring->mqd_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("fail to resv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v10_0_kgq_init_queue(ring, true);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
amdgpu_bo_unreserve(ring->mqd_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("fail to unresv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_ring_test_ring(ring);
|
||||
}
|
||||
|
||||
static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
|
||||
unsigned int vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_ring *kiq_ring = &kiq->ring;
|
||||
unsigned long flags;
|
||||
int i, r;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
|
||||
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
|
||||
if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) {
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
kiq->pmf->kiq_unmap_queues(kiq_ring, ring, RESET_QUEUES,
|
||||
0, 0);
|
||||
amdgpu_ring_commit(kiq_ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
r = amdgpu_ring_test_ring(kiq_ring);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* make sure dequeue is complete*/
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
nv_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout)
|
||||
r = -ETIMEDOUT;
|
||||
nv_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to wait on hqd deactivate\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_bo_reserve(ring->mqd_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
dev_err(adev->dev, "fail to resv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v10_0_kcq_init_queue(ring, true);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
amdgpu_bo_unreserve(ring->mqd_obj);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to unresv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->map_queues_size)) {
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
kiq->pmf->kiq_map_queues(kiq_ring, ring);
|
||||
amdgpu_ring_commit(kiq_ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
r = amdgpu_ring_test_ring(kiq_ring);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return amdgpu_ring_test_ring(ring);
|
||||
}
|
||||
|
||||
static void gfx_v10_ip_print(void *handle, struct drm_printer *p)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
@ -9619,6 +9771,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
|
||||
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
|
||||
.soft_recovery = gfx_v10_0_ring_soft_recovery,
|
||||
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
|
||||
.reset = gfx_v10_0_reset_kgq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
|
||||
@ -9655,6 +9808,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
|
||||
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
|
||||
.soft_recovery = gfx_v10_0_ring_soft_recovery,
|
||||
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
|
||||
.reset = gfx_v10_0_reset_kcq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_kiq = {
|
||||
|
@ -3984,13 +3984,13 @@ static int gfx_v11_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v11_0_gfx_init_queue(struct amdgpu_ring *ring)
|
||||
static int gfx_v11_0_kgq_init_queue(struct amdgpu_ring *ring, bool reset)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct v11_gfx_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.gfx_ring[0];
|
||||
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
if (!reset && !amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc21_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
@ -4026,7 +4026,7 @@ static int gfx_v11_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
|
||||
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v11_0_gfx_init_queue(ring);
|
||||
r = gfx_v11_0_kgq_init_queue(ring, false);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
@ -4321,13 +4321,13 @@ static int gfx_v11_0_kiq_init_queue(struct amdgpu_ring *ring)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v11_0_kcq_init_queue(struct amdgpu_ring *ring)
|
||||
static int gfx_v11_0_kcq_init_queue(struct amdgpu_ring *ring, bool reset)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct v11_compute_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.compute_ring[0];
|
||||
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
if (!reset && !amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc21_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
@ -4391,7 +4391,7 @@ static int gfx_v11_0_kcq_resume(struct amdgpu_device *adev)
|
||||
goto done;
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v11_0_kcq_init_queue(ring);
|
||||
r = gfx_v11_0_kcq_init_queue(ring, false);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
@ -4781,7 +4781,7 @@ static int gfx_v11_0_soft_reset(void *handle)
|
||||
int r, i, j, k;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
gfx_v11_0_set_safe_mode(adev, 0);
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, regCP_INT_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_INT_CNTL, CMP_BUSY_INT_ENABLE, 0);
|
||||
@ -4900,7 +4900,7 @@ static int gfx_v11_0_soft_reset(void *handle)
|
||||
tmp = REG_SET_FIELD(tmp, CP_INT_CNTL, GFX_IDLE_INT_ENABLE, 1);
|
||||
WREG32_SOC15(GC, 0, regCP_INT_CNTL, tmp);
|
||||
|
||||
gfx_v11_0_unset_safe_mode(adev, 0);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
|
||||
return gfx_v11_0_cp_resume(adev);
|
||||
}
|
||||
@ -5923,6 +5923,9 @@ static int gfx_v11_0_ring_preempt_ib(struct amdgpu_ring *ring)
|
||||
struct amdgpu_ring *kiq_ring = &kiq->ring;
|
||||
unsigned long flags;
|
||||
|
||||
if (adev->enable_mes)
|
||||
return -EINVAL;
|
||||
|
||||
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
|
||||
return -EINVAL;
|
||||
|
||||
@ -6088,7 +6091,9 @@ static void gfx_v11_0_ring_soft_recovery(struct amdgpu_ring *ring,
|
||||
value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
WREG32_SOC15(GC, 0, regSQ_CMD, value);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6541,6 +6546,99 @@ static void gfx_v11_0_emit_mem_sync(struct amdgpu_ring *ring)
|
||||
amdgpu_ring_write(ring, gcr_cntl); /* GCR_CNTL */
|
||||
}
|
||||
|
||||
static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
int r;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
|
||||
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_bo_reserve(ring->mqd_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
dev_err(adev->dev, "fail to resv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v11_0_kgq_init_queue(ring, true);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
amdgpu_bo_unreserve(ring->mqd_obj);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to unresv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_mes_map_legacy_queue(adev, ring);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to remap kgq\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_ring_test_ring(ring);
|
||||
}
|
||||
|
||||
static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
int i, r = 0;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc21_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 0x2);
|
||||
WREG32_SOC15(GC, 0, regSPI_COMPUTE_QUEUE_RESET, 0x1);
|
||||
|
||||
/* make sure dequeue is complete*/
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout)
|
||||
r = -ETIMEDOUT;
|
||||
soc21_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to wait on hqd deactivate\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_bo_reserve(ring->mqd_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
dev_err(adev->dev, "fail to resv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v11_0_kcq_init_queue(ring, true);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
amdgpu_bo_unreserve(ring->mqd_obj);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to unresv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_mes_map_legacy_queue(adev, ring);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to remap kcq\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_ring_test_ring(ring);
|
||||
}
|
||||
|
||||
static void gfx_v11_ip_print(void *handle, struct drm_printer *p)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
@ -6742,6 +6840,7 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
|
||||
.emit_reg_write_reg_wait = gfx_v11_0_ring_emit_reg_write_reg_wait,
|
||||
.soft_recovery = gfx_v11_0_ring_soft_recovery,
|
||||
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
|
||||
.reset = gfx_v11_0_reset_kgq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
|
||||
@ -6779,6 +6878,7 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
|
||||
.emit_reg_write_reg_wait = gfx_v11_0_ring_emit_reg_write_reg_wait,
|
||||
.soft_recovery = gfx_v11_0_ring_soft_recovery,
|
||||
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
|
||||
.reset = gfx_v11_0_reset_kcq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_kiq = {
|
||||
|
@ -2916,13 +2916,13 @@ static int gfx_v12_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v12_0_gfx_init_queue(struct amdgpu_ring *ring)
|
||||
static int gfx_v12_0_kgq_init_queue(struct amdgpu_ring *ring, bool reset)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct v12_gfx_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.gfx_ring[0];
|
||||
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
if (!reset && !amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc24_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
@ -2958,7 +2958,7 @@ static int gfx_v12_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
|
||||
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v12_0_gfx_init_queue(ring);
|
||||
r = gfx_v12_0_kgq_init_queue(ring, false);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
@ -3262,13 +3262,13 @@ static int gfx_v12_0_kiq_init_queue(struct amdgpu_ring *ring)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v12_0_kcq_init_queue(struct amdgpu_ring *ring)
|
||||
static int gfx_v12_0_kcq_init_queue(struct amdgpu_ring *ring, bool reset)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct v12_compute_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.compute_ring[0];
|
||||
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
if (!reset && !amdgpu_in_reset(adev) && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc24_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
@ -3332,7 +3332,7 @@ static int gfx_v12_0_kcq_resume(struct amdgpu_device *adev)
|
||||
goto done;
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v12_0_kcq_init_queue(ring);
|
||||
r = gfx_v12_0_kcq_init_queue(ring, false);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
@ -4501,6 +4501,9 @@ static int gfx_v12_0_ring_preempt_ib(struct amdgpu_ring *ring)
|
||||
struct amdgpu_ring *kiq_ring = &kiq->ring;
|
||||
unsigned long flags;
|
||||
|
||||
if (adev->enable_mes)
|
||||
return -EINVAL;
|
||||
|
||||
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
|
||||
return -EINVAL;
|
||||
|
||||
@ -4617,7 +4620,9 @@ static void gfx_v12_0_ring_soft_recovery(struct amdgpu_ring *ring,
|
||||
value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
WREG32_SOC15(GC, 0, regSQ_CMD, value);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5155,6 +5160,93 @@ static void gfx_v12_ip_dump(void *handle)
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
}
|
||||
|
||||
static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
int r;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
|
||||
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "reset via MES failed %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_bo_reserve(ring->mqd_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
dev_err(adev->dev, "fail to resv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v12_0_kgq_init_queue(ring, true);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
amdgpu_bo_unreserve(ring->mqd_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("fail to unresv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_mes_map_legacy_queue(adev, ring);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to remap kgq\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_ring_test_ring(ring);
|
||||
}
|
||||
|
||||
static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
int r, i;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc24_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 0x2);
|
||||
WREG32_SOC15(GC, 0, regSPI_COMPUTE_QUEUE_RESET, 0x1);
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
soc24_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
|
||||
r = amdgpu_bo_reserve(ring->mqd_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("fail to resv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
|
||||
if (!r) {
|
||||
r = gfx_v12_0_kcq_init_queue(ring, true);
|
||||
amdgpu_bo_kunmap(ring->mqd_obj);
|
||||
ring->mqd_ptr = NULL;
|
||||
}
|
||||
amdgpu_bo_unreserve(ring->mqd_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("fail to unresv mqd_obj\n");
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_mes_map_legacy_queue(adev, ring);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to remap kcq\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_ring_test_ring(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs gfx_v12_0_ip_funcs = {
|
||||
.name = "gfx_v12_0",
|
||||
.early_init = gfx_v12_0_early_init,
|
||||
@ -5217,6 +5309,7 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_gfx = {
|
||||
.emit_reg_write_reg_wait = gfx_v12_0_ring_emit_reg_write_reg_wait,
|
||||
.soft_recovery = gfx_v12_0_ring_soft_recovery,
|
||||
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
|
||||
.reset = gfx_v12_0_reset_kgq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
|
||||
@ -5251,6 +5344,7 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
|
||||
.emit_reg_write_reg_wait = gfx_v12_0_ring_emit_reg_write_reg_wait,
|
||||
.soft_recovery = gfx_v12_0_ring_soft_recovery,
|
||||
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
|
||||
.reset = gfx_v12_0_reset_kcq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_kiq = {
|
||||
|
@ -7233,6 +7233,10 @@ static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
|
||||
unsigned long flags;
|
||||
int i, r;
|
||||
|
||||
if (!adev->debug_exp_resets &&
|
||||
!adev->gfx.num_gfx_rings)
|
||||
return -EINVAL;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -3052,6 +3052,9 @@ static void gfx_v9_4_3_ring_soft_recovery(struct amdgpu_ring *ring,
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
uint32_t value = 0;
|
||||
|
||||
if (!adev->debug_exp_resets)
|
||||
return;
|
||||
|
||||
value = REG_SET_FIELD(value, SQ_CMD, CMD, 0x03);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
|
||||
@ -3466,6 +3469,98 @@ static void gfx_v9_4_3_emit_wave_limit(struct amdgpu_ring *ring, bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
static int gfx_v9_4_3_unmap_done(struct amdgpu_device *adev, uint32_t me,
|
||||
uint32_t pipe, uint32_t queue,
|
||||
uint32_t xcc_id)
|
||||
{
|
||||
int i, r;
|
||||
/* make sure dequeue is complete*/
|
||||
gfx_v9_4_3_xcc_set_safe_mode(adev, xcc_id);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc15_grbm_select(adev, me, pipe, queue, 0, GET_INST(GC, xcc_id));
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout)
|
||||
r = -ETIMEDOUT;
|
||||
else
|
||||
r = 0;
|
||||
soc15_grbm_select(adev, 0, 0, 0, 0, GET_INST(GC, xcc_id));
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
gfx_v9_4_3_xcc_unset_safe_mode(adev, xcc_id);
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
static bool gfx_v9_4_3_pipe_reset_support(struct amdgpu_device *adev)
|
||||
{
|
||||
/*TODO: Need check gfx9.4.4 mec fw whether supports pipe reset as well.*/
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) &&
|
||||
adev->gfx.mec_fw_version >= 0x0000009b)
|
||||
return true;
|
||||
else
|
||||
dev_warn_once(adev->dev, "Please use the latest MEC version to see whether support pipe reset\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int gfx_v9_4_3_reset_hw_pipe(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
uint32_t reset_pipe, clean_pipe;
|
||||
int r;
|
||||
|
||||
if (!gfx_v9_4_3_pipe_reset_support(adev))
|
||||
return -EINVAL;
|
||||
|
||||
gfx_v9_4_3_xcc_set_safe_mode(adev, ring->xcc_id);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
|
||||
reset_pipe = RREG32_SOC15(GC, GET_INST(GC, ring->xcc_id), regCP_MEC_CNTL);
|
||||
clean_pipe = reset_pipe;
|
||||
|
||||
if (ring->me == 1) {
|
||||
switch (ring->pipe) {
|
||||
case 0:
|
||||
reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL,
|
||||
MEC_ME1_PIPE0_RESET, 1);
|
||||
break;
|
||||
case 1:
|
||||
reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL,
|
||||
MEC_ME1_PIPE1_RESET, 1);
|
||||
break;
|
||||
case 2:
|
||||
reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL,
|
||||
MEC_ME1_PIPE2_RESET, 1);
|
||||
break;
|
||||
case 3:
|
||||
reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL,
|
||||
MEC_ME1_PIPE3_RESET, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (ring->pipe)
|
||||
reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL,
|
||||
MEC_ME2_PIPE1_RESET, 1);
|
||||
else
|
||||
reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL,
|
||||
MEC_ME2_PIPE0_RESET, 1);
|
||||
}
|
||||
|
||||
WREG32_SOC15(GC, GET_INST(GC, ring->xcc_id), regCP_MEC_CNTL, reset_pipe);
|
||||
WREG32_SOC15(GC, GET_INST(GC, ring->xcc_id), regCP_MEC_CNTL, clean_pipe);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
gfx_v9_4_3_xcc_unset_safe_mode(adev, ring->xcc_id);
|
||||
|
||||
r = gfx_v9_4_3_unmap_done(adev, ring->me, ring->pipe, ring->queue, ring->xcc_id);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
|
||||
unsigned int vmid)
|
||||
{
|
||||
@ -3473,7 +3568,10 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[ring->xcc_id];
|
||||
struct amdgpu_ring *kiq_ring = &kiq->ring;
|
||||
unsigned long flags;
|
||||
int r, i;
|
||||
int r;
|
||||
|
||||
if (!adev->debug_exp_resets)
|
||||
return -EINVAL;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return -EINVAL;
|
||||
@ -3495,26 +3593,23 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
r = amdgpu_ring_test_ring(kiq_ring);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* make sure dequeue is complete*/
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, ring->xcc_id);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc15_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0, GET_INST(GC, ring->xcc_id));
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout)
|
||||
r = -ETIMEDOUT;
|
||||
soc15_grbm_select(adev, 0, 0, 0, 0, GET_INST(GC, ring->xcc_id));
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, ring->xcc_id);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to wait on hqd deactive\n");
|
||||
return r;
|
||||
dev_err(adev->dev, "kiq ring test failed after ring: %s queue reset\n",
|
||||
ring->name);
|
||||
goto pipe_reset;
|
||||
}
|
||||
|
||||
r = gfx_v9_4_3_unmap_done(adev, ring->me, ring->pipe, ring->queue, ring->xcc_id);
|
||||
if (r)
|
||||
dev_err(adev->dev, "fail to wait on hqd deactive and will try pipe reset\n");
|
||||
|
||||
pipe_reset:
|
||||
if(r) {
|
||||
r = gfx_v9_4_3_reset_hw_pipe(ring);
|
||||
dev_info(adev->dev, "ring: %s pipe reset :%s\n", ring->name,
|
||||
r ? "failed" : "successfully");
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_bo_reserve(ring->mqd_obj, false);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "amdgpu.h"
|
||||
#include "soc15_common.h"
|
||||
#include "soc21.h"
|
||||
#include "gfx_v11_0.h"
|
||||
#include "gc/gc_11_0_0_offset.h"
|
||||
#include "gc/gc_11_0_0_sh_mask.h"
|
||||
#include "gc/gc_11_0_0_default.h"
|
||||
@ -360,9 +361,83 @@ static int mes_v11_0_remove_hw_queue(struct amdgpu_mes *mes,
|
||||
offsetof(union MESAPI__REMOVE_QUEUE, api_status));
|
||||
}
|
||||
|
||||
static int mes_v11_0_reset_queue_mmio(struct amdgpu_mes *mes, uint32_t queue_type,
|
||||
uint32_t me_id, uint32_t pipe_id,
|
||||
uint32_t queue_id, uint32_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = mes->adev;
|
||||
uint32_t value;
|
||||
int i, r = 0;
|
||||
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
|
||||
if (queue_type == AMDGPU_RING_TYPE_GFX) {
|
||||
dev_info(adev->dev, "reset gfx queue (%d:%d:%d: vmid:%d)\n",
|
||||
me_id, pipe_id, queue_id, vmid);
|
||||
|
||||
mutex_lock(&adev->gfx.reset_sem_mutex);
|
||||
gfx_v11_0_request_gfx_index_mutex(adev, true);
|
||||
/* all se allow writes */
|
||||
WREG32_SOC15(GC, 0, regGRBM_GFX_INDEX,
|
||||
(uint32_t)(0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT));
|
||||
value = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
|
||||
if (pipe_id == 0)
|
||||
value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE0_QUEUES, 1 << queue_id);
|
||||
else
|
||||
value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE1_QUEUES, 1 << queue_id);
|
||||
WREG32_SOC15(GC, 0, regCP_VMID_RESET, value);
|
||||
gfx_v11_0_request_gfx_index_mutex(adev, false);
|
||||
mutex_unlock(&adev->gfx.reset_sem_mutex);
|
||||
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0);
|
||||
/* wait till dequeue take effects */
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, regCP_GFX_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout) {
|
||||
dev_err(adev->dev, "failed to wait on gfx hqd deactivate\n");
|
||||
r = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
soc21_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
} else if (queue_type == AMDGPU_RING_TYPE_COMPUTE) {
|
||||
dev_info(adev->dev, "reset compute queue (%d:%d:%d)\n",
|
||||
me_id, pipe_id, queue_id);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0);
|
||||
WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 0x2);
|
||||
WREG32_SOC15(GC, 0, regSPI_COMPUTE_QUEUE_RESET, 0x1);
|
||||
|
||||
/* wait till dequeue take effects */
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout) {
|
||||
dev_err(adev->dev, "failed to wait on hqd deactivate\n");
|
||||
r = -ETIMEDOUT;
|
||||
}
|
||||
soc21_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
}
|
||||
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int mes_v11_0_reset_hw_queue(struct amdgpu_mes *mes,
|
||||
struct mes_reset_queue_input *input)
|
||||
{
|
||||
if (input->use_mmio)
|
||||
return mes_v11_0_reset_queue_mmio(mes, input->queue_type,
|
||||
input->me_id, input->pipe_id,
|
||||
input->queue_id, input->vmid);
|
||||
|
||||
union MESAPI__RESET mes_reset_queue_pkt;
|
||||
|
||||
memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt));
|
||||
@ -648,6 +723,11 @@ static int mes_v11_0_reset_legacy_queue(struct amdgpu_mes *mes,
|
||||
{
|
||||
union MESAPI__RESET mes_reset_queue_pkt;
|
||||
|
||||
if (input->use_mmio)
|
||||
return mes_v11_0_reset_queue_mmio(mes, input->queue_type,
|
||||
input->me_id, input->pipe_id,
|
||||
input->queue_id, input->vmid);
|
||||
|
||||
memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt));
|
||||
|
||||
mes_reset_queue_pkt.header.type = MES_API_TYPE_SCHEDULER;
|
||||
@ -775,6 +855,28 @@ static void mes_v11_0_free_ucode_buffers(struct amdgpu_device *adev,
|
||||
(void **)&adev->mes.ucode_fw_ptr[pipe]);
|
||||
}
|
||||
|
||||
static void mes_v11_0_get_fw_version(struct amdgpu_device *adev)
|
||||
{
|
||||
int pipe;
|
||||
|
||||
/* get MES scheduler/KIQ versions */
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
|
||||
for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
|
||||
soc21_grbm_select(adev, 3, pipe, 0, 0);
|
||||
|
||||
if (pipe == AMDGPU_MES_SCHED_PIPE)
|
||||
adev->mes.sched_version =
|
||||
RREG32_SOC15(GC, 0, regCP_MES_GP3_LO);
|
||||
else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq)
|
||||
adev->mes.kiq_version =
|
||||
RREG32_SOC15(GC, 0, regCP_MES_GP3_LO);
|
||||
}
|
||||
|
||||
soc21_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
}
|
||||
|
||||
static void mes_v11_0_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
uint64_t ucode_addr;
|
||||
@ -1144,18 +1246,6 @@ static int mes_v11_0_queue_init(struct amdgpu_device *adev,
|
||||
mes_v11_0_queue_init_register(ring);
|
||||
}
|
||||
|
||||
/* get MES scheduler/KIQ versions */
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc21_grbm_select(adev, 3, pipe, 0, 0);
|
||||
|
||||
if (pipe == AMDGPU_MES_SCHED_PIPE)
|
||||
adev->mes.sched_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO);
|
||||
else if (pipe == AMDGPU_MES_KIQ_PIPE && adev->enable_mes_kiq)
|
||||
adev->mes.kiq_version = RREG32_SOC15(GC, 0, regCP_MES_GP3_LO);
|
||||
|
||||
soc21_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1402,15 +1492,24 @@ static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev)
|
||||
|
||||
mes_v11_0_enable(adev, true);
|
||||
|
||||
mes_v11_0_get_fw_version(adev);
|
||||
|
||||
mes_v11_0_kiq_setting(&adev->gfx.kiq[0].ring);
|
||||
|
||||
r = mes_v11_0_queue_init(adev, AMDGPU_MES_KIQ_PIPE);
|
||||
if (r)
|
||||
goto failure;
|
||||
|
||||
r = mes_v11_0_hw_init(adev);
|
||||
if (r)
|
||||
goto failure;
|
||||
if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x47)
|
||||
adev->mes.enable_legacy_queue_map = true;
|
||||
else
|
||||
adev->mes.enable_legacy_queue_map = false;
|
||||
|
||||
if (adev->mes.enable_legacy_queue_map) {
|
||||
r = mes_v11_0_hw_init(adev);
|
||||
if (r)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
|
@ -1332,6 +1332,7 @@ static int mes_v12_0_sw_init(void *handle)
|
||||
adev->mes.funcs = &mes_v12_0_funcs;
|
||||
adev->mes.kiq_hw_init = &mes_v12_0_kiq_hw_init;
|
||||
adev->mes.kiq_hw_fini = &mes_v12_0_kiq_hw_fini;
|
||||
adev->mes.enable_legacy_queue_map = true;
|
||||
|
||||
adev->mes.event_log_size = AMDGPU_MES_LOG_BUFFER_SIZE;
|
||||
|
||||
@ -1488,9 +1489,11 @@ static int mes_v12_0_kiq_hw_init(struct amdgpu_device *adev)
|
||||
mes_v12_0_set_hw_resources_1(&adev->mes, AMDGPU_MES_KIQ_PIPE);
|
||||
}
|
||||
|
||||
r = mes_v12_0_hw_init(adev);
|
||||
if (r)
|
||||
goto failure;
|
||||
if (adev->mes.enable_legacy_queue_map) {
|
||||
r = mes_v12_0_hw_init(adev);
|
||||
if (r)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
|
@ -2464,11 +2464,14 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange,
|
||||
adev = pdd->dev->adev;
|
||||
|
||||
/* Check and drain ih1 ring if cam not available */
|
||||
ih = &adev->irq.ih1;
|
||||
checkpoint_wptr = amdgpu_ih_get_wptr(adev, ih);
|
||||
if (ih->rptr != checkpoint_wptr) {
|
||||
svms->checkpoint_ts[i] = amdgpu_ih_decode_iv_ts(adev, ih, checkpoint_wptr, -1);
|
||||
continue;
|
||||
if (adev->irq.ih1.ring_size) {
|
||||
ih = &adev->irq.ih1;
|
||||
checkpoint_wptr = amdgpu_ih_get_wptr(adev, ih);
|
||||
if (ih->rptr != checkpoint_wptr) {
|
||||
svms->checkpoint_ts[i] =
|
||||
amdgpu_ih_decode_iv_ts(adev, ih, checkpoint_wptr, -1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if dev->irq.ih_soft is not empty */
|
||||
|
@ -1754,6 +1754,30 @@ static struct dml2_soc_bb *dm_dmub_get_vbios_bounding_box(struct amdgpu_device *
|
||||
return bb;
|
||||
}
|
||||
|
||||
static enum dmub_ips_disable_type dm_get_default_ips_mode(
|
||||
struct amdgpu_device *adev)
|
||||
{
|
||||
/*
|
||||
* On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to
|
||||
* cause a hard hang. A fix exists for newer PMFW.
|
||||
*
|
||||
* As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest
|
||||
* IPS state in all cases, except for s0ix and all displays off (DPMS),
|
||||
* where IPS2 is allowed.
|
||||
*
|
||||
* When checking pmfw version, use the major and minor only.
|
||||
*/
|
||||
if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(3, 5, 0) &&
|
||||
(adev->pm.fw_version & 0x00FFFF00) < 0x005D6300)
|
||||
return DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
|
||||
if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 5, 0))
|
||||
return DMUB_IPS_ENABLE;
|
||||
|
||||
/* ASICs older than DCN35 do not have IPSs */
|
||||
return DMUB_IPS_DISABLE_ALL;
|
||||
}
|
||||
|
||||
static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct dc_init_data init_data;
|
||||
@ -1864,8 +1888,14 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_IPS)
|
||||
init_data.flags.disable_ips = DMUB_IPS_DISABLE_ALL;
|
||||
else
|
||||
else if (amdgpu_dc_debug_mask & DC_DISABLE_IPS_DYNAMIC)
|
||||
init_data.flags.disable_ips = DMUB_IPS_DISABLE_DYNAMIC;
|
||||
else if (amdgpu_dc_debug_mask & DC_DISABLE_IPS2_DYNAMIC)
|
||||
init_data.flags.disable_ips = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
else if (amdgpu_dc_debug_mask & DC_FORCE_IPS_ENABLE)
|
||||
init_data.flags.disable_ips = DMUB_IPS_ENABLE;
|
||||
else
|
||||
init_data.flags.disable_ips = dm_get_default_ips_mode(adev);
|
||||
|
||||
init_data.flags.disable_ips_in_vpb = 0;
|
||||
|
||||
@ -4507,7 +4537,7 @@ static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
struct amdgpu_dm_backlight_caps caps;
|
||||
struct dc_link *link;
|
||||
u32 brightness;
|
||||
bool rc;
|
||||
bool rc, reallow_idle = false;
|
||||
|
||||
amdgpu_dm_update_backlight_caps(dm, bl_idx);
|
||||
caps = dm->backlight_caps[bl_idx];
|
||||
@ -4520,6 +4550,12 @@ static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
link = (struct dc_link *)dm->backlight_link[bl_idx];
|
||||
|
||||
/* Change brightness based on AUX property */
|
||||
mutex_lock(&dm->dc_lock);
|
||||
if (dm->dc->caps.ips_support && dm->dc->ctx->dmub_srv->idle_allowed) {
|
||||
dc_allow_idle_optimizations(dm->dc, false);
|
||||
reallow_idle = true;
|
||||
}
|
||||
|
||||
if (caps.aux_support) {
|
||||
rc = dc_link_set_backlight_level_nits(link, true, brightness,
|
||||
AUX_BL_DEFAULT_TRANSITION_TIME_MS);
|
||||
@ -4531,6 +4567,11 @@ static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
DRM_DEBUG("DM: Failed to update backlight on eDP[%d]\n", bl_idx);
|
||||
}
|
||||
|
||||
if (dm->dc->caps.ips_support && reallow_idle)
|
||||
dc_allow_idle_optimizations(dm->dc, true);
|
||||
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
|
||||
if (rc)
|
||||
dm->actual_brightness[bl_idx] = user_brightness;
|
||||
}
|
||||
@ -6441,7 +6482,8 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
||||
dc_link_get_highest_encoding_format(aconnector->dc_link),
|
||||
&stream->timing.dsc_cfg)) {
|
||||
stream->timing.flags.DSC = 1;
|
||||
DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from SST RX\n", __func__, drm_connector->name);
|
||||
DRM_DEBUG_DRIVER("%s: SST_DSC [%s] DSC is selected from SST RX\n",
|
||||
__func__, drm_connector->name);
|
||||
}
|
||||
} else if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) {
|
||||
timing_bw_in_kbps = dc_bandwidth_in_kbps_from_timing(&stream->timing,
|
||||
@ -6460,7 +6502,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
||||
dc_link_get_highest_encoding_format(aconnector->dc_link),
|
||||
&stream->timing.dsc_cfg)) {
|
||||
stream->timing.flags.DSC = 1;
|
||||
DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from DP-HDMI PCON\n",
|
||||
DRM_DEBUG_DRIVER("%s: SST_DSC [%s] DSC is selected from DP-HDMI PCON\n",
|
||||
__func__, drm_connector->name);
|
||||
}
|
||||
}
|
||||
@ -11637,7 +11679,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
if (dc_resource_is_dsc_encoding_supported(dc)) {
|
||||
ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
|
||||
if (ret) {
|
||||
drm_dbg_atomic(dev, "compute_mst_dsc_configs_for_state() failed\n");
|
||||
drm_dbg_atomic(dev, "MST_DSC compute_mst_dsc_configs_for_state() failed\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
@ -11658,7 +11700,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
*/
|
||||
ret = drm_dp_mst_atomic_check(state);
|
||||
if (ret) {
|
||||
drm_dbg_atomic(dev, "drm_dp_mst_atomic_check() failed\n");
|
||||
drm_dbg_atomic(dev, "MST drm_dp_mst_atomic_check() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
status = dc_validate_global_state(dc, dm_state->context, true);
|
||||
|
@ -759,7 +759,7 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
|
||||
uint8_t ret = 0;
|
||||
|
||||
drm_dbg_dp(aux->drm_dev,
|
||||
"Configure DSC to non-virtual dpcd synaptics\n");
|
||||
"MST_DSC Configure DSC to non-virtual dpcd synaptics\n");
|
||||
|
||||
if (enable) {
|
||||
/* When DSC is enabled on previous boot and reboot with the hub,
|
||||
@ -772,7 +772,7 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
|
||||
apply_synaptics_fifo_reset_wa(aux);
|
||||
|
||||
ret = drm_dp_dpcd_write(aux, DP_DSC_ENABLE, &enable, 1);
|
||||
DRM_INFO("Send DSC enable to synaptics\n");
|
||||
DRM_INFO("MST_DSC Send DSC enable to synaptics\n");
|
||||
|
||||
} else {
|
||||
/* Synaptics hub not support virtual dpcd,
|
||||
@ -781,7 +781,7 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
|
||||
*/
|
||||
if (!stream->link->link_status.link_active) {
|
||||
ret = drm_dp_dpcd_write(aux, DP_DSC_ENABLE, &enable, 1);
|
||||
DRM_INFO("Send DSC disable to synaptics\n");
|
||||
DRM_INFO("MST_DSC Send DSC disable to synaptics\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -823,14 +823,14 @@ bool dm_helpers_dp_write_dsc_enable(
|
||||
DP_DSC_ENABLE,
|
||||
&enable_passthrough, 1);
|
||||
drm_dbg_dp(dev,
|
||||
"Sent DSC pass-through enable to virtual dpcd port, ret = %u\n",
|
||||
"MST_DSC Sent DSC pass-through enable to virtual dpcd port, ret = %u\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
ret = drm_dp_dpcd_write(aconnector->dsc_aux,
|
||||
DP_DSC_ENABLE, &enable_dsc, 1);
|
||||
drm_dbg_dp(dev,
|
||||
"Sent DSC decoding enable to %s port, ret = %u\n",
|
||||
"MST_DSC Sent DSC decoding enable to %s port, ret = %u\n",
|
||||
(port->passthrough_aux) ? "remote RX" :
|
||||
"virtual dpcd",
|
||||
ret);
|
||||
@ -838,7 +838,7 @@ bool dm_helpers_dp_write_dsc_enable(
|
||||
ret = drm_dp_dpcd_write(aconnector->dsc_aux,
|
||||
DP_DSC_ENABLE, &enable_dsc, 1);
|
||||
drm_dbg_dp(dev,
|
||||
"Sent DSC decoding disable to %s port, ret = %u\n",
|
||||
"MST_DSC Sent DSC decoding disable to %s port, ret = %u\n",
|
||||
(port->passthrough_aux) ? "remote RX" :
|
||||
"virtual dpcd",
|
||||
ret);
|
||||
@ -848,7 +848,7 @@ bool dm_helpers_dp_write_dsc_enable(
|
||||
DP_DSC_ENABLE,
|
||||
&enable_passthrough, 1);
|
||||
drm_dbg_dp(dev,
|
||||
"Sent DSC pass-through disable to virtual dpcd port, ret = %u\n",
|
||||
"MST_DSC Sent DSC pass-through disable to virtual dpcd port, ret = %u\n",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
@ -858,12 +858,12 @@ bool dm_helpers_dp_write_dsc_enable(
|
||||
if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) {
|
||||
ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
|
||||
drm_dbg_dp(dev,
|
||||
"Send DSC %s to SST RX\n",
|
||||
"SST_DSC Send DSC %s to SST RX\n",
|
||||
enable_dsc ? "enable" : "disable");
|
||||
} else if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) {
|
||||
ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
|
||||
drm_dbg_dp(dev,
|
||||
"Send DSC %s to DP-HDMI PCON\n",
|
||||
"SST_DSC Send DSC %s to DP-HDMI PCON\n",
|
||||
enable_dsc ? "enable" : "disable");
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
|
||||
aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux;
|
||||
|
||||
/* synaptics cascaded MST hub case */
|
||||
if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port))
|
||||
if (is_synaptics_cascaded_panamera(aconnector->dc_link, port))
|
||||
aconnector->dsc_aux = port->mgr->aux;
|
||||
|
||||
if (!aconnector->dsc_aux)
|
||||
@ -578,6 +578,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
||||
if (!aconnector)
|
||||
return NULL;
|
||||
|
||||
DRM_DEBUG_DRIVER("%s: Create aconnector 0x%p for port 0x%p\n", __func__, aconnector, port);
|
||||
|
||||
connector = &aconnector->base;
|
||||
aconnector->mst_output_port = port;
|
||||
aconnector->mst_root = master;
|
||||
@ -872,11 +874,11 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
|
||||
if (params[i].sink) {
|
||||
if (params[i].sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
|
||||
params[i].sink->sink_signal != SIGNAL_TYPE_NONE)
|
||||
DRM_DEBUG_DRIVER("%s i=%d dispname=%s\n", __func__, i,
|
||||
DRM_DEBUG_DRIVER("MST_DSC %s i=%d dispname=%s\n", __func__, i,
|
||||
params[i].sink->edid_caps.display_name);
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("dsc=%d bits_per_pixel=%d pbn=%d\n",
|
||||
DRM_DEBUG_DRIVER("MST_DSC dsc=%d bits_per_pixel=%d pbn=%d\n",
|
||||
params[i].timing->flags.DSC,
|
||||
params[i].timing->dsc_cfg.bits_per_pixel,
|
||||
vars[i + k].pbn);
|
||||
@ -1054,6 +1056,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
|
||||
if (next_index == -1)
|
||||
break;
|
||||
|
||||
DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index);
|
||||
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
|
||||
ret = drm_dp_atomic_find_time_slots(state,
|
||||
params[next_index].port->mgr,
|
||||
@ -1064,10 +1067,12 @@ static int try_disable_dsc(struct drm_atomic_state *state,
|
||||
|
||||
ret = drm_dp_mst_atomic_check(state);
|
||||
if (ret == 0) {
|
||||
DRM_DEBUG_DRIVER("MST_DSC index #%d, greedily disable dsc\n", next_index);
|
||||
vars[next_index].dsc_enabled = false;
|
||||
vars[next_index].bpp_x16 = 0;
|
||||
} else {
|
||||
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
|
||||
DRM_DEBUG_DRIVER("MST_DSC index #%d, restore minimum compression\n", next_index);
|
||||
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000);
|
||||
ret = drm_dp_atomic_find_time_slots(state,
|
||||
params[next_index].port->mgr,
|
||||
params[next_index].port,
|
||||
@ -1082,6 +1087,15 @@ static int try_disable_dsc(struct drm_atomic_state *state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void log_dsc_params(int count, struct dsc_mst_fairness_vars *vars, int k)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
DRM_DEBUG_DRIVER("MST_DSC DSC params: stream #%d --- dsc_enabled = %d, bpp_x16 = %d, pbn = %d\n",
|
||||
i, vars[i + k].dsc_enabled, vars[i + k].bpp_x16, vars[i + k].pbn);
|
||||
}
|
||||
|
||||
static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state,
|
||||
struct dc_link *dc_link,
|
||||
@ -1104,6 +1118,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
return PTR_ERR(mst_state);
|
||||
|
||||
/* Set up params */
|
||||
DRM_DEBUG_DRIVER("%s: MST_DSC Set up params for %d streams\n", __func__, dc_state->stream_count);
|
||||
for (i = 0; i < dc_state->stream_count; i++) {
|
||||
struct dc_dsc_policy dsc_policy = {0};
|
||||
|
||||
@ -1145,6 +1160,9 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
params[count].bw_range.stream_kbps = dc_bandwidth_in_kbps_from_timing(&stream->timing,
|
||||
dc_link_get_highest_encoding_format(dc_link));
|
||||
|
||||
DRM_DEBUG_DRIVER("MST_DSC #%d stream 0x%p - max_kbps = %u, min_kbps = %u, uncompressed_kbps = %u\n",
|
||||
count, stream, params[count].bw_range.max_kbps, params[count].bw_range.min_kbps,
|
||||
params[count].bw_range.stream_kbps);
|
||||
count++;
|
||||
}
|
||||
|
||||
@ -1159,6 +1177,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
*link_vars_start_index += count;
|
||||
|
||||
/* Try no compression */
|
||||
DRM_DEBUG_DRIVER("MST_DSC Try no compression\n");
|
||||
for (i = 0; i < count; i++) {
|
||||
vars[i + k].aconnector = params[i].aconnector;
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
|
||||
@ -1177,7 +1196,10 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
return ret;
|
||||
}
|
||||
|
||||
log_dsc_params(count, vars, k);
|
||||
|
||||
/* Try max compression */
|
||||
DRM_DEBUG_DRIVER("MST_DSC Try max compression\n");
|
||||
for (i = 0; i < count; i++) {
|
||||
if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) {
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000);
|
||||
@ -1201,14 +1223,26 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* Optimize degree of compression */
|
||||
ret = increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
log_dsc_params(count, vars, k);
|
||||
|
||||
ret = try_disable_dsc(state, dc_link, params, vars, count, k);
|
||||
if (ret < 0)
|
||||
/* Optimize degree of compression */
|
||||
DRM_DEBUG_DRIVER("MST_DSC Try optimize compression\n");
|
||||
ret = increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k);
|
||||
if (ret < 0) {
|
||||
DRM_DEBUG_DRIVER("MST_DSC Failed to optimize compression\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
log_dsc_params(count, vars, k);
|
||||
|
||||
DRM_DEBUG_DRIVER("MST_DSC Try disable compression\n");
|
||||
ret = try_disable_dsc(state, dc_link, params, vars, count, k);
|
||||
if (ret < 0) {
|
||||
DRM_DEBUG_DRIVER("MST_DSC Failed to disable compression\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
log_dsc_params(count, vars, k);
|
||||
|
||||
set_dsc_configs_from_fairness_vars(params, vars, count, k);
|
||||
|
||||
@ -1230,17 +1264,19 @@ static bool is_dsc_need_re_compute(
|
||||
|
||||
/* only check phy used by dsc mst branch */
|
||||
if (dc_link->type != dc_connection_mst_branch)
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
/* add a check for older MST DSC with no virtual DPCDs */
|
||||
if (needs_dsc_aux_workaround(dc_link) &&
|
||||
(!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
|
||||
dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)))
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++)
|
||||
stream_on_link[i] = NULL;
|
||||
|
||||
DRM_DEBUG_DRIVER("%s: MST_DSC check on %d streams in new dc_state\n", __func__, dc_state->stream_count);
|
||||
|
||||
/* check if there is mode change in new request */
|
||||
for (i = 0; i < dc_state->stream_count; i++) {
|
||||
struct drm_crtc_state *new_crtc_state;
|
||||
@ -1250,6 +1286,8 @@ static bool is_dsc_need_re_compute(
|
||||
if (!stream)
|
||||
continue;
|
||||
|
||||
DRM_DEBUG_DRIVER("%s:%d MST_DSC checking #%d stream 0x%p\n", __func__, __LINE__, i, stream);
|
||||
|
||||
/* check if stream using the same link for mst */
|
||||
if (stream->link != dc_link)
|
||||
continue;
|
||||
@ -1262,8 +1300,11 @@ static bool is_dsc_need_re_compute(
|
||||
new_stream_on_link_num++;
|
||||
|
||||
new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base);
|
||||
if (!new_conn_state)
|
||||
if (!new_conn_state) {
|
||||
DRM_DEBUG_DRIVER("%s:%d MST_DSC no new_conn_state for stream 0x%p, aconnector 0x%p\n",
|
||||
__func__, __LINE__, stream, aconnector);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_ERR(new_conn_state))
|
||||
continue;
|
||||
@ -1272,21 +1313,36 @@ static bool is_dsc_need_re_compute(
|
||||
continue;
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
|
||||
if (!new_crtc_state)
|
||||
if (!new_crtc_state) {
|
||||
DRM_DEBUG_DRIVER("%s:%d MST_DSC no new_crtc_state for crtc of stream 0x%p, aconnector 0x%p\n",
|
||||
__func__, __LINE__, stream, aconnector);
|
||||
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)
|
||||
return true;
|
||||
new_crtc_state->connectors_changed) {
|
||||
DRM_DEBUG_DRIVER("%s:%d MST_DSC dsc recompte required."
|
||||
"stream 0x%p in new dc_state\n",
|
||||
__func__, __LINE__, stream);
|
||||
is_dsc_need_re_compute = true;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_stream_on_link_num == 0)
|
||||
return false;
|
||||
if (new_stream_on_link_num == 0) {
|
||||
DRM_DEBUG_DRIVER("%s:%d MST_DSC no mode change request for streams in new dc_state\n",
|
||||
__func__, __LINE__);
|
||||
is_dsc_need_re_compute = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("%s: MST_DSC check on %d streams in current dc_state\n",
|
||||
__func__, dc->current_state->stream_count);
|
||||
|
||||
/* check current_state if there stream on link but it is not in
|
||||
* new request state
|
||||
@ -1310,11 +1366,18 @@ static bool is_dsc_need_re_compute(
|
||||
|
||||
if (j == new_stream_on_link_num) {
|
||||
/* not in new state */
|
||||
DRM_DEBUG_DRIVER("%s:%d MST_DSC dsc recompute required."
|
||||
"stream 0x%p in current dc_state but not in new dc_state\n",
|
||||
__func__, __LINE__, stream);
|
||||
is_dsc_need_re_compute = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
DRM_DEBUG_DRIVER("%s: MST_DSC dsc recompute %s\n",
|
||||
__func__, is_dsc_need_re_compute ? "required" : "not required");
|
||||
|
||||
return is_dsc_need_re_compute;
|
||||
}
|
||||
|
||||
@ -1343,6 +1406,9 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
|
||||
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
|
||||
|
||||
DRM_DEBUG_DRIVER("%s: MST_DSC compute mst dsc configs for stream 0x%p, aconnector 0x%p\n",
|
||||
__func__, stream, aconnector);
|
||||
|
||||
if (!aconnector || !aconnector->dc_sink || !aconnector->mst_output_port)
|
||||
continue;
|
||||
|
||||
@ -1375,8 +1441,11 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
stream = dc_state->streams[i];
|
||||
|
||||
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) {
|
||||
DRM_DEBUG_DRIVER("%s:%d MST_DSC Failed to request dsc hw resource for stream 0x%p\n",
|
||||
__func__, __LINE__, stream);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1405,6 +1474,9 @@ static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
|
||||
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
|
||||
|
||||
DRM_DEBUG_DRIVER("MST_DSC pre compute mst dsc configs for #%d stream 0x%p, aconnector 0x%p\n",
|
||||
i, stream, aconnector);
|
||||
|
||||
if (!aconnector || !aconnector->dc_sink || !aconnector->mst_output_port)
|
||||
continue;
|
||||
|
||||
@ -1494,12 +1566,12 @@ int pre_validate_dsc(struct drm_atomic_state *state,
|
||||
int ret = 0;
|
||||
|
||||
if (!is_dsc_precompute_needed(state)) {
|
||||
DRM_INFO_ONCE("DSC precompute is not needed.\n");
|
||||
DRM_INFO_ONCE("%s:%d MST_DSC dsc precompute is not needed\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
ret = dm_atomic_get_state(state, dm_state_ptr);
|
||||
if (ret != 0) {
|
||||
DRM_INFO_ONCE("dm_atomic_get_state() failed\n");
|
||||
DRM_INFO_ONCE("%s:%d MST_DSC dm_atomic_get_state() failed\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
dm_state = *dm_state_ptr;
|
||||
@ -1553,7 +1625,8 @@ int pre_validate_dsc(struct drm_atomic_state *state,
|
||||
|
||||
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("%s:%d MST_DSC dsc pre_compute_mst_dsc_configs_for_state() failed\n",
|
||||
__func__, __LINE__);
|
||||
ret = -EINVAL;
|
||||
goto clean_exit;
|
||||
}
|
||||
@ -1567,12 +1640,15 @@ int pre_validate_dsc(struct drm_atomic_state *state,
|
||||
|
||||
if (local_dc_state->streams[i] &&
|
||||
dc_is_timing_changed(stream, local_dc_state->streams[i])) {
|
||||
DRM_INFO_ONCE("crtc[%d] needs mode_changed\n", i);
|
||||
DRM_INFO_ONCE("%s:%d MST_DSC crtc[%d] needs mode_change\n", __func__, __LINE__, i);
|
||||
} else {
|
||||
int ind = find_crtc_index_in_state_by_stream(state, stream);
|
||||
|
||||
if (ind >= 0)
|
||||
if (ind >= 0) {
|
||||
DRM_INFO_ONCE("%s:%d MST_DSC no mode changed for stream 0x%p\n",
|
||||
__func__, __LINE__, stream);
|
||||
state->crtcs[ind].new_state->mode_changed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
clean_exit:
|
||||
@ -1697,7 +1773,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
end_to_end_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
|
||||
|
||||
if (stream_kbps <= end_to_end_bw_in_kbps) {
|
||||
DRM_DEBUG_DRIVER("No DSC needed. End-to-end bw sufficient.");
|
||||
DRM_DEBUG_DRIVER("MST_DSC no dsc required. End-to-end bw sufficient\n");
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
@ -1710,7 +1786,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
/*capable of dsc passthough. dsc bitstream along the entire path*/
|
||||
if (aconnector->mst_output_port->passthrough_aux) {
|
||||
if (bw_range.min_kbps > end_to_end_bw_in_kbps) {
|
||||
DRM_DEBUG_DRIVER("DSC passthrough. Max dsc compression can't fit into end-to-end bw\n");
|
||||
DRM_DEBUG_DRIVER("MST_DSC dsc passthrough and decode at endpoint"
|
||||
"Max dsc compression bw can't fit into end-to-end bw\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
} else {
|
||||
@ -1721,7 +1798,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
/*Get last DP link BW capability*/
|
||||
if (dp_get_link_current_set_bw(&aconnector->mst_output_port->aux, &end_link_bw)) {
|
||||
if (stream_kbps > end_link_bw) {
|
||||
DRM_DEBUG_DRIVER("DSC decode at last link. Mode required bw can't fit into available bw\n");
|
||||
DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link."
|
||||
"Mode required bw can't fit into last link\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
}
|
||||
@ -1734,7 +1812,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
virtual_channel_bw_in_kbps = kbps_from_pbn(immediate_upstream_port->full_pbn);
|
||||
virtual_channel_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
|
||||
if (bw_range.min_kbps > virtual_channel_bw_in_kbps) {
|
||||
DRM_DEBUG_DRIVER("DSC decode at last link. Max dsc compression can't fit into MST available bw\n");
|
||||
DRM_DEBUG_DRIVER("MST_DSC dsc decode at last link."
|
||||
"Max dsc compression can't fit into MST available bw\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
}
|
||||
@ -1751,9 +1830,9 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
dc_link_get_highest_encoding_format(stream->link),
|
||||
&stream->timing.dsc_cfg)) {
|
||||
stream->timing.flags.DSC = 1;
|
||||
DRM_DEBUG_DRIVER("Require dsc and dsc config found\n");
|
||||
DRM_DEBUG_DRIVER("MST_DSC require dsc and dsc config found\n");
|
||||
} else {
|
||||
DRM_DEBUG_DRIVER("Require dsc but can't find appropriate dsc config\n");
|
||||
DRM_DEBUG_DRIVER("MST_DSC require dsc but can't find appropriate dsc config\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
|
||||
@ -1775,11 +1854,11 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
|
||||
if (branch_max_throughput_mps != 0 &&
|
||||
((stream->timing.pix_clk_100hz / 10) > branch_max_throughput_mps * 1000)) {
|
||||
DRM_DEBUG_DRIVER("DSC is required but max throughput mps fails");
|
||||
DRM_DEBUG_DRIVER("MST_DSC require dsc but max throughput mps fails\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
} else {
|
||||
DRM_DEBUG_DRIVER("DSC is required but can't find common dsc config.");
|
||||
DRM_DEBUG_DRIVER("MST_DSC require dsc but can't find common dsc config\n");
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
#endif
|
||||
|
@ -1283,6 +1283,7 @@ int amdgpu_dm_plane_get_cursor_position(struct drm_plane *plane, struct drm_crtc
|
||||
struct dc_cursor_position *position)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct amdgpu_device *adev = drm_to_adev(plane->dev);
|
||||
int x, y;
|
||||
int xorigin = 0, yorigin = 0;
|
||||
|
||||
@ -1314,12 +1315,14 @@ int amdgpu_dm_plane_get_cursor_position(struct drm_plane *plane, struct drm_crtc
|
||||
y = 0;
|
||||
}
|
||||
position->enable = true;
|
||||
position->translate_by_source = true;
|
||||
position->x = x;
|
||||
position->y = y;
|
||||
position->x_hotspot = xorigin;
|
||||
position->y_hotspot = yorigin;
|
||||
|
||||
if (amdgpu_ip_version(adev, DCE_HWIP, 0) < IP_VERSION(4, 0, 1))
|
||||
position->translate_by_source = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ static void init_transmitter_control(struct bios_parser *bp)
|
||||
uint8_t frev;
|
||||
uint8_t crev = 0;
|
||||
|
||||
if (!BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev))
|
||||
if (!BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) && (bp->base.ctx->dc->ctx->dce_version <= DCN_VERSION_2_0))
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
||||
switch (crev) {
|
||||
|
@ -305,9 +305,6 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
if (new_clocks->dtbclk_en && !new_clocks->ref_dtbclk_khz)
|
||||
new_clocks->ref_dtbclk_khz = 600000;
|
||||
|
||||
if (dc->debug.min_disp_clk_khz > 0 && new_clocks->dispclk_khz < dc->debug.min_disp_clk_khz)
|
||||
new_clocks->dispclk_khz = dc->debug.min_disp_clk_khz;
|
||||
|
||||
/*
|
||||
* if it is safe to lower, but we are already in the lower state, we don't have to do anything
|
||||
* also if safe to lower is false, we just go in the higher state
|
||||
@ -385,6 +382,9 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
|
||||
dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
|
||||
|
||||
if (dc->debug.min_disp_clk_khz > 0 && new_clocks->dispclk_khz < dc->debug.min_disp_clk_khz)
|
||||
new_clocks->dispclk_khz = dc->debug.min_disp_clk_khz;
|
||||
|
||||
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
|
||||
dcn35_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
|
||||
dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
|
||||
@ -1100,7 +1100,7 @@ void dcn35_clk_mgr_construct(
|
||||
|
||||
clk_mgr->smu_wm_set.wm_set = (struct dcn35_watermarks *)dm_helpers_allocate_gpu_mem(
|
||||
clk_mgr->base.base.ctx,
|
||||
DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
|
||||
DC_MEM_ALLOC_TYPE_GART,
|
||||
sizeof(struct dcn35_watermarks),
|
||||
&clk_mgr->smu_wm_set.mc_address.quad_part);
|
||||
|
||||
@ -1112,7 +1112,7 @@ void dcn35_clk_mgr_construct(
|
||||
|
||||
smu_dpm_clks.dpm_clks = (DpmClocks_t_dcn35 *)dm_helpers_allocate_gpu_mem(
|
||||
clk_mgr->base.base.ctx,
|
||||
DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
|
||||
DC_MEM_ALLOC_TYPE_GART,
|
||||
sizeof(DpmClocks_t_dcn35),
|
||||
&smu_dpm_clks.mc_address.quad_part);
|
||||
|
||||
@ -1209,7 +1209,7 @@ void dcn35_clk_mgr_construct(
|
||||
}
|
||||
|
||||
if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0)
|
||||
dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
|
||||
dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_GART,
|
||||
smu_dpm_clks.dpm_clks);
|
||||
|
||||
if (ctx->dc->config.disable_ips != DMUB_IPS_DISABLE_ALL) {
|
||||
|
@ -1366,9 +1366,6 @@ static void dcn401_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
|
||||
unsigned int num_steps = 0;
|
||||
|
||||
if (dc->work_arounds.skip_clock_update)
|
||||
return;
|
||||
|
||||
if (dc->debug.enable_legacy_clock_update) {
|
||||
dcn401_update_clocks_legacy(clk_mgr_base, context, safe_to_lower);
|
||||
return;
|
||||
|
@ -2690,6 +2690,9 @@ static enum surface_update_type check_update_surfaces_for_stream(
|
||||
stream_update->vrr_active_variable || stream_update->vrr_active_fixed))
|
||||
su_flags->bits.fams_changed = 1;
|
||||
|
||||
if (stream_update->scaler_sharpener_update)
|
||||
su_flags->bits.scaler_sharpener = 1;
|
||||
|
||||
if (su_flags->raw != 0)
|
||||
overall_type = UPDATE_TYPE_FULL;
|
||||
|
||||
@ -3022,6 +3025,8 @@ static void copy_stream_update_to_stream(struct dc *dc,
|
||||
update->dsc_config = NULL;
|
||||
}
|
||||
}
|
||||
if (update->scaler_sharpener_update)
|
||||
stream->scaler_sharpener_update = *update->scaler_sharpener_update;
|
||||
}
|
||||
|
||||
static void backup_planes_and_stream_state(
|
||||
@ -4713,7 +4718,8 @@ static bool full_update_required(struct dc *dc,
|
||||
stream_update->func_shaper ||
|
||||
stream_update->lut3d_func ||
|
||||
stream_update->pending_test_pattern ||
|
||||
stream_update->crtc_timing_adjust))
|
||||
stream_update->crtc_timing_adjust ||
|
||||
stream_update->scaler_sharpener_update))
|
||||
return true;
|
||||
|
||||
if (stream) {
|
||||
@ -5161,6 +5167,8 @@ void dc_set_power_state(struct dc *dc, enum dc_acpi_cm_power_state power_state)
|
||||
|
||||
dc_z10_restore(dc);
|
||||
|
||||
dc_dmub_srv_notify_fw_dc_power_state(dc->ctx->dmub_srv, power_state);
|
||||
|
||||
dc->hwss.init_hw(dc);
|
||||
|
||||
if (dc->hwss.init_sys_ctx != NULL &&
|
||||
@ -5172,6 +5180,8 @@ void dc_set_power_state(struct dc *dc, enum dc_acpi_cm_power_state power_state)
|
||||
default:
|
||||
ASSERT(dc->current_state->stream_count == 0);
|
||||
|
||||
dc_dmub_srv_notify_fw_dc_power_state(dc->ctx->dmub_srv, power_state);
|
||||
|
||||
dc_state_destruct(dc->current_state);
|
||||
|
||||
break;
|
||||
|
@ -1506,8 +1506,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
|
||||
|
||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha;
|
||||
spl_out->scl_data.h_active = pipe_ctx->plane_res.scl_data.h_active;
|
||||
spl_out->scl_data.v_active = pipe_ctx->plane_res.scl_data.v_active;
|
||||
|
||||
// Convert pipe_ctx to respective input params for SPL
|
||||
translate_SPL_in_params_from_pipe_ctx(pipe_ctx, spl_in);
|
||||
|
@ -55,7 +55,7 @@ struct aux_payload;
|
||||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.297"
|
||||
#define DC_VER "3.2.299"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
@ -761,7 +761,8 @@ union dpia_debug_options {
|
||||
uint32_t extend_aux_rd_interval:1; /* bit 2 */
|
||||
uint32_t disable_mst_dsc_work_around:1; /* bit 3 */
|
||||
uint32_t enable_force_tbt3_work_around:1; /* bit 4 */
|
||||
uint32_t reserved:27;
|
||||
uint32_t disable_usb4_pm_support:1; /* bit 5 */
|
||||
uint32_t reserved:26;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
};
|
||||
@ -1051,6 +1052,7 @@ struct dc_debug_options {
|
||||
unsigned int disable_spl;
|
||||
unsigned int force_easf;
|
||||
unsigned int force_sharpness;
|
||||
unsigned int force_sharpness_level;
|
||||
unsigned int force_lls;
|
||||
bool notify_dpia_hr_bw;
|
||||
bool enable_ips_visual_confirm;
|
||||
@ -1347,7 +1349,7 @@ struct dc_plane_state {
|
||||
enum mpcc_movable_cm_location mcm_location;
|
||||
struct dc_csc_transform cursor_csc_color_matrix;
|
||||
bool adaptive_sharpness_en;
|
||||
unsigned int sharpnessX1000;
|
||||
int sharpness_level;
|
||||
enum linear_light_scaling linear_light_scaling;
|
||||
};
|
||||
|
||||
|
@ -1476,7 +1476,7 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
|
||||
ips2_exit_count);
|
||||
}
|
||||
|
||||
void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState)
|
||||
void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state power_state)
|
||||
{
|
||||
struct dmub_srv *dmub;
|
||||
|
||||
@ -1485,12 +1485,38 @@ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_c
|
||||
|
||||
dmub = dc_dmub_srv->dmub;
|
||||
|
||||
if (powerState == DC_ACPI_CM_POWER_STATE_D0)
|
||||
if (power_state == DC_ACPI_CM_POWER_STATE_D0)
|
||||
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D0);
|
||||
else
|
||||
dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D3);
|
||||
}
|
||||
|
||||
void dc_dmub_srv_notify_fw_dc_power_state(struct dc_dmub_srv *dc_dmub_srv,
|
||||
enum dc_acpi_cm_power_state power_state)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
if (!dc_dmub_srv)
|
||||
return;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.idle_opt_set_dc_power_state.header.type = DMUB_CMD__IDLE_OPT;
|
||||
cmd.idle_opt_set_dc_power_state.header.sub_type = DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE;
|
||||
cmd.idle_opt_set_dc_power_state.header.payload_bytes =
|
||||
sizeof(cmd.idle_opt_set_dc_power_state) - sizeof(cmd.idle_opt_set_dc_power_state.header);
|
||||
|
||||
if (power_state == DC_ACPI_CM_POWER_STATE_D0) {
|
||||
cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_D0;
|
||||
} else if (power_state == DC_ACPI_CM_POWER_STATE_D3) {
|
||||
cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_D3;
|
||||
} else {
|
||||
cmd.idle_opt_set_dc_power_state.data.power_state = DMUB_IDLE_OPT_DC_POWER_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc_dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
}
|
||||
|
||||
bool dc_dmub_srv_should_detect(struct dc_dmub_srv *dc_dmub_srv)
|
||||
{
|
||||
volatile const struct dmub_shared_state_ips_fw *ips_fw;
|
||||
|
@ -109,7 +109,29 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait);
|
||||
|
||||
void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle);
|
||||
|
||||
void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState);
|
||||
/**
|
||||
* dc_dmub_srv_set_power_state() - Sets the power state for DMUB service.
|
||||
*
|
||||
* Controls whether messaging the DMCUB or interfacing with it via HW register
|
||||
* interaction is permittable.
|
||||
*
|
||||
* @dc_dmub_srv - The DC DMUB service pointer
|
||||
* @power_state - the DC power state
|
||||
*/
|
||||
void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state power_state);
|
||||
|
||||
/**
|
||||
* dc_dmub_srv_notify_fw_dc_power_state() - Notifies firmware of the DC power state.
|
||||
*
|
||||
* Differs from dc_dmub_srv_set_power_state in that it needs to access HW in order
|
||||
* to message DMCUB of the state transition. Should come after the D0 exit and
|
||||
* before D3 set power state.
|
||||
*
|
||||
* @dc_dmub_srv - The DC DMUB service pointer
|
||||
* @power_state - the DC power state
|
||||
*/
|
||||
void dc_dmub_srv_notify_fw_dc_power_state(struct dc_dmub_srv *dc_dmub_srv,
|
||||
enum dc_acpi_cm_power_state power_state);
|
||||
|
||||
/**
|
||||
* @dc_dmub_srv_should_detect() - Checks if link detection is required.
|
||||
|
@ -42,26 +42,26 @@ static void populate_spltaps_from_taps(struct spl_taps *spl_scaling_quality,
|
||||
static void populate_taps_from_spltaps(struct scaling_taps *scaling_quality,
|
||||
const struct spl_taps *spl_scaling_quality)
|
||||
{
|
||||
scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c;
|
||||
scaling_quality->h_taps = spl_scaling_quality->h_taps;
|
||||
scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c;
|
||||
scaling_quality->v_taps = spl_scaling_quality->v_taps;
|
||||
scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c + 1;
|
||||
scaling_quality->h_taps = spl_scaling_quality->h_taps + 1;
|
||||
scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c + 1;
|
||||
scaling_quality->v_taps = spl_scaling_quality->v_taps + 1;
|
||||
}
|
||||
static void populate_ratios_from_splratios(struct scaling_ratios *ratios,
|
||||
const struct spl_ratios *spl_ratios)
|
||||
const struct ratio *spl_ratios)
|
||||
{
|
||||
ratios->horz = spl_ratios->horz;
|
||||
ratios->vert = spl_ratios->vert;
|
||||
ratios->horz_c = spl_ratios->horz_c;
|
||||
ratios->vert_c = spl_ratios->vert_c;
|
||||
ratios->horz = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio >> 5, 3, 19);
|
||||
ratios->vert = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio >> 5, 3, 19);
|
||||
ratios->horz_c = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio_c >> 5, 3, 19);
|
||||
ratios->vert_c = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio_c >> 5, 3, 19);
|
||||
}
|
||||
static void populate_inits_from_splinits(struct scl_inits *inits,
|
||||
const struct spl_inits *spl_inits)
|
||||
const struct init *spl_inits)
|
||||
{
|
||||
inits->h = spl_inits->h;
|
||||
inits->v = spl_inits->v;
|
||||
inits->h_c = spl_inits->h_c;
|
||||
inits->v_c = spl_inits->v_c;
|
||||
inits->h = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int, spl_inits->h_filter_init_frac >> 5, 0, 19);
|
||||
inits->v = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int, spl_inits->v_filter_init_frac >> 5, 0, 19);
|
||||
inits->h_c = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int_c, spl_inits->h_filter_init_frac_c >> 5, 0, 19);
|
||||
inits->v_c = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int_c, spl_inits->v_filter_init_frac_c >> 5, 0, 19);
|
||||
}
|
||||
/// @brief Translate SPL input parameters from pipe context
|
||||
/// @param pipe_ctx
|
||||
@ -139,24 +139,36 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
|
||||
else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 2)
|
||||
spl_in->disable_easf = true;
|
||||
/* Translate adaptive sharpening preference */
|
||||
if (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 0) {
|
||||
spl_in->adaptive_sharpness.enable = (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 1) ? true : false;
|
||||
if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 2)
|
||||
spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
|
||||
else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 3)
|
||||
spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
|
||||
else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness >= 4)
|
||||
spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
|
||||
} else {
|
||||
spl_in->adaptive_sharpness.enable = plane_state->adaptive_sharpness_en;
|
||||
if (plane_state->sharpnessX1000 == 0)
|
||||
unsigned int sharpness_setting = pipe_ctx->stream->ctx->dc->debug.force_sharpness;
|
||||
unsigned int force_sharpness_level = pipe_ctx->stream->ctx->dc->debug.force_sharpness_level;
|
||||
if (sharpness_setting == SHARPNESS_HW_OFF)
|
||||
spl_in->adaptive_sharpness.enable = false;
|
||||
else if (sharpness_setting == SHARPNESS_ZERO) {
|
||||
spl_in->adaptive_sharpness.enable = true;
|
||||
spl_in->adaptive_sharpness.sharpness_level = 0;
|
||||
} else if (sharpness_setting == SHARPNESS_CUSTOM) {
|
||||
spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_min = 0;
|
||||
spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_max = 1750;
|
||||
spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_mid = 750;
|
||||
spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_min = 0;
|
||||
spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_max = 3500;
|
||||
spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_mid = 1500;
|
||||
spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_min = 0;
|
||||
spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_max = 2750;
|
||||
spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_mid = 1500;
|
||||
|
||||
if (force_sharpness_level > 0) {
|
||||
if (force_sharpness_level > 10)
|
||||
force_sharpness_level = 10;
|
||||
spl_in->adaptive_sharpness.enable = true;
|
||||
spl_in->adaptive_sharpness.sharpness_level = force_sharpness_level;
|
||||
} else if (!plane_state->adaptive_sharpness_en) {
|
||||
spl_in->adaptive_sharpness.enable = false;
|
||||
else if (plane_state->sharpnessX1000 < 999)
|
||||
spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
|
||||
else if (plane_state->sharpnessX1000 < 1999)
|
||||
spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
|
||||
else // Any other value is high sharpness
|
||||
spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
|
||||
spl_in->adaptive_sharpness.sharpness_level = 0;
|
||||
} else {
|
||||
spl_in->adaptive_sharpness.enable = true;
|
||||
spl_in->adaptive_sharpness.sharpness_level = plane_state->sharpness_level;
|
||||
}
|
||||
}
|
||||
// Translate linear light scaling preference
|
||||
if (pipe_ctx->stream->ctx->dc->debug.force_lls > 0)
|
||||
@ -171,6 +183,22 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
|
||||
/* Translate transfer function */
|
||||
spl_in->basic_in.tf_type = (enum spl_transfer_func_type) plane_state->in_transfer_func.type;
|
||||
spl_in->basic_in.tf_predefined_type = (enum spl_transfer_func_predefined) plane_state->in_transfer_func.tf;
|
||||
|
||||
spl_in->h_active = pipe_ctx->plane_res.scl_data.h_active;
|
||||
spl_in->v_active = pipe_ctx->plane_res.scl_data.v_active;
|
||||
/* Check if it is stream is in fullscreen and if its HDR.
|
||||
* Use this to determine sharpness levels
|
||||
*/
|
||||
spl_in->is_fullscreen = dm_helpers_is_fullscreen(pipe_ctx->stream->ctx, pipe_ctx->stream);
|
||||
spl_in->is_hdr_on = dm_helpers_is_hdr_on(pipe_ctx->stream->ctx, pipe_ctx->stream);
|
||||
spl_in->hdr_multx100 = 0;
|
||||
if (spl_in->is_hdr_on) {
|
||||
spl_in->hdr_multx100 = (uint32_t)dc_fixpt_floor(dc_fixpt_mul(plane_state->hdr_mult,
|
||||
dc_fixpt_from_int(100)));
|
||||
/* Disable sharpness for HDR Mult > 6.0 */
|
||||
if (spl_in->hdr_multx100 > 600)
|
||||
spl_in->adaptive_sharpness.enable = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Translate SPL output parameters to pipe context
|
||||
@ -179,15 +207,15 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
|
||||
void translate_SPL_out_params_to_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_out *spl_out)
|
||||
{
|
||||
// Make scaler data recout point to spl output field recout
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->scl_data.recout);
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->dscl_prog_data->recout);
|
||||
// Make scaler data ratios point to spl output field ratios
|
||||
populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->scl_data.ratios);
|
||||
populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->dscl_prog_data->ratios);
|
||||
// Make scaler data viewport point to spl output field viewport
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->scl_data.viewport);
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->dscl_prog_data->viewport);
|
||||
// Make scaler data viewport_c point to spl output field viewport_c
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->scl_data.viewport_c);
|
||||
populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->dscl_prog_data->viewport_c);
|
||||
// Make scaler data taps point to spl output field scaling taps
|
||||
populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->scl_data.taps);
|
||||
populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->dscl_prog_data->taps);
|
||||
// Make scaler data init point to spl output field init
|
||||
populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->scl_data.inits);
|
||||
populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->dscl_prog_data->init);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define __DC_SPL_TRANSLATE_H__
|
||||
#include "dc.h"
|
||||
#include "resource.h"
|
||||
#include "dm_helpers.h"
|
||||
|
||||
/* Map SPL input parameters to pipe context
|
||||
* @pipe_ctx: pipe context
|
||||
|
@ -142,6 +142,7 @@ union stream_update_flags {
|
||||
uint32_t mst_bw : 1;
|
||||
uint32_t crtc_timing_adjust : 1;
|
||||
uint32_t fams_changed : 1;
|
||||
uint32_t scaler_sharpener : 1;
|
||||
} bits;
|
||||
|
||||
uint32_t raw;
|
||||
@ -308,6 +309,7 @@ struct dc_stream_state {
|
||||
bool is_phantom;
|
||||
|
||||
struct luminance_data lumin_data;
|
||||
bool scaler_sharpener_update;
|
||||
};
|
||||
|
||||
#define ABM_LEVEL_IMMEDIATE_DISABLE 255
|
||||
@ -353,6 +355,7 @@ struct dc_stream_update {
|
||||
struct dc_cursor_attributes *cursor_attributes;
|
||||
struct dc_cursor_position *cursor_position;
|
||||
bool *hw_cursor_req;
|
||||
bool *scaler_sharpener_update;
|
||||
};
|
||||
|
||||
bool dc_is_stream_unchanged(
|
||||
|
@ -1050,6 +1050,23 @@ union replay_error_status {
|
||||
unsigned char raw;
|
||||
};
|
||||
|
||||
union replay_low_refresh_rate_enable_options {
|
||||
struct {
|
||||
//BIT[0-3]: Replay Low Hz Support control
|
||||
unsigned int ENABLE_LOW_RR_SUPPORT :1;
|
||||
unsigned int RESERVED_1_3 :3;
|
||||
//BIT[4-15]: Replay Low Hz Enable Scenarios
|
||||
unsigned int ENABLE_STATIC_SCREEN :1;
|
||||
unsigned int ENABLE_FULL_SCREEN_VIDEO :1;
|
||||
unsigned int ENABLE_GENERAL_UI :1;
|
||||
unsigned int RESERVED_7_15 :9;
|
||||
//BIT[16-31]: Replay Low Hz Enable Check
|
||||
unsigned int ENABLE_STATIC_FLICKER_CHECK :1;
|
||||
unsigned int RESERVED_17_31 :15;
|
||||
} bits;
|
||||
unsigned int raw;
|
||||
};
|
||||
|
||||
struct replay_config {
|
||||
/* Replay feature is supported */
|
||||
bool replay_supported;
|
||||
@ -1073,6 +1090,8 @@ struct replay_config {
|
||||
bool replay_support_fast_resync_in_ultra_sleep_mode;
|
||||
/* Replay error status */
|
||||
union replay_error_status replay_error_status;
|
||||
/* Replay Low Hz enable Options */
|
||||
union replay_low_refresh_rate_enable_options low_rr_enable_options;
|
||||
};
|
||||
|
||||
/* Replay feature flags*/
|
||||
|
@ -328,6 +328,17 @@
|
||||
type DPSTREAMCLK1_GATE_DISABLE;\
|
||||
type DPSTREAMCLK2_GATE_DISABLE;\
|
||||
type DPSTREAMCLK3_GATE_DISABLE;\
|
||||
type SYMCLKA_FE_GATE_DISABLE;\
|
||||
type SYMCLKB_FE_GATE_DISABLE;\
|
||||
type SYMCLKC_FE_GATE_DISABLE;\
|
||||
type SYMCLKD_FE_GATE_DISABLE;\
|
||||
type SYMCLKE_FE_GATE_DISABLE;\
|
||||
type SYMCLKA_GATE_DISABLE;\
|
||||
type SYMCLKB_GATE_DISABLE;\
|
||||
type SYMCLKC_GATE_DISABLE;\
|
||||
type SYMCLKD_GATE_DISABLE;\
|
||||
type SYMCLKE_GATE_DISABLE;\
|
||||
|
||||
|
||||
#define DCCG401_REG_FIELD_LIST(type) \
|
||||
type OTG0_TMDS_PIXEL_RATE_DIV;\
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "core_types.h"
|
||||
#include "resource.h"
|
||||
#include "dcn35_dccg.h"
|
||||
|
||||
#define TO_DCN_DCCG(dccg)\
|
||||
@ -136,7 +137,7 @@ static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool enable)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -165,7 +166,7 @@ static void dccg35_set_symclk32_se_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
|
||||
return;
|
||||
|
||||
/* SYMCLK32_ROOT_SE#_GATE_DISABLE will clock gate in DCCG */
|
||||
@ -204,7 +205,7 @@ static void dccg35_set_symclk32_le_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -231,7 +232,7 @@ static void dccg35_set_physymclk_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -262,35 +263,45 @@ static void dccg35_set_physymclk_rcg(
|
||||
}
|
||||
|
||||
static void dccg35_set_symclk_fe_rcg(
|
||||
struct dccg *dccg,
|
||||
int inst,
|
||||
bool enable)
|
||||
struct dccg *dccg,
|
||||
int inst,
|
||||
bool enable)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKA_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKB_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKC_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKD_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 4:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKE_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
@ -307,27 +318,37 @@ static void dccg35_set_symclk_be_rcg(
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
/* TBD add symclk_be in rcg control bits */
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKA_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKA_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKB_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKB_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKC_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKC_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKD_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKD_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 4:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
@ -342,7 +363,7 @@ static void dccg35_set_dtbclk_p_rcg(struct dccg *dccg, int inst, bool enable)
|
||||
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -370,7 +391,7 @@ static void dccg35_set_dppclk_rcg(struct dccg *dccg,
|
||||
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -399,7 +420,7 @@ static void dccg35_set_dpstreamclk_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -436,7 +457,7 @@ static void dccg35_set_smclk32_se_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -1082,7 +1103,8 @@ static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg)
|
||||
uint32_t dispclk_rdivider_value = 0;
|
||||
|
||||
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);
|
||||
REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
|
||||
if (dispclk_rdivider_value != 0)
|
||||
REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
|
||||
}
|
||||
|
||||
static void dcn35_set_dppclk_enable(struct dccg *dccg,
|
||||
@ -1692,6 +1714,12 @@ static void dccg35_disable_symclk32_se(
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg35_init_cb(struct dccg *dccg)
|
||||
{
|
||||
(void)dccg;
|
||||
/* Any RCG should be done when driver enter low power mode*/
|
||||
}
|
||||
|
||||
void dccg35_init(struct dccg *dccg)
|
||||
{
|
||||
int otg_inst;
|
||||
@ -2042,8 +2070,6 @@ static void dccg35_set_dpstreamclk_cb(
|
||||
enum dtbclk_source dtb_clk_src;
|
||||
enum dp_stream_clk_source dp_stream_clk_src;
|
||||
|
||||
ASSERT(otg_inst >= DP_STREAM_DTBCLK_P5);
|
||||
|
||||
switch (src) {
|
||||
case REFCLK:
|
||||
dtb_clk_src = DTBCLK_REFCLK;
|
||||
@ -2098,6 +2124,13 @@ static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (dccg->dpp_clock_gated[dpp_inst]) {
|
||||
/*
|
||||
* Do not update the DPPCLK DTO if the clock is stopped.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (dccg->ref_dppclk && req_dppclk) {
|
||||
int ref_dppclk = dccg->ref_dppclk;
|
||||
int modulo, phase;
|
||||
@ -2125,19 +2158,20 @@ static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
|
||||
}
|
||||
|
||||
static void dccg35_dpp_root_clock_control_cb(
|
||||
struct dccg *dccg,
|
||||
unsigned int dpp_inst,
|
||||
bool power_on)
|
||||
struct dccg *dccg,
|
||||
unsigned int dpp_inst,
|
||||
bool power_on)
|
||||
{
|
||||
if (dccg->dpp_clock_gated[dpp_inst] == power_on)
|
||||
return;
|
||||
/* power_on set indicates we need to ungate
|
||||
* Currently called from optimize_bandwidth and prepare_bandwidth calls
|
||||
* Since clock source is not passed restore to refclock on ungate
|
||||
* Redundant as gating when enabled is acheived through update_dpp_dto
|
||||
*/
|
||||
if (power_on)
|
||||
dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_REFCLK);
|
||||
else
|
||||
dccg35_disable_dpp_clk_new(dccg, dpp_inst);
|
||||
dccg35_set_dppclk_rcg(dccg, dpp_inst, !power_on);
|
||||
|
||||
dccg->dpp_clock_gated[dpp_inst] = !power_on;
|
||||
}
|
||||
|
||||
static void dccg35_enable_symclk32_se_cb(
|
||||
@ -2321,7 +2355,7 @@ static const struct dccg_funcs dccg35_funcs_new = {
|
||||
.update_dpp_dto = dccg35_update_dpp_dto_cb,
|
||||
.dpp_root_clock_control = dccg35_dpp_root_clock_control_cb,
|
||||
.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
|
||||
.dccg_init = dccg35_init,
|
||||
.dccg_init = dccg35_init_cb,
|
||||
.set_dpstreamclk = dccg35_set_dpstreamclk_cb,
|
||||
.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating_cb,
|
||||
.enable_symclk32_se = dccg35_enable_symclk32_se_cb,
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#define MAX_PIPES 6
|
||||
|
||||
#define GPINT_RETRY_NUM 20
|
||||
|
||||
static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3};
|
||||
static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5};
|
||||
|
||||
@ -222,6 +224,7 @@ static void dmub_replay_residency(struct dmub_replay *dmub, uint8_t panel_inst,
|
||||
uint32_t *residency, const bool is_start, enum pr_residency_mode mode)
|
||||
{
|
||||
uint16_t param = (uint16_t)(panel_inst << 8);
|
||||
uint32_t i = 0;
|
||||
|
||||
switch (mode) {
|
||||
case PR_RESIDENCY_MODE_PHY:
|
||||
@ -249,10 +252,17 @@ static void dmub_replay_residency(struct dmub_replay *dmub, uint8_t panel_inst,
|
||||
if (is_start)
|
||||
param |= REPLAY_RESIDENCY_ENABLE;
|
||||
|
||||
// Send gpint command and wait for ack
|
||||
if (!dc_wake_and_execute_gpint(dmub->ctx, DMUB_GPINT__REPLAY_RESIDENCY, param,
|
||||
residency, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
|
||||
*residency = 0;
|
||||
for (i = 0; i < GPINT_RETRY_NUM; i++) {
|
||||
// Send gpint command and wait for ack
|
||||
if (dc_wake_and_execute_gpint(dmub->ctx, DMUB_GPINT__REPLAY_RESIDENCY, param,
|
||||
residency, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
|
||||
return;
|
||||
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
// it means gpint retry many times
|
||||
*residency = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -777,6 +777,14 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
|
||||
* certain cases. Hence do corrective active and disable scaling.
|
||||
*/
|
||||
plane->composition.scaler_info.enabled = false;
|
||||
} else if ((plane_state->ctx->dc->config.use_spl == true) &&
|
||||
(plane->composition.scaler_info.enabled == false)) {
|
||||
/* To enable sharpener for 1:1, scaler must be enabled. If use_spl is set, then
|
||||
* allow case where ratio is 1 but taps > 1
|
||||
*/
|
||||
if ((scaler_data->taps.h_taps > 1) || (scaler_data->taps.v_taps > 1) ||
|
||||
(scaler_data->taps.h_taps_c > 1) || (scaler_data->taps.v_taps_c > 1))
|
||||
plane->composition.scaler_info.enabled = true;
|
||||
}
|
||||
|
||||
/* always_scale is only used for debug purposes not used in production but has to be
|
||||
|
@ -5,7 +5,6 @@
|
||||
#ifndef __DML_TOP_TYPES_H__
|
||||
#define __DML_TOP_TYPES_H__
|
||||
|
||||
#include "dml_top_types.h"
|
||||
#include "dml_top_display_cfg_types.h"
|
||||
#include "dml_top_soc_parameter_types.h"
|
||||
#include "dml_top_policy_types.h"
|
||||
|
@ -2085,7 +2085,11 @@ static void CalculateDCCConfiguration(
|
||||
unsigned int full_swath_bytes_vert_wc_l;
|
||||
unsigned int full_swath_bytes_vert_wc_c;
|
||||
|
||||
yuv420 = dml_is_420(SourcePixelFormat);
|
||||
if (dml_is_420(SourcePixelFormat))
|
||||
yuv420 = 1;
|
||||
else
|
||||
yuv420 = 0;
|
||||
|
||||
horz_div_l = 1;
|
||||
horz_div_c = 1;
|
||||
vert_div_l = 1;
|
||||
@ -2553,8 +2557,11 @@ static void calculate_mcache_setting(
|
||||
l->luma_time_factor = (double)l->mvmpg_width_c / l->mvmpg_width_l * 2;
|
||||
|
||||
// The algorithm starts with computing a non-integer, avg_mcache_element_size_l/c:
|
||||
l->avg_mcache_element_size_l = l->meta_row_width_l / *p->num_mcaches_l;
|
||||
if (l->is_dual_plane) {
|
||||
if (*p->num_mcaches_l) {
|
||||
l->avg_mcache_element_size_l = l->meta_row_width_l / *p->num_mcaches_l;
|
||||
}
|
||||
|
||||
if (l->is_dual_plane && *p->num_mcaches_c) {
|
||||
l->avg_mcache_element_size_c = l->meta_row_width_c / *p->num_mcaches_c;
|
||||
|
||||
if (!p->imall_enable || (*p->mall_comb_mcache_l == *p->mall_comb_mcache_c)) {
|
||||
@ -2683,9 +2690,9 @@ static double dml_get_return_bandwidth_available(
|
||||
double ideal_fabric_bandwidth = fclk_mhz * (double)soc->fabric_datapath_to_dcn_data_return_bytes;
|
||||
double ideal_dram_bandwidth = dram_bw_mbps; //dram_speed_mts * soc->clk_table.dram_config.channel_count * soc->clk_table.dram_config.channel_width_bytes;
|
||||
|
||||
double derate_sdp_factor = 1;
|
||||
double derate_fabric_factor = 1;
|
||||
double derate_dram_factor = 1;
|
||||
double derate_sdp_factor;
|
||||
double derate_fabric_factor;
|
||||
double derate_dram_factor;
|
||||
|
||||
double derate_sdp_bandwidth;
|
||||
double derate_fabric_bandwidth;
|
||||
@ -5056,6 +5063,8 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
|
||||
s->trip_to_mem = 0.0;
|
||||
*p->Tvm_trips = 0.0;
|
||||
*p->Tr0_trips = 0.0;
|
||||
s->Tvm_no_trip_oto = 0.0;
|
||||
s->Tr0_no_trip_oto = 0.0;
|
||||
s->Tvm_trips_rounded = 0.0;
|
||||
s->Tr0_trips_rounded = 0.0;
|
||||
s->max_Tsw = 0.0;
|
||||
@ -5293,31 +5302,38 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
|
||||
s->Lsw_oto = math_ceil2(4.0 * math_max2(s->prefetch_sw_bytes / s->prefetch_bw_oto / s->LineTime, s->min_Lsw_oto), 1.0) / 4.0;
|
||||
|
||||
if (p->display_cfg->gpuvm_enable == true) {
|
||||
s->Tvm_oto = math_max3(
|
||||
*p->Tvm_trips,
|
||||
s->Tvm_no_trip_oto = math_max2(
|
||||
*p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_oto,
|
||||
s->LineTime / 4.0);
|
||||
s->Tvm_oto = math_max2(
|
||||
*p->Tvm_trips,
|
||||
s->Tvm_no_trip_oto);
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
dml2_printf("DML::%s: Tvm_oto max0 = %f\n", __func__, *p->Tvm_trips);
|
||||
dml2_printf("DML::%s: Tvm_oto max1 = %f\n", __func__, *p->Tno_bw + vm_bytes * p->HostVMInefficiencyFactor / s->prefetch_bw_oto);
|
||||
dml2_printf("DML::%s: Tvm_oto max2 = %f\n", __func__, s->LineTime / 4.0);
|
||||
#endif
|
||||
} else {
|
||||
s->Tvm_no_trip_oto = s->Tvm_trips_rounded;
|
||||
s->Tvm_oto = s->Tvm_trips_rounded;
|
||||
}
|
||||
|
||||
if ((p->display_cfg->gpuvm_enable == true || p->setup_for_tdlut || dcc_mrq_enable)) {
|
||||
s->Tr0_oto = math_max3(
|
||||
*p->Tr0_trips,
|
||||
s->Tr0_no_trip_oto = math_max2(
|
||||
(p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_oto,
|
||||
s->LineTime / 4.0);
|
||||
s->Tr0_oto = math_max2(
|
||||
*p->Tr0_trips,
|
||||
s->Tr0_no_trip_oto);
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
dml2_printf("DML::%s: Tr0_oto max0 = %f\n", __func__, *p->Tr0_trips);
|
||||
dml2_printf("DML::%s: Tr0_oto max1 = %f\n", __func__, (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + p->meta_row_bytes + tdlut_row_bytes) / s->prefetch_bw_oto);
|
||||
dml2_printf("DML::%s: Tr0_oto max2 = %f\n", __func__, s->LineTime / 4);
|
||||
#endif
|
||||
} else
|
||||
s->Tr0_oto = (s->LineTime - s->Tvm_oto) / 4.0;
|
||||
} else {
|
||||
s->Tr0_no_trip_oto = (s->LineTime - s->Tvm_oto) / 4.0;
|
||||
s->Tr0_oto = s->Tr0_no_trip_oto;
|
||||
}
|
||||
|
||||
s->Tvm_oto_lines = math_ceil2(4.0 * s->Tvm_oto / s->LineTime, 1) / 4.0;
|
||||
s->Tr0_oto_lines = math_ceil2(4.0 * s->Tr0_oto / s->LineTime, 1) / 4.0;
|
||||
@ -5595,6 +5611,9 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
|
||||
dml2_printf("DML::%s: Tvm_equ = %f\n", __func__, s->Tvm_equ);
|
||||
dml2_printf("DML::%s: Tr0_equ = %f\n", __func__, s->Tr0_equ);
|
||||
#endif
|
||||
// Lsw = dst_y_prefetch - (dst_y_per_vm_vblank + 2*dst_y_per_row_vblank)
|
||||
s->Lsw_equ = s->dst_y_prefetch_equ - math_ceil2(4.0 * (s->Tvm_equ + 2 * s->Tr0_equ) / s->LineTime, 1.0) / 4.0;
|
||||
|
||||
// Use the more stressful prefetch schedule
|
||||
if (s->dst_y_prefetch_oto < s->dst_y_prefetch_equ) {
|
||||
*p->dst_y_prefetch = s->dst_y_prefetch_oto;
|
||||
@ -5603,25 +5622,28 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
|
||||
|
||||
*p->dst_y_per_vm_vblank = math_ceil2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
|
||||
*p->dst_y_per_row_vblank = math_ceil2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
|
||||
s->dst_y_per_vm_no_trip_vblank = math_ceil2(4.0 * s->Tvm_no_trip_oto / s->LineTime, 1.0) / 4.0;
|
||||
s->dst_y_per_row_no_trip_vblank = math_ceil2(4.0 * s->Tr0_no_trip_oto / s->LineTime, 1.0) / 4.0;
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
dml2_printf("DML::%s: Using oto scheduling for prefetch\n", __func__);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
*p->dst_y_prefetch = s->dst_y_prefetch_equ;
|
||||
s->TimeForFetchingVM = s->Tvm_equ;
|
||||
s->TimeForFetchingRowInVBlank = s->Tr0_equ;
|
||||
|
||||
*p->dst_y_per_vm_vblank = math_ceil2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
|
||||
*p->dst_y_per_row_vblank = math_ceil2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
|
||||
*p->dst_y_per_vm_vblank = math_ceil2(4.0 * s->TimeForFetchingVM / s->LineTime, 1.0) / 4.0;
|
||||
*p->dst_y_per_row_vblank = math_ceil2(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
|
||||
s->dst_y_per_vm_no_trip_vblank = *p->dst_y_per_vm_vblank;
|
||||
s->dst_y_per_row_no_trip_vblank = *p->dst_y_per_row_vblank;
|
||||
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
dml2_printf("DML::%s: Using equ bw scheduling for prefetch\n", __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Lsw = dst_y_prefetch - (dst_y_per_vm_vblank + 2*dst_y_per_row_vblank)
|
||||
s->LinesToRequestPrefetchPixelData = *p->dst_y_prefetch - *p->dst_y_per_vm_vblank - 2 * *p->dst_y_per_row_vblank; // Lsw
|
||||
/* take worst case Lsw to calculate bandwidth requirement regardless of schedule */
|
||||
s->LinesToRequestPrefetchPixelData = math_min2(s->Lsw_equ, s->Lsw_oto); // Lsw
|
||||
|
||||
s->cursor_prefetch_bytes = (unsigned int)math_max2(p->cursor_bytes_per_chunk, 4 * p->cursor_bytes_per_line);
|
||||
*p->prefetch_cursor_bw = p->num_cursors * s->cursor_prefetch_bytes / (s->LinesToRequestPrefetchPixelData * s->LineTime);
|
||||
@ -5741,13 +5763,13 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
|
||||
|
||||
if (vm_bytes == 0) {
|
||||
prefetch_vm_bw = 0;
|
||||
} else if (*p->dst_y_per_vm_vblank > 0) {
|
||||
} else if (s->dst_y_per_vm_no_trip_vblank > 0) {
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
dml2_printf("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
|
||||
dml2_printf("DML::%s: dst_y_per_vm_vblank = %f\n", __func__, *p->dst_y_per_vm_vblank);
|
||||
dml2_printf("DML::%s: LineTime = %f\n", __func__, s->LineTime);
|
||||
#endif
|
||||
prefetch_vm_bw = vm_bytes * p->HostVMInefficiencyFactor / (*p->dst_y_per_vm_vblank * s->LineTime);
|
||||
prefetch_vm_bw = vm_bytes * p->HostVMInefficiencyFactor / (s->dst_y_per_vm_no_trip_vblank * s->LineTime);
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
dml2_printf("DML::%s: prefetch_vm_bw = %f\n", __func__, prefetch_vm_bw);
|
||||
#endif
|
||||
@ -5759,8 +5781,8 @@ static bool CalculatePrefetchSchedule(struct dml2_core_internal_scratch *scratch
|
||||
|
||||
if (p->PixelPTEBytesPerRow == 0 && tdlut_row_bytes == 0) {
|
||||
prefetch_row_bw = 0;
|
||||
} else if (*p->dst_y_per_row_vblank > 0) {
|
||||
prefetch_row_bw = (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + tdlut_row_bytes) / (*p->dst_y_per_row_vblank * s->LineTime);
|
||||
} else if (s->dst_y_per_row_no_trip_vblank > 0) {
|
||||
prefetch_row_bw = (p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + tdlut_row_bytes) / (s->dst_y_per_row_no_trip_vblank * s->LineTime);
|
||||
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
dml2_printf("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow);
|
||||
@ -7194,7 +7216,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
|
||||
mode_lib->ms.support.WritebackLatencySupport = true;
|
||||
for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
|
||||
if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.enable == true &&
|
||||
(mode_lib->ms.WriteBandwidth[k] > mode_lib->ip.writeback_interface_buffer_size_kbytes * 1024 / mode_lib->soc.qos_parameters.writeback.base_latency_us)) {
|
||||
(mode_lib->ms.WriteBandwidth[k] > mode_lib->ip.writeback_interface_buffer_size_kbytes * 1024 / ((double)mode_lib->soc.qos_parameters.writeback.base_latency_us))) {
|
||||
mode_lib->ms.support.WritebackLatencySupport = false;
|
||||
}
|
||||
}
|
||||
@ -10739,7 +10761,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
|
||||
mode_lib->mp.UrgentLatency,
|
||||
mode_lib->mp.TripToMemory,
|
||||
!dml_is_phantom_pipe(&display_cfg->plane_descriptors[k]) && display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.drr_config.enabled ?
|
||||
get_g6_temp_read_blackout_us(&mode_lib->soc, (unsigned int)(mode_lib->ms.uclk_freq_mhz * 1000), in_out_params->min_clk_index) : 0.0);
|
||||
get_g6_temp_read_blackout_us(&mode_lib->soc, (unsigned int)(mode_lib->mp.uclk_freq_mhz * 1000), in_out_params->min_clk_index) : 0.0);
|
||||
|
||||
myPipe->Dppclk = mode_lib->mp.Dppclk[k];
|
||||
myPipe->Dispclk = mode_lib->mp.Dispclk;
|
||||
|
@ -1187,11 +1187,15 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
|
||||
double prefetch_bw_oto;
|
||||
double Tvm_oto;
|
||||
double Tr0_oto;
|
||||
double Tvm_no_trip_oto;
|
||||
double Tr0_no_trip_oto;
|
||||
double Tvm_oto_lines;
|
||||
double Tr0_oto_lines;
|
||||
double dst_y_prefetch_oto;
|
||||
double TimeForFetchingVM;
|
||||
double TimeForFetchingRowInVBlank;
|
||||
double dst_y_per_vm_no_trip_vblank;
|
||||
double dst_y_per_row_no_trip_vblank;
|
||||
double LinesToRequestPrefetchPixelData;
|
||||
unsigned int HostVMDynamicLevelsTrips;
|
||||
double trip_to_mem;
|
||||
@ -1199,6 +1203,7 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
|
||||
double Tr0_trips_rounded;
|
||||
double max_Tsw;
|
||||
double Lsw_oto;
|
||||
double Lsw_equ;
|
||||
double Tpre_rounded;
|
||||
double prefetch_bw_equ;
|
||||
double Tvm_equ;
|
||||
|
@ -497,7 +497,6 @@ bool pmo_dcn3_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_out *in
|
||||
in_out->cfg_support_info->plane_support_info[i].dpps_used)) {
|
||||
result = false;
|
||||
} else {
|
||||
free_pipes -= planes_on_stream;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -666,7 +665,7 @@ bool pmo_dcn3_optimize_for_pstate_support(struct dml2_pmo_optimize_for_pstate_su
|
||||
struct dml2_pmo_instance *pmo = in_out->instance;
|
||||
unsigned int stream_index;
|
||||
bool success = false;
|
||||
bool reached_end = true;
|
||||
bool reached_end;
|
||||
|
||||
memcpy(in_out->optimized_display_config, in_out->base_display_config, sizeof(struct display_configuation_with_meta));
|
||||
|
||||
|
@ -334,7 +334,6 @@ bool pmo_dcn4_fams2_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_o
|
||||
in_out->cfg_support_info->plane_support_info[i].dpps_used)) {
|
||||
result = false;
|
||||
} else {
|
||||
free_pipes -= planes_on_stream;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -672,8 +671,6 @@ bool pmo_dcn4_fams2_initialize(struct dml2_pmo_initialize_in_out *in_out)
|
||||
/* populate list */
|
||||
expand_base_strategies(pmo, base_strategy_list_4_display, base_strategy_list_4_display_size, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -944,7 +941,8 @@ static void build_synchronized_timing_groups(
|
||||
for (j = i + 1; j < display_config->display_config.num_streams; j++) {
|
||||
if (memcmp(master_timing,
|
||||
&display_config->display_config.stream_descriptors[j].timing,
|
||||
sizeof(struct dml2_timing_cfg)) == 0) {
|
||||
sizeof(struct dml2_timing_cfg)) == 0 &&
|
||||
display_config->display_config.stream_descriptors[i].output.output_encoder == display_config->display_config.stream_descriptors[j].output.output_encoder) {
|
||||
set_bit_in_bitfield(&pmo->scratch.pmo_dcn4.synchronized_timing_group_masks[timing_group_idx], j);
|
||||
set_bit_in_bitfield(&stream_mapped_mask, j);
|
||||
}
|
||||
|
@ -219,7 +219,6 @@ bool dml2_top_optimization_perform_optimization_phase_1(struct dml2_optimization
|
||||
copy_display_configuration_with_meta(&l->cur_candidate_display_cfg, params->display_config);
|
||||
highest_state = l->cur_candidate_display_cfg.stage1.min_clk_index_for_latency;
|
||||
lowest_state = 0;
|
||||
cur_state = 0;
|
||||
|
||||
while (highest_state > lowest_state) {
|
||||
cur_state = (highest_state + lowest_state) / 2;
|
||||
|
@ -101,7 +101,7 @@ struct dml2_wrapper_scratch {
|
||||
struct dml2_dml_to_dc_pipe_mapping dml_to_dc_pipe_mapping;
|
||||
bool enable_flexible_pipe_mapping;
|
||||
bool plane_duplicate_exists;
|
||||
unsigned int dp2_mst_stream_count;
|
||||
int hpo_stream_to_link_encoder_mapping[MAX_HPO_DP2_ENCODERS];
|
||||
};
|
||||
|
||||
struct dml2_helper_det_policy_scratch {
|
||||
|
@ -733,8 +733,7 @@ static void populate_dml_timing_cfg_from_stream_state(struct dml_timing_cfg_st *
|
||||
}
|
||||
|
||||
static void populate_dml_output_cfg_from_stream_state(struct dml_output_cfg_st *out, unsigned int location,
|
||||
const struct dc_stream_state *in, const struct pipe_ctx *pipe,
|
||||
unsigned int dp2_mst_stream_count)
|
||||
const struct dc_stream_state *in, const struct pipe_ctx *pipe, struct dml2_context *dml2)
|
||||
{
|
||||
unsigned int output_bpc;
|
||||
|
||||
@ -747,8 +746,8 @@ static void populate_dml_output_cfg_from_stream_state(struct dml_output_cfg_st *
|
||||
case SIGNAL_TYPE_DISPLAY_PORT_MST:
|
||||
case SIGNAL_TYPE_DISPLAY_PORT:
|
||||
out->OutputEncoder[location] = dml_dp;
|
||||
if (is_dp2p0_output_encoder(pipe, dp2_mst_stream_count))
|
||||
out->OutputEncoder[location] = dml_dp2p0;
|
||||
if (dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[location] != -1)
|
||||
out->OutputEncoder[dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[location]] = dml_dp2p0;
|
||||
break;
|
||||
case SIGNAL_TYPE_EDP:
|
||||
out->OutputEncoder[location] = dml_edp;
|
||||
@ -1199,36 +1198,6 @@ static void dml2_populate_pipe_to_plane_index_mapping(struct dml2_context *dml2,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int calculate_dp2_mst_stream_count(struct dc_state *context)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int dp2_mst_stream_count = 0;
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
struct dc_stream_state *stream = context->streams[i];
|
||||
|
||||
if (!stream || stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MAX_PIPES; j++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (!pipe_ctx || !pipe_ctx->stream)
|
||||
continue;
|
||||
|
||||
if (stream != pipe_ctx->stream)
|
||||
continue;
|
||||
|
||||
if (pipe_ctx->stream_res.hpo_dp_stream_enc && pipe_ctx->link_res.hpo_dp_link_enc) {
|
||||
dp2_mst_stream_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp2_mst_stream_count;
|
||||
}
|
||||
|
||||
static void populate_dml_writeback_cfg_from_stream_state(struct dml_writeback_cfg_st *out,
|
||||
unsigned int location, const struct dc_stream_state *in)
|
||||
{
|
||||
@ -1269,6 +1238,30 @@ static void populate_dml_writeback_cfg_from_stream_state(struct dml_writeback_cf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dml2_map_hpo_stream_encoder_to_hpo_link_encoder_index(struct dml2_context *dml2, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
struct pipe_ctx *current_pipe_context;
|
||||
|
||||
/* Scratch gets reset to zero in dml, but link encoder instance can be zero, so reset to -1 */
|
||||
for (i = 0; i < MAX_HPO_DP2_ENCODERS; i++) {
|
||||
dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[i] = -1;
|
||||
}
|
||||
|
||||
/* If an HPO stream encoder is allocated to a pipe, get the instance of it's allocated HPO Link encoder */
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
current_pipe_context = &context->res_ctx.pipe_ctx[i];
|
||||
if (current_pipe_context->stream &&
|
||||
current_pipe_context->stream_res.hpo_dp_stream_enc &&
|
||||
current_pipe_context->link_res.hpo_dp_link_enc &&
|
||||
dc_is_dp_signal(current_pipe_context->stream->signal)) {
|
||||
dml2->v20.scratch.hpo_stream_to_link_encoder_mapping[current_pipe_context->stream_res.hpo_dp_stream_enc->inst] =
|
||||
current_pipe_context->link_res.hpo_dp_link_enc->inst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg)
|
||||
{
|
||||
int i = 0, j = 0, k = 0;
|
||||
@ -1291,8 +1284,8 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
|
||||
if (dml2->v20.dml_core_ctx.ip.hostvm_enable)
|
||||
dml2->v20.dml_core_ctx.policy.AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter;
|
||||
|
||||
dml2->v20.scratch.dp2_mst_stream_count = calculate_dp2_mst_stream_count(context);
|
||||
dml2_populate_pipe_to_plane_index_mapping(dml2, context);
|
||||
dml2_map_hpo_stream_encoder_to_hpo_link_encoder_index(dml2, context);
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
current_pipe_context = NULL;
|
||||
@ -1313,7 +1306,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
|
||||
ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);
|
||||
|
||||
populate_dml_timing_cfg_from_stream_state(&dml_dispcfg->timing, disp_cfg_stream_location, context->streams[i]);
|
||||
populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_stream_location, context->streams[i], current_pipe_context, dml2->v20.scratch.dp2_mst_stream_count);
|
||||
populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_stream_location, context->streams[i], current_pipe_context, dml2);
|
||||
/*Call site for populate_dml_writeback_cfg_from_stream_state*/
|
||||
populate_dml_writeback_cfg_from_stream_state(&dml_dispcfg->writeback,
|
||||
disp_cfg_stream_location, context->streams[i]);
|
||||
@ -1378,7 +1371,7 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat
|
||||
|
||||
if (j >= 1) {
|
||||
populate_dml_timing_cfg_from_stream_state(&dml_dispcfg->timing, disp_cfg_plane_location, context->streams[i]);
|
||||
populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_plane_location, context->streams[i], current_pipe_context, dml2->v20.scratch.dp2_mst_stream_count);
|
||||
populate_dml_output_cfg_from_stream_state(&dml_dispcfg->output, disp_cfg_plane_location, context->streams[i], current_pipe_context, dml2);
|
||||
switch (context->streams[i]->debug.force_odm_combine_segments) {
|
||||
case 2:
|
||||
dml2->v20.dml_core_ctx.policy.ODMUse[disp_cfg_plane_location] = dml_odm_use_policy_combine_2to1;
|
||||
|
@ -36,6 +36,6 @@ void dml2_translate_socbb_params(const struct dc *in_dc, struct soc_bounding_box
|
||||
void dml2_translate_soc_states(const struct dc *in_dc, struct soc_states_st *out, int num_states);
|
||||
void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_state *context, struct dml_display_cfg_st *dml_dispcfg);
|
||||
void dml2_update_pipe_ctx_dchub_regs(struct _vcs_dpi_dml_display_rq_regs_st *rq_regs, struct _vcs_dpi_dml_display_dlg_regs_st *disp_dlg_regs, struct _vcs_dpi_dml_display_ttu_regs_st *disp_ttu_regs, struct pipe_ctx *out);
|
||||
bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe, unsigned int dp2_mst_stream_count);
|
||||
bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe);
|
||||
|
||||
#endif //__DML2_TRANSLATION_HELPER_H__
|
||||
|
@ -153,7 +153,7 @@ unsigned int dml2_util_get_maximum_odm_combine_for_output(bool force_odm_4to1, e
|
||||
}
|
||||
}
|
||||
|
||||
bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx, unsigned int dp2_mst_stream_count)
|
||||
bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
|
||||
return false;
|
||||
@ -161,14 +161,6 @@ bool is_dp2p0_output_encoder(const struct pipe_ctx *pipe_ctx, unsigned int dp2_m
|
||||
/* If this assert is hit then we have a link encoder dynamic management issue */
|
||||
ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true);
|
||||
|
||||
/* Count MST hubs once by treating only 1st remote sink in topology as an encoder */
|
||||
if (pipe_ctx->stream->link && pipe_ctx->stream->link->remote_sinks[0] && dp2_mst_stream_count > 1) {
|
||||
return (pipe_ctx->stream_res.hpo_dp_stream_enc &&
|
||||
pipe_ctx->link_res.hpo_dp_link_enc &&
|
||||
dc_is_dp_signal(pipe_ctx->stream->signal) &&
|
||||
(pipe_ctx->stream->link->remote_sinks[0]->sink_id == pipe_ctx->stream->sink->sink_id));
|
||||
}
|
||||
|
||||
return (pipe_ctx->stream_res.hpo_dp_stream_enc &&
|
||||
pipe_ctx->link_res.hpo_dp_link_enc &&
|
||||
dc_is_dp_signal(pipe_ctx->stream->signal));
|
||||
@ -181,7 +173,7 @@ bool is_dtbclk_required(const struct dc *dc, struct dc_state *context)
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
if (is_dp2p0_output_encoder(&context->res_ctx.pipe_ctx[i], context->bw_ctx.dml2->v20.scratch.dp2_mst_stream_count))
|
||||
if (is_dp2p0_output_encoder(&context->res_ctx.pipe_ctx[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -280,7 +280,8 @@ static void dpp401_dscl_set_scaler_filter(
|
||||
static void dpp401_dscl_set_scl_filter(
|
||||
struct dcn401_dpp *dpp,
|
||||
const struct scaler_data *scl_data,
|
||||
bool chroma_coef_mode)
|
||||
bool chroma_coef_mode,
|
||||
bool force_coeffs_update)
|
||||
{
|
||||
bool h_2tap_hardcode_coef_en = false;
|
||||
bool v_2tap_hardcode_coef_en = false;
|
||||
@ -343,7 +344,7 @@ static void dpp401_dscl_set_scl_filter(
|
||||
|| (filter_v_c && (filter_v_c != dpp->filter_v_c));
|
||||
}
|
||||
|
||||
if (filter_updated) {
|
||||
if ((filter_updated) || (force_coeffs_update)) {
|
||||
uint32_t scl_mode = REG_READ(SCL_MODE);
|
||||
|
||||
if (!h_2tap_hardcode_coef_en && filter_h) {
|
||||
@ -655,6 +656,226 @@ static void dpp401_dscl_set_recout(struct dcn401_dpp *dpp,
|
||||
/* Number of RECOUT vertical lines */
|
||||
RECOUT_HEIGHT, recout->height);
|
||||
}
|
||||
/**
|
||||
* dpp401_dscl_program_easf_v - Program EASF_V
|
||||
*
|
||||
* @dpp_base: High level DPP struct
|
||||
* @scl_data: scalaer_data info
|
||||
*
|
||||
* This is the primary function to program vertical EASF registers
|
||||
*
|
||||
*/
|
||||
static void dpp401_dscl_program_easf_v(struct dpp *dpp_base, const struct scaler_data *scl_data)
|
||||
{
|
||||
struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
|
||||
|
||||
PERF_TRACE();
|
||||
/* DSCL_EASF_V_MODE */
|
||||
REG_SET_3(DSCL_EASF_V_MODE, 0,
|
||||
SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en,
|
||||
SCL_EASF_V_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_v_sharp_factor,
|
||||
SCL_EASF_V_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_v_ring);
|
||||
|
||||
if (!scl_data->dscl_prog_data.easf_v_en) {
|
||||
PERF_TRACE();
|
||||
return;
|
||||
}
|
||||
|
||||
/* DSCL_EASF_V_BF_CNTL */
|
||||
REG_SET_6(DSCL_EASF_V_BF_CNTL, 0,
|
||||
SCL_EASF_V_BF1_EN, scl_data->dscl_prog_data.easf_v_bf1_en,
|
||||
SCL_EASF_V_BF2_MODE, scl_data->dscl_prog_data.easf_v_bf2_mode,
|
||||
SCL_EASF_V_BF3_MODE, scl_data->dscl_prog_data.easf_v_bf3_mode,
|
||||
SCL_EASF_V_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat1_gain,
|
||||
SCL_EASF_V_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat2_gain,
|
||||
SCL_EASF_V_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_v_bf2_roc_gain);
|
||||
/* DSCL_EASF_V_RINGEST_3TAP_CNTLn */
|
||||
REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL1, 0,
|
||||
SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_uptilt,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt_max);
|
||||
REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL2, 0,
|
||||
SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_slope,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt1_slope);
|
||||
REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL3, 0,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_slope,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_offset);
|
||||
/* DSCL_EASF_V_RINGEST_EVENTAP_REDUCE */
|
||||
REG_SET_2(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE, 0,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg1,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg2);
|
||||
/* DSCL_EASF_V_RINGEST_EVENTAP_GAIN */
|
||||
REG_SET_2(DSCL_EASF_V_RINGEST_EVENTAP_GAIN, 0,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain1,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain2);
|
||||
/* DSCL_EASF_V_BF_FINAL_MAX_MIN */
|
||||
REG_SET_4(DSCL_EASF_V_BF_FINAL_MAX_MIN, 0,
|
||||
SCL_EASF_V_BF_MAXA, scl_data->dscl_prog_data.easf_v_bf_maxa,
|
||||
SCL_EASF_V_BF_MAXB, scl_data->dscl_prog_data.easf_v_bf_maxb,
|
||||
SCL_EASF_V_BF_MINA, scl_data->dscl_prog_data.easf_v_bf_mina,
|
||||
SCL_EASF_V_BF_MINB, scl_data->dscl_prog_data.easf_v_bf_minb);
|
||||
/* DSCL_EASF_V_BF1_PWL_SEGn */
|
||||
REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG0, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg0,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg0,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg0);
|
||||
REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG1, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg1,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg1,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg1);
|
||||
REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG2, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg2,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg2,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg2);
|
||||
REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG3, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg3,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg3,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg3);
|
||||
REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG4, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg4,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg4,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg4);
|
||||
REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG5, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg5,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg5,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg5);
|
||||
REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG6, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg6,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg6,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg6);
|
||||
REG_SET_2(DSCL_EASF_V_BF1_PWL_SEG7, 0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg7,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg7);
|
||||
/* DSCL_EASF_V_BF3_PWL_SEGn */
|
||||
REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG0, 0,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set0,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set0,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set0);
|
||||
REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG1, 0,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set1,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set1,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set1);
|
||||
REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG2, 0,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set2,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set2,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set2);
|
||||
REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG3, 0,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set3,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set3,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set3);
|
||||
REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG4, 0,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set4,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set4,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set4);
|
||||
REG_SET_2(DSCL_EASF_V_BF3_PWL_SEG5, 0,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set5,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set5);
|
||||
PERF_TRACE();
|
||||
}
|
||||
/**
|
||||
* dpp401_dscl_program_easf_h - Program EASF_H
|
||||
*
|
||||
* @dpp_base: High level DPP struct
|
||||
* @scl_data: scalaer_data info
|
||||
*
|
||||
* This is the primary function to program horizontal EASF registers
|
||||
*
|
||||
*/
|
||||
static void dpp401_dscl_program_easf_h(struct dpp *dpp_base, const struct scaler_data *scl_data)
|
||||
{
|
||||
struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
|
||||
|
||||
PERF_TRACE();
|
||||
/* DSCL_EASF_H_MODE */
|
||||
REG_SET_3(DSCL_EASF_H_MODE, 0,
|
||||
SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en,
|
||||
SCL_EASF_H_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_h_sharp_factor,
|
||||
SCL_EASF_H_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_h_ring);
|
||||
|
||||
if (!scl_data->dscl_prog_data.easf_h_en) {
|
||||
PERF_TRACE();
|
||||
return;
|
||||
}
|
||||
|
||||
/* DSCL_EASF_H_BF_CNTL */
|
||||
REG_SET_6(DSCL_EASF_H_BF_CNTL, 0,
|
||||
SCL_EASF_H_BF1_EN, scl_data->dscl_prog_data.easf_h_bf1_en,
|
||||
SCL_EASF_H_BF2_MODE, scl_data->dscl_prog_data.easf_h_bf2_mode,
|
||||
SCL_EASF_H_BF3_MODE, scl_data->dscl_prog_data.easf_h_bf3_mode,
|
||||
SCL_EASF_H_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat1_gain,
|
||||
SCL_EASF_H_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat2_gain,
|
||||
SCL_EASF_H_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_h_bf2_roc_gain);
|
||||
/* DSCL_EASF_H_RINGEST_EVENTAP_REDUCE */
|
||||
REG_SET_2(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE, 0,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg1,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg2);
|
||||
/* DSCL_EASF_H_RINGEST_EVENTAP_GAIN */
|
||||
REG_SET_2(DSCL_EASF_H_RINGEST_EVENTAP_GAIN, 0,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain1,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain2);
|
||||
/* DSCL_EASF_H_BF_FINAL_MAX_MIN */
|
||||
REG_SET_4(DSCL_EASF_H_BF_FINAL_MAX_MIN, 0,
|
||||
SCL_EASF_H_BF_MAXA, scl_data->dscl_prog_data.easf_h_bf_maxa,
|
||||
SCL_EASF_H_BF_MAXB, scl_data->dscl_prog_data.easf_h_bf_maxb,
|
||||
SCL_EASF_H_BF_MINA, scl_data->dscl_prog_data.easf_h_bf_mina,
|
||||
SCL_EASF_H_BF_MINB, scl_data->dscl_prog_data.easf_h_bf_minb);
|
||||
/* DSCL_EASF_H_BF1_PWL_SEGn */
|
||||
REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG0, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg0,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg0,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg0);
|
||||
REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG1, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg1,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg1,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg1);
|
||||
REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG2, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg2,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg2,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg2);
|
||||
REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG3, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg3,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg3,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg3);
|
||||
REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG4, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg4,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg4,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg4);
|
||||
REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG5, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg5,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg5,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg5);
|
||||
REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG6, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg6,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg6,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg6);
|
||||
REG_SET_2(DSCL_EASF_H_BF1_PWL_SEG7, 0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg7,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg7);
|
||||
/* DSCL_EASF_H_BF3_PWL_SEGn */
|
||||
REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG0, 0,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set0,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set0,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set0);
|
||||
REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG1, 0,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set1,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set1,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set1);
|
||||
REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG2, 0,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set2,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set2,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set2);
|
||||
REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG3, 0,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set3,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set3,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set3);
|
||||
REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG4, 0,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set4,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set4,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set4);
|
||||
REG_SET_2(DSCL_EASF_H_BF3_PWL_SEG5, 0,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set5,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set5);
|
||||
PERF_TRACE();
|
||||
}
|
||||
/**
|
||||
* dpp401_dscl_program_easf - Program EASF
|
||||
*
|
||||
@ -669,261 +890,19 @@ static void dpp401_dscl_program_easf(struct dpp *dpp_base, const struct scaler_d
|
||||
struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
|
||||
|
||||
PERF_TRACE();
|
||||
REG_UPDATE(DSCL_SC_MODE,
|
||||
SCL_SC_MATRIX_MODE, scl_data->dscl_prog_data.easf_matrix_mode);
|
||||
REG_UPDATE(DSCL_SC_MODE,
|
||||
/* DSCL_SC_MODE */
|
||||
REG_SET_2(DSCL_SC_MODE, 0,
|
||||
SCL_SC_MATRIX_MODE, scl_data->dscl_prog_data.easf_matrix_mode,
|
||||
SCL_SC_LTONL_EN, scl_data->dscl_prog_data.easf_ltonl_en);
|
||||
/* DSCL_EASF_V_MODE */
|
||||
REG_UPDATE(DSCL_EASF_V_MODE,
|
||||
SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en);
|
||||
REG_UPDATE(DSCL_EASF_V_MODE,
|
||||
SCL_EASF_V_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_v_sharp_factor);
|
||||
REG_UPDATE(DSCL_EASF_V_MODE,
|
||||
SCL_EASF_V_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_v_ring);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_CNTL,
|
||||
SCL_EASF_V_BF1_EN, scl_data->dscl_prog_data.easf_v_bf1_en);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_CNTL,
|
||||
SCL_EASF_V_BF2_MODE, scl_data->dscl_prog_data.easf_v_bf2_mode);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_CNTL,
|
||||
SCL_EASF_V_BF3_MODE, scl_data->dscl_prog_data.easf_v_bf3_mode);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_CNTL,
|
||||
SCL_EASF_V_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat1_gain);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_CNTL,
|
||||
SCL_EASF_V_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat2_gain);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_CNTL,
|
||||
SCL_EASF_V_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_v_bf2_roc_gain);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL1,
|
||||
SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_uptilt);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL1,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt_max);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL2,
|
||||
SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_slope);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL2,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt1_slope);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL3,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_slope);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_3TAP_CNTL3,
|
||||
SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_offset);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg1);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg2);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_GAIN,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain1);
|
||||
REG_UPDATE(DSCL_EASF_V_RINGEST_EVENTAP_GAIN,
|
||||
SCL_EASF_V_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain2);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_V_BF_MAXA, scl_data->dscl_prog_data.easf_v_bf_maxa);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_V_BF_MAXB, scl_data->dscl_prog_data.easf_v_bf_maxb);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_V_BF_MINA, scl_data->dscl_prog_data.easf_v_bf_mina);
|
||||
REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_V_BF_MINB, scl_data->dscl_prog_data.easf_v_bf_minb);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg0);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg0);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg0);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg1);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg1);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg1);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg2);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg2);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg2);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg3);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg3);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg3);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg4);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg4);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg4);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg5);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg5);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg5);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg6);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg6);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
|
||||
SCL_EASF_V_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg6);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG7,
|
||||
SCL_EASF_V_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg7);
|
||||
REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG7,
|
||||
SCL_EASF_V_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg7);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set0);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set0);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set0);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set1);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set1);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set1);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set2);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set2);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set2);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set3);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set3);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set3);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set4);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set4);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
|
||||
SCL_EASF_V_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set4);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG5,
|
||||
SCL_EASF_V_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set5);
|
||||
REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG5,
|
||||
SCL_EASF_V_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set5);
|
||||
/* DSCL_EASF_H_MODE */
|
||||
REG_UPDATE(DSCL_EASF_H_MODE,
|
||||
SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en);
|
||||
REG_UPDATE(DSCL_EASF_H_MODE,
|
||||
SCL_EASF_H_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_h_sharp_factor);
|
||||
REG_UPDATE(DSCL_EASF_H_MODE,
|
||||
SCL_EASF_H_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_h_ring);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_CNTL,
|
||||
SCL_EASF_H_BF1_EN, scl_data->dscl_prog_data.easf_h_bf1_en);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_CNTL,
|
||||
SCL_EASF_H_BF2_MODE, scl_data->dscl_prog_data.easf_h_bf2_mode);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_CNTL,
|
||||
SCL_EASF_H_BF3_MODE, scl_data->dscl_prog_data.easf_h_bf3_mode);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_CNTL,
|
||||
SCL_EASF_H_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat1_gain);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_CNTL,
|
||||
SCL_EASF_H_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat2_gain);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_CNTL,
|
||||
SCL_EASF_H_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_h_bf2_roc_gain);
|
||||
REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg1);
|
||||
REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg2);
|
||||
REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_GAIN,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain1);
|
||||
REG_UPDATE(DSCL_EASF_H_RINGEST_EVENTAP_GAIN,
|
||||
SCL_EASF_H_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain2);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_H_BF_MAXA, scl_data->dscl_prog_data.easf_h_bf_maxa);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_H_BF_MAXB, scl_data->dscl_prog_data.easf_h_bf_maxb);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_H_BF_MINA, scl_data->dscl_prog_data.easf_h_bf_mina);
|
||||
REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
|
||||
SCL_EASF_H_BF_MINB, scl_data->dscl_prog_data.easf_h_bf_minb);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg0);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg0);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg0);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg1);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg1);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg1);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg2);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg2);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg2);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg3);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg3);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg3);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg4);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg4);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg4);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg5);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg5);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg5);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg6);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg6);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
|
||||
SCL_EASF_H_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg6);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG7,
|
||||
SCL_EASF_H_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg7);
|
||||
REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG7,
|
||||
SCL_EASF_H_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg7);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set0);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set0);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set0);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set1);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set1);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set1);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set2);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set2);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set2);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set3);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set3);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set3);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set4);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set4);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
|
||||
SCL_EASF_H_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set4);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG5,
|
||||
SCL_EASF_H_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set5);
|
||||
REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG5,
|
||||
SCL_EASF_H_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set5);
|
||||
/* DSCL_EASF_SC_MATRIX_C0C1, DSCL_EASF_SC_MATRIX_C2C3 */
|
||||
REG_UPDATE(DSCL_SC_MATRIX_C0C1,
|
||||
SCL_SC_MATRIX_C0, scl_data->dscl_prog_data.easf_matrix_c0);
|
||||
REG_UPDATE(DSCL_SC_MATRIX_C0C1,
|
||||
REG_SET_2(DSCL_SC_MATRIX_C0C1, 0,
|
||||
SCL_SC_MATRIX_C0, scl_data->dscl_prog_data.easf_matrix_c0,
|
||||
SCL_SC_MATRIX_C1, scl_data->dscl_prog_data.easf_matrix_c1);
|
||||
REG_UPDATE(DSCL_SC_MATRIX_C2C3,
|
||||
SCL_SC_MATRIX_C2, scl_data->dscl_prog_data.easf_matrix_c2);
|
||||
REG_UPDATE(DSCL_SC_MATRIX_C2C3,
|
||||
REG_SET_2(DSCL_SC_MATRIX_C2C3, 0,
|
||||
SCL_SC_MATRIX_C2, scl_data->dscl_prog_data.easf_matrix_c2,
|
||||
SCL_SC_MATRIX_C3, scl_data->dscl_prog_data.easf_matrix_c3);
|
||||
dpp401_dscl_program_easf_v(dpp_base, scl_data);
|
||||
dpp401_dscl_program_easf_h(dpp_base, scl_data);
|
||||
PERF_TRACE();
|
||||
}
|
||||
/**
|
||||
@ -958,10 +937,11 @@ static void dpp401_dscl_set_isharp_filter(
|
||||
|
||||
REG_UPDATE(ISHARP_DELTA_CTRL,
|
||||
ISHARP_DELTA_LUT_HOST_SELECT, 0);
|
||||
/* LUT data write is auto-indexed. Write index once */
|
||||
REG_SET(ISHARP_DELTA_INDEX, 0,
|
||||
ISHARP_DELTA_INDEX, 0);
|
||||
for (level = 0; level < NUM_LEVELS; level++) {
|
||||
filter_data = filter[level];
|
||||
REG_SET(ISHARP_DELTA_INDEX, 0,
|
||||
ISHARP_DELTA_INDEX, level);
|
||||
REG_SET(ISHARP_DELTA_DATA, 0,
|
||||
ISHARP_DELTA_DATA, filter_data);
|
||||
}
|
||||
@ -976,107 +956,76 @@ static void dpp401_dscl_set_isharp_filter(
|
||||
*
|
||||
*/
|
||||
static void dpp401_dscl_program_isharp(struct dpp *dpp_base,
|
||||
const struct scaler_data *scl_data)
|
||||
const struct scaler_data *scl_data,
|
||||
bool program_isharp_1dlut,
|
||||
bool *bs_coeffs_updated)
|
||||
{
|
||||
struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
|
||||
*bs_coeffs_updated = false;
|
||||
|
||||
PERF_TRACE();
|
||||
/* ISHARP_EN */
|
||||
REG_UPDATE(ISHARP_MODE,
|
||||
ISHARP_EN, scl_data->dscl_prog_data.isharp_en);
|
||||
/* ISHARP_NOISEDET_EN */
|
||||
REG_UPDATE(ISHARP_MODE,
|
||||
ISHARP_NOISEDET_EN, scl_data->dscl_prog_data.isharp_noise_det.enable);
|
||||
/* ISHARP_NOISEDET_MODE */
|
||||
REG_UPDATE(ISHARP_MODE,
|
||||
ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode);
|
||||
/* ISHARP_NOISEDET_UTHRE */
|
||||
REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
|
||||
ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold);
|
||||
/* ISHARP_NOISEDET_DTHRE */
|
||||
REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
|
||||
/* ISHARP_MODE */
|
||||
REG_SET_6(ISHARP_MODE, 0,
|
||||
ISHARP_EN, scl_data->dscl_prog_data.isharp_en,
|
||||
ISHARP_NOISEDET_EN, scl_data->dscl_prog_data.isharp_noise_det.enable,
|
||||
ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode,
|
||||
ISHARP_LBA_MODE, scl_data->dscl_prog_data.isharp_lba.mode,
|
||||
ISHARP_FMT_MODE, scl_data->dscl_prog_data.isharp_fmt.mode,
|
||||
ISHARP_FMT_NORM, scl_data->dscl_prog_data.isharp_fmt.norm);
|
||||
|
||||
/* Skip remaining register programming if ISHARP is disabled */
|
||||
if (!scl_data->dscl_prog_data.isharp_en) {
|
||||
PERF_TRACE();
|
||||
return;
|
||||
}
|
||||
|
||||
/* ISHARP_NOISEDET_THRESHOLD */
|
||||
REG_SET_2(ISHARP_NOISEDET_THRESHOLD, 0,
|
||||
ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold,
|
||||
ISHARP_NOISEDET_DTHRE, scl_data->dscl_prog_data.isharp_noise_det.dthreshold);
|
||||
REG_UPDATE(ISHARP_MODE,
|
||||
ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode);
|
||||
/* ISHARP_NOISEDET_UTHRE */
|
||||
REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
|
||||
ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold);
|
||||
/* ISHARP_NOISEDET_DTHRE */
|
||||
REG_UPDATE(ISHARP_NOISEDET_THRESHOLD,
|
||||
ISHARP_NOISEDET_DTHRE, scl_data->dscl_prog_data.isharp_noise_det.dthreshold);
|
||||
/* ISHARP_NOISEDET_PWL_START_IN */
|
||||
REG_UPDATE(ISHARP_NOISE_GAIN_PWL,
|
||||
ISHARP_NOISEDET_PWL_START_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_start_in);
|
||||
/* ISHARP_NOISEDET_PWL_END_IN */
|
||||
REG_UPDATE(ISHARP_NOISE_GAIN_PWL,
|
||||
ISHARP_NOISEDET_PWL_END_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_end_in);
|
||||
/* ISHARP_NOISEDET_PWL_SLOPE */
|
||||
REG_UPDATE(ISHARP_NOISE_GAIN_PWL,
|
||||
|
||||
/* ISHARP_NOISE_GAIN_PWL */
|
||||
REG_SET_3(ISHARP_NOISE_GAIN_PWL, 0,
|
||||
ISHARP_NOISEDET_PWL_START_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_start_in,
|
||||
ISHARP_NOISEDET_PWL_END_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_end_in,
|
||||
ISHARP_NOISEDET_PWL_SLOPE, scl_data->dscl_prog_data.isharp_noise_det.pwl_slope);
|
||||
/* ISHARP_LBA_MODE */
|
||||
REG_UPDATE(ISHARP_MODE,
|
||||
ISHARP_LBA_MODE, scl_data->dscl_prog_data.isharp_lba.mode);
|
||||
|
||||
/* ISHARP_LBA: IN_SEG, BASE_SEG, SLOPE_SEG */
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG0,
|
||||
ISHARP_LBA_PWL_IN_SEG0, scl_data->dscl_prog_data.isharp_lba.in_seg[0]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG0,
|
||||
ISHARP_LBA_PWL_BASE_SEG0, scl_data->dscl_prog_data.isharp_lba.base_seg[0]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG0,
|
||||
REG_SET_3(ISHARP_LBA_PWL_SEG0, 0,
|
||||
ISHARP_LBA_PWL_IN_SEG0, scl_data->dscl_prog_data.isharp_lba.in_seg[0],
|
||||
ISHARP_LBA_PWL_BASE_SEG0, scl_data->dscl_prog_data.isharp_lba.base_seg[0],
|
||||
ISHARP_LBA_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.isharp_lba.slope_seg[0]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG1,
|
||||
ISHARP_LBA_PWL_IN_SEG1, scl_data->dscl_prog_data.isharp_lba.in_seg[1]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG1,
|
||||
ISHARP_LBA_PWL_BASE_SEG1, scl_data->dscl_prog_data.isharp_lba.base_seg[1]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG1,
|
||||
REG_SET_3(ISHARP_LBA_PWL_SEG1, 0,
|
||||
ISHARP_LBA_PWL_IN_SEG1, scl_data->dscl_prog_data.isharp_lba.in_seg[1],
|
||||
ISHARP_LBA_PWL_BASE_SEG1, scl_data->dscl_prog_data.isharp_lba.base_seg[1],
|
||||
ISHARP_LBA_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.isharp_lba.slope_seg[1]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG2,
|
||||
ISHARP_LBA_PWL_IN_SEG2, scl_data->dscl_prog_data.isharp_lba.in_seg[2]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG2,
|
||||
ISHARP_LBA_PWL_BASE_SEG2, scl_data->dscl_prog_data.isharp_lba.base_seg[2]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG2,
|
||||
REG_SET_3(ISHARP_LBA_PWL_SEG2, 0,
|
||||
ISHARP_LBA_PWL_IN_SEG2, scl_data->dscl_prog_data.isharp_lba.in_seg[2],
|
||||
ISHARP_LBA_PWL_BASE_SEG2, scl_data->dscl_prog_data.isharp_lba.base_seg[2],
|
||||
ISHARP_LBA_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.isharp_lba.slope_seg[2]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG3,
|
||||
ISHARP_LBA_PWL_IN_SEG3, scl_data->dscl_prog_data.isharp_lba.in_seg[3]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG3,
|
||||
ISHARP_LBA_PWL_BASE_SEG3, scl_data->dscl_prog_data.isharp_lba.base_seg[3]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG3,
|
||||
REG_SET_3(ISHARP_LBA_PWL_SEG3, 0,
|
||||
ISHARP_LBA_PWL_IN_SEG3, scl_data->dscl_prog_data.isharp_lba.in_seg[3],
|
||||
ISHARP_LBA_PWL_BASE_SEG3, scl_data->dscl_prog_data.isharp_lba.base_seg[3],
|
||||
ISHARP_LBA_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.isharp_lba.slope_seg[3]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG4,
|
||||
ISHARP_LBA_PWL_IN_SEG4, scl_data->dscl_prog_data.isharp_lba.in_seg[4]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG4,
|
||||
ISHARP_LBA_PWL_BASE_SEG4, scl_data->dscl_prog_data.isharp_lba.base_seg[4]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG4,
|
||||
REG_SET_3(ISHARP_LBA_PWL_SEG4, 0,
|
||||
ISHARP_LBA_PWL_IN_SEG4, scl_data->dscl_prog_data.isharp_lba.in_seg[4],
|
||||
ISHARP_LBA_PWL_BASE_SEG4, scl_data->dscl_prog_data.isharp_lba.base_seg[4],
|
||||
ISHARP_LBA_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.isharp_lba.slope_seg[4]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG5,
|
||||
ISHARP_LBA_PWL_IN_SEG5, scl_data->dscl_prog_data.isharp_lba.in_seg[5]);
|
||||
REG_UPDATE(ISHARP_LBA_PWL_SEG5,
|
||||
REG_SET_2(ISHARP_LBA_PWL_SEG5, 0,
|
||||
ISHARP_LBA_PWL_IN_SEG5, scl_data->dscl_prog_data.isharp_lba.in_seg[5],
|
||||
ISHARP_LBA_PWL_BASE_SEG5, scl_data->dscl_prog_data.isharp_lba.base_seg[5]);
|
||||
|
||||
/* ISHARP_FMT_MODE */
|
||||
REG_UPDATE(ISHARP_MODE,
|
||||
ISHARP_FMT_MODE, scl_data->dscl_prog_data.isharp_fmt.mode);
|
||||
/* ISHARP_FMT_NORM */
|
||||
REG_UPDATE(ISHARP_MODE,
|
||||
ISHARP_FMT_NORM, scl_data->dscl_prog_data.isharp_fmt.norm);
|
||||
/* ISHARP_DELTA_LUT */
|
||||
dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
|
||||
/* ISHARP_NLDELTA_SCLIP_EN_P */
|
||||
REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
|
||||
ISHARP_NLDELTA_SCLIP_EN_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_p);
|
||||
/* ISHARP_NLDELTA_SCLIP_PIVOT_P */
|
||||
REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
|
||||
ISHARP_NLDELTA_SCLIP_PIVOT_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_p);
|
||||
/* ISHARP_NLDELTA_SCLIP_SLOPE_P */
|
||||
REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
|
||||
ISHARP_NLDELTA_SCLIP_SLOPE_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_p);
|
||||
/* ISHARP_NLDELTA_SCLIP_EN_N */
|
||||
REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
|
||||
ISHARP_NLDELTA_SCLIP_EN_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_n);
|
||||
/* ISHARP_NLDELTA_SCLIP_PIVOT_N */
|
||||
REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
|
||||
ISHARP_NLDELTA_SCLIP_PIVOT_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_n);
|
||||
/* ISHARP_NLDELTA_SCLIP_SLOPE_N */
|
||||
REG_UPDATE(ISHARP_NLDELTA_SOFT_CLIP,
|
||||
if (!program_isharp_1dlut)
|
||||
dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
|
||||
|
||||
/* ISHARP_NLDELTA_SOFT_CLIP */
|
||||
REG_SET_6(ISHARP_NLDELTA_SOFT_CLIP, 0,
|
||||
ISHARP_NLDELTA_SCLIP_EN_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_p,
|
||||
ISHARP_NLDELTA_SCLIP_PIVOT_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_p,
|
||||
ISHARP_NLDELTA_SCLIP_SLOPE_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_p,
|
||||
ISHARP_NLDELTA_SCLIP_EN_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_n,
|
||||
ISHARP_NLDELTA_SCLIP_PIVOT_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_n,
|
||||
ISHARP_NLDELTA_SCLIP_SLOPE_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_n);
|
||||
|
||||
/* Blur and Scale Coefficients - SCL_COEF_RAM_TAP_SELECT */
|
||||
@ -1086,12 +1035,14 @@ static void dpp401_dscl_program_isharp(struct dpp *dpp_base,
|
||||
dpp, scl_data->taps.v_taps,
|
||||
SCL_COEF_VERTICAL_BLUR_SCALE,
|
||||
scl_data->dscl_prog_data.filter_blur_scale_v);
|
||||
*bs_coeffs_updated = true;
|
||||
}
|
||||
if (scl_data->dscl_prog_data.filter_blur_scale_h) {
|
||||
dpp401_dscl_set_scaler_filter(
|
||||
dpp, scl_data->taps.h_taps,
|
||||
SCL_COEF_HORIZONTAL_BLUR_SCALE,
|
||||
scl_data->dscl_prog_data.filter_blur_scale_h);
|
||||
*bs_coeffs_updated = true;
|
||||
}
|
||||
}
|
||||
PERF_TRACE();
|
||||
@ -1122,12 +1073,29 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
|
||||
dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
|
||||
bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
|
||||
&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
|
||||
bool program_isharp_1dlut = false;
|
||||
bool bs_coeffs_updated = false;
|
||||
|
||||
|
||||
if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
|
||||
return;
|
||||
|
||||
PERF_TRACE();
|
||||
|
||||
/* If only sharpness has changed, then only update 1dlut, then return */
|
||||
if (scl_data->dscl_prog_data.isharp_en &&
|
||||
(dpp->scl_data.dscl_prog_data.sharpness_level
|
||||
!= scl_data->dscl_prog_data.sharpness_level)) {
|
||||
/* ISHARP_DELTA_LUT */
|
||||
dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
|
||||
dpp->scl_data.dscl_prog_data.sharpness_level = scl_data->dscl_prog_data.sharpness_level;
|
||||
dpp->scl_data.dscl_prog_data.isharp_delta = scl_data->dscl_prog_data.isharp_delta;
|
||||
|
||||
if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
|
||||
return;
|
||||
program_isharp_1dlut = true;
|
||||
}
|
||||
|
||||
dpp->scl_data = *scl_data;
|
||||
|
||||
if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
|
||||
@ -1181,7 +1149,7 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
|
||||
if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) {
|
||||
if (dpp->base.ctx->dc->config.prefer_easf)
|
||||
dpp401_dscl_disable_easf(dpp_base, scl_data);
|
||||
dpp401_dscl_program_isharp(dpp_base, scl_data);
|
||||
dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1208,12 +1176,18 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
|
||||
SCL_V_NUM_TAPS_C, v_num_taps_c,
|
||||
SCL_H_NUM_TAPS_C, h_num_taps_c);
|
||||
|
||||
dpp401_dscl_set_scl_filter(dpp, scl_data, ycbcr);
|
||||
/* ISharp configuration
|
||||
* - B&S coeffs are written to same coeff RAM as WB scaler coeffs
|
||||
* - coeff RAM toggle is in EASF programming
|
||||
* - if we are only programming B&S coeffs, then need to reprogram
|
||||
* WB scaler coeffs and toggle coeff RAM together
|
||||
*/
|
||||
//if (dpp->base.ctx->dc->config.prefer_easf)
|
||||
dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
|
||||
|
||||
dpp401_dscl_set_scl_filter(dpp, scl_data, ycbcr, bs_coeffs_updated);
|
||||
/* Edge adaptive scaler function configuration */
|
||||
if (dpp->base.ctx->dc->config.prefer_easf)
|
||||
dpp401_dscl_program_easf(dpp_base, scl_data);
|
||||
/* isharp configuration */
|
||||
//if (dpp->base.ctx->dc->config.prefer_easf)
|
||||
dpp401_dscl_program_isharp(dpp_base, scl_data);
|
||||
PERF_TRACE();
|
||||
}
|
||||
|
@ -147,37 +147,6 @@ void dcn35_init_hw(struct dc *dc)
|
||||
hws->funcs.bios_golden_init(dc);
|
||||
}
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
|
||||
|
||||
/* Disable gating for PHYASYMCLK. This will be enabled in dccg if needed */
|
||||
REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYBSYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYCSYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYDSYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYESYMCLK_ROOT_GATE_DISABLE, 1);
|
||||
|
||||
REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL4,
|
||||
DPIASYMCLK0_GATE_DISABLE, 0,
|
||||
DPIASYMCLK1_GATE_DISABLE, 0,
|
||||
DPIASYMCLK2_GATE_DISABLE, 0,
|
||||
DPIASYMCLK3_GATE_DISABLE, 0);
|
||||
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL5, 0xFFFFFFFF);
|
||||
REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
|
||||
DTBCLK_P0_GATE_DISABLE, 0,
|
||||
DTBCLK_P1_GATE_DISABLE, 0,
|
||||
DTBCLK_P2_GATE_DISABLE, 0,
|
||||
DTBCLK_P3_GATE_DISABLE, 0);
|
||||
REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
|
||||
DPSTREAMCLK0_GATE_DISABLE, 0,
|
||||
DPSTREAMCLK1_GATE_DISABLE, 0,
|
||||
DPSTREAMCLK2_GATE_DISABLE, 0,
|
||||
DPSTREAMCLK3_GATE_DISABLE, 0);
|
||||
|
||||
}
|
||||
|
||||
// Initialize the dccg
|
||||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
@ -305,20 +274,6 @@ void dcn35_init_hw(struct dc *dc)
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
|
||||
|
||||
REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_FE_GATE_DISABLE, 0,
|
||||
SYMCLKB_FE_GATE_DISABLE, 0,
|
||||
SYMCLKC_FE_GATE_DISABLE, 0,
|
||||
SYMCLKD_FE_GATE_DISABLE, 0,
|
||||
SYMCLKE_FE_GATE_DISABLE, 0);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, HDMICHARCLK0_GATE_DISABLE, 0);
|
||||
REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_GATE_DISABLE, 0,
|
||||
SYMCLKB_GATE_DISABLE, 0,
|
||||
SYMCLKC_GATE_DISABLE, 0,
|
||||
SYMCLKD_GATE_DISABLE, 0,
|
||||
SYMCLKE_GATE_DISABLE, 0);
|
||||
|
||||
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,9 @@
|
||||
|
||||
#include "dml2/dml2_wrapper.h"
|
||||
|
||||
#include "spl/dc_spl_scl_easf_filters.h"
|
||||
#include "spl/dc_spl_isharp_filters.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
enum dcn401_clk_src_array_id {
|
||||
@ -2126,6 +2129,10 @@ static bool dcn401_resource_construct(
|
||||
dc->dml2_options.max_segments_per_hubp = 20;
|
||||
dc->dml2_options.det_segment_size = DCN4_01_CRB_SEGMENT_SIZE_KB;
|
||||
|
||||
/* SPL */
|
||||
spl_init_easf_filter_coeffs();
|
||||
spl_init_blur_scale_coeffs();
|
||||
|
||||
return true;
|
||||
|
||||
create_fail:
|
||||
|
@ -23,7 +23,7 @@
|
||||
# Makefile for the 'spl' sub-component of DAL.
|
||||
# It provides the scaling library interface.
|
||||
|
||||
SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_filters_old.o dc_spl_isharp_filters.o
|
||||
SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_easf_filters.o dc_spl_isharp_filters.o dc_spl_filters.o spl_fixpt31_32.o spl_custom_float.o
|
||||
|
||||
AMD_DAL_SPL = $(addprefix $(AMDDALPATH)/dc/spl/,$(SPL))
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
15
drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c
Normal file
15
drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.c
Normal file
@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "dc_spl_filters.h"
|
||||
|
||||
void convert_filter_s1_10_to_s1_12(const uint16_t *s1_10_filter,
|
||||
uint16_t *s1_12_filter, int num_taps)
|
||||
{
|
||||
int num_entries = NUM_PHASES_COEFF * num_taps;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_entries; i++)
|
||||
*(s1_12_filter + i) = *(s1_10_filter + i) * 4;
|
||||
}
|
15
drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h
Normal file
15
drivers/gpu/drm/amd/display/dc/spl/dc_spl_filters.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
/* Copyright 2024 Advanced Micro Devices, Inc. */
|
||||
|
||||
#ifndef __DC_SPL_FILTERS_H__
|
||||
#define __DC_SPL_FILTERS_H__
|
||||
|
||||
#include "dc_spl_types.h"
|
||||
|
||||
#define NUM_PHASES_COEFF 33
|
||||
|
||||
void convert_filter_s1_10_to_s1_12(const uint16_t *s1_10_filter,
|
||||
uint16_t *s1_12_filter, int num_taps);
|
||||
|
||||
#endif /* __DC_SPL_FILTERS_H__ */
|
@ -2,6 +2,8 @@
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "spl_debug.h"
|
||||
#include "dc_spl_filters.h"
|
||||
#include "dc_spl_isharp_filters.h"
|
||||
|
||||
//========================================
|
||||
@ -15,7 +17,7 @@
|
||||
// C_start = 40.000000
|
||||
// C_end = 64.000000
|
||||
//========================================
|
||||
static const uint32_t filter_isharp_1D_lut_0[32] = {
|
||||
static const uint32_t filter_isharp_1D_lut_0[ISHARP_LUT_TABLE_SIZE] = {
|
||||
0x02010000,
|
||||
0x0A070503,
|
||||
0x1614100D,
|
||||
@ -61,7 +63,7 @@ static const uint32_t filter_isharp_1D_lut_0[32] = {
|
||||
// C_end = 127.000000
|
||||
//========================================
|
||||
|
||||
static const uint32_t filter_isharp_1D_lut_0p5x[32] = {
|
||||
static const uint32_t filter_isharp_1D_lut_0p5x[ISHARP_LUT_TABLE_SIZE] = {
|
||||
0x00000000,
|
||||
0x02020101,
|
||||
0x06050403,
|
||||
@ -106,7 +108,7 @@ static const uint32_t filter_isharp_1D_lut_0p5x[32] = {
|
||||
// C_start = 96.000000
|
||||
// C_end = 127.000000
|
||||
//========================================
|
||||
static const uint32_t filter_isharp_1D_lut_1p0x[32] = {
|
||||
static const uint32_t filter_isharp_1D_lut_1p0x[ISHARP_LUT_TABLE_SIZE] = {
|
||||
0x01000000,
|
||||
0x05040302,
|
||||
0x0B0A0806,
|
||||
@ -151,7 +153,7 @@ static const uint32_t filter_isharp_1D_lut_1p0x[32] = {
|
||||
// C_start = 96.000000
|
||||
// C_end = 127.000000
|
||||
//========================================
|
||||
static const uint32_t filter_isharp_1D_lut_1p5x[32] = {
|
||||
static const uint32_t filter_isharp_1D_lut_1p5x[ISHARP_LUT_TABLE_SIZE] = {
|
||||
0x01010000,
|
||||
0x07050402,
|
||||
0x110F0C0A,
|
||||
@ -196,7 +198,7 @@ static const uint32_t filter_isharp_1D_lut_1p5x[32] = {
|
||||
// C_start = 40.000000
|
||||
// C_end = 127.000000
|
||||
//========================================
|
||||
static const uint32_t filter_isharp_1D_lut_2p0x[32] = {
|
||||
static const uint32_t filter_isharp_1D_lut_2p0x[ISHARP_LUT_TABLE_SIZE] = {
|
||||
0x02010000,
|
||||
0x0A070503,
|
||||
0x1614100D,
|
||||
@ -230,6 +232,53 @@ static const uint32_t filter_isharp_1D_lut_2p0x[32] = {
|
||||
0x080B0D0E,
|
||||
0x00020406,
|
||||
};
|
||||
//========================================
|
||||
// Delta Gain 1DLUT
|
||||
// LUT content is packed as 4-bytes into one DWORD/entry
|
||||
// A_start = 0.000000
|
||||
// A_end = 10.000000
|
||||
// A_gain = 3.000000
|
||||
// B_start = 11.000000
|
||||
// B_end = 127.000000
|
||||
// C_start = 40.000000
|
||||
// C_end = 127.000000
|
||||
//========================================
|
||||
static const uint32_t filter_isharp_1D_lut_3p0x[ISHARP_LUT_TABLE_SIZE] = {
|
||||
0x03010000,
|
||||
0x0F0B0805,
|
||||
0x211E1813,
|
||||
0x2B292624,
|
||||
0x3533302E,
|
||||
0x3E3C3A37,
|
||||
0x46444240,
|
||||
0x4D4B4A48,
|
||||
0x5352504F,
|
||||
0x59575655,
|
||||
0x5D5C5B5A,
|
||||
0x61605F5E,
|
||||
0x64646362,
|
||||
0x66666565,
|
||||
0x68686767,
|
||||
0x68686868,
|
||||
0x68686868,
|
||||
0x67676868,
|
||||
0x65656666,
|
||||
0x62636464,
|
||||
0x5E5F6061,
|
||||
0x5A5B5C5D,
|
||||
0x55565759,
|
||||
0x4F505253,
|
||||
0x484A4B4D,
|
||||
0x40424446,
|
||||
0x373A3C3E,
|
||||
0x2E303335,
|
||||
0x2426292B,
|
||||
0x191B1E21,
|
||||
0x0D101316,
|
||||
0x0003060A,
|
||||
};
|
||||
|
||||
//========================================
|
||||
// Wide scaler coefficients
|
||||
//========================================================
|
||||
// <using> gen_scaler_coeffs.m
|
||||
@ -284,7 +333,7 @@ static const uint16_t filter_isharp_wide_6tap_64p[198] = {
|
||||
// <CoefType> Blur & Scale LPF
|
||||
// <CoefQuant> S1.10
|
||||
//========================================================
|
||||
static const uint16_t filter_isharp_bs_4tap_64p[198] = {
|
||||
static const uint16_t filter_isharp_bs_4tap_in_6_64p[198] = {
|
||||
0x0000, 0x00E5, 0x0237, 0x00E4, 0x0000, 0x0000,
|
||||
0x0000, 0x00DE, 0x0237, 0x00EB, 0x0000, 0x0000,
|
||||
0x0000, 0x00D7, 0x0236, 0x00F2, 0x0001, 0x0000,
|
||||
@ -319,6 +368,138 @@ static const uint16_t filter_isharp_bs_4tap_64p[198] = {
|
||||
0x0000, 0x003B, 0x01CF, 0x01C2, 0x0034, 0x0000,
|
||||
0x0000, 0x0037, 0x01C9, 0x01C9, 0x0037, 0x0000
|
||||
};
|
||||
//========================================================
|
||||
// <using> gen_BlurScale_coeffs.m
|
||||
// <date> 25-Apr-2022
|
||||
// <num_taps> 4
|
||||
// <num_phases> 64
|
||||
// <CoefType> Blur & Scale LPF
|
||||
// <CoefQuant> S1.10
|
||||
//========================================================
|
||||
static const uint16_t filter_isharp_bs_4tap_64p[132] = {
|
||||
0x00E5, 0x0237, 0x00E4, 0x0000,
|
||||
0x00DE, 0x0237, 0x00EB, 0x0000,
|
||||
0x00D7, 0x0236, 0x00F2, 0x0001,
|
||||
0x00D0, 0x0235, 0x00FA, 0x0001,
|
||||
0x00C9, 0x0234, 0x0101, 0x0002,
|
||||
0x00C2, 0x0233, 0x0108, 0x0003,
|
||||
0x00BB, 0x0232, 0x0110, 0x0003,
|
||||
0x00B5, 0x0230, 0x0117, 0x0004,
|
||||
0x00AE, 0x022E, 0x011F, 0x0005,
|
||||
0x00A8, 0x022C, 0x0126, 0x0006,
|
||||
0x00A2, 0x022A, 0x012D, 0x0007,
|
||||
0x009C, 0x0228, 0x0134, 0x0008,
|
||||
0x0096, 0x0225, 0x013C, 0x0009,
|
||||
0x0090, 0x0222, 0x0143, 0x000B,
|
||||
0x008A, 0x021F, 0x014B, 0x000C,
|
||||
0x0085, 0x021C, 0x0151, 0x000E,
|
||||
0x007F, 0x0218, 0x015A, 0x000F,
|
||||
0x007A, 0x0215, 0x0160, 0x0011,
|
||||
0x0074, 0x0211, 0x0168, 0x0013,
|
||||
0x006F, 0x020D, 0x016F, 0x0015,
|
||||
0x006A, 0x0209, 0x0176, 0x0017,
|
||||
0x0065, 0x0204, 0x017E, 0x0019,
|
||||
0x0060, 0x0200, 0x0185, 0x001B,
|
||||
0x005C, 0x01FB, 0x018C, 0x001D,
|
||||
0x0057, 0x01F6, 0x0193, 0x0020,
|
||||
0x0053, 0x01F1, 0x019A, 0x0022,
|
||||
0x004E, 0x01EC, 0x01A1, 0x0025,
|
||||
0x004A, 0x01E6, 0x01A8, 0x0028,
|
||||
0x0046, 0x01E1, 0x01AF, 0x002A,
|
||||
0x0042, 0x01DB, 0x01B6, 0x002D,
|
||||
0x003F, 0x01D5, 0x01BB, 0x0031,
|
||||
0x003B, 0x01CF, 0x01C2, 0x0034,
|
||||
0x0037, 0x01C9, 0x01C9, 0x0037,
|
||||
};
|
||||
//========================================================
|
||||
// <using> gen_BlurScale_coeffs.m
|
||||
// <date> 09-Jun-2022
|
||||
// <num_taps> 3
|
||||
// <num_phases> 64
|
||||
// <CoefType> Blur & Scale LPF
|
||||
// <CoefQuant> S1.10
|
||||
//========================================================
|
||||
static const uint16_t filter_isharp_bs_3tap_64p[99] = {
|
||||
0x0200, 0x0200, 0x0000,
|
||||
0x01F6, 0x0206, 0x0004,
|
||||
0x01EC, 0x020B, 0x0009,
|
||||
0x01E2, 0x0211, 0x000D,
|
||||
0x01D8, 0x0216, 0x0012,
|
||||
0x01CE, 0x021C, 0x0016,
|
||||
0x01C4, 0x0221, 0x001B,
|
||||
0x01BA, 0x0226, 0x0020,
|
||||
0x01B0, 0x022A, 0x0026,
|
||||
0x01A6, 0x022F, 0x002B,
|
||||
0x019C, 0x0233, 0x0031,
|
||||
0x0192, 0x0238, 0x0036,
|
||||
0x0188, 0x023C, 0x003C,
|
||||
0x017E, 0x0240, 0x0042,
|
||||
0x0174, 0x0244, 0x0048,
|
||||
0x016A, 0x0248, 0x004E,
|
||||
0x0161, 0x024A, 0x0055,
|
||||
0x0157, 0x024E, 0x005B,
|
||||
0x014D, 0x0251, 0x0062,
|
||||
0x0144, 0x0253, 0x0069,
|
||||
0x013A, 0x0256, 0x0070,
|
||||
0x0131, 0x0258, 0x0077,
|
||||
0x0127, 0x025B, 0x007E,
|
||||
0x011E, 0x025C, 0x0086,
|
||||
0x0115, 0x025E, 0x008D,
|
||||
0x010B, 0x0260, 0x0095,
|
||||
0x0102, 0x0262, 0x009C,
|
||||
0x00F9, 0x0263, 0x00A4,
|
||||
0x00F0, 0x0264, 0x00AC,
|
||||
0x00E7, 0x0265, 0x00B4,
|
||||
0x00DF, 0x0264, 0x00BD,
|
||||
0x00D6, 0x0265, 0x00C5,
|
||||
0x00CD, 0x0266, 0x00CD,
|
||||
};
|
||||
|
||||
/* Converted Blur & Scale coeff tables from S1.10 to S1.12 */
|
||||
static uint16_t filter_isharp_bs_4tap_in_6_64p_s1_12[198];
|
||||
static uint16_t filter_isharp_bs_4tap_64p_s1_12[132];
|
||||
static uint16_t filter_isharp_bs_3tap_64p_s1_12[99];
|
||||
|
||||
/* Pre-generated 1DLUT for given setup and sharpness level */
|
||||
struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = {
|
||||
{
|
||||
0, 0,
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
}
|
||||
},
|
||||
{
|
||||
0, 0,
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
}
|
||||
},
|
||||
{
|
||||
0, 0,
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
}
|
||||
},
|
||||
{
|
||||
0, 0,
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_0(void)
|
||||
{
|
||||
return filter_isharp_1D_lut_0;
|
||||
@ -339,11 +520,165 @@ const uint32_t *spl_get_filter_isharp_1D_lut_2p0x(void)
|
||||
{
|
||||
return filter_isharp_1D_lut_2p0x;
|
||||
}
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_3p0x(void)
|
||||
{
|
||||
return filter_isharp_1D_lut_3p0x;
|
||||
}
|
||||
const uint16_t *spl_get_filter_isharp_wide_6tap_64p(void)
|
||||
{
|
||||
return filter_isharp_wide_6tap_64p;
|
||||
}
|
||||
const uint16_t *spl_get_filter_isharp_bs_4tap_64p(void)
|
||||
uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void)
|
||||
{
|
||||
return filter_isharp_bs_4tap_64p;
|
||||
return filter_isharp_bs_4tap_in_6_64p_s1_12;
|
||||
}
|
||||
uint16_t *spl_get_filter_isharp_bs_4tap_64p(void)
|
||||
{
|
||||
return filter_isharp_bs_4tap_64p_s1_12;
|
||||
}
|
||||
uint16_t *spl_get_filter_isharp_bs_3tap_64p(void)
|
||||
{
|
||||
return filter_isharp_bs_3tap_64p_s1_12;
|
||||
}
|
||||
|
||||
static unsigned int spl_calculate_sharpness_level(int discrete_sharpness_level, enum system_setup setup,
|
||||
struct spl_sharpness_range sharpness_range)
|
||||
{
|
||||
unsigned int sharpness_level = 0;
|
||||
|
||||
int min_sharpness, max_sharpness, mid_sharpness;
|
||||
|
||||
switch (setup) {
|
||||
|
||||
case HDR_L:
|
||||
min_sharpness = sharpness_range.hdr_rgb_min;
|
||||
max_sharpness = sharpness_range.hdr_rgb_max;
|
||||
mid_sharpness = sharpness_range.hdr_rgb_mid;
|
||||
break;
|
||||
case HDR_NL:
|
||||
/* currently no use case, use Non-linear SDR values for now */
|
||||
case SDR_NL:
|
||||
min_sharpness = sharpness_range.sdr_yuv_min;
|
||||
max_sharpness = sharpness_range.sdr_yuv_max;
|
||||
mid_sharpness = sharpness_range.sdr_yuv_mid;
|
||||
break;
|
||||
case SDR_L:
|
||||
default:
|
||||
min_sharpness = sharpness_range.sdr_rgb_min;
|
||||
max_sharpness = sharpness_range.sdr_rgb_max;
|
||||
mid_sharpness = sharpness_range.sdr_rgb_mid;
|
||||
break;
|
||||
}
|
||||
|
||||
int lower_half_step_size = (mid_sharpness - min_sharpness) / 5;
|
||||
int upper_half_step_size = (max_sharpness - mid_sharpness) / 5;
|
||||
|
||||
// lower half linear approximation
|
||||
if (discrete_sharpness_level < 5)
|
||||
sharpness_level = min_sharpness + (lower_half_step_size * discrete_sharpness_level);
|
||||
// upper half linear approximation
|
||||
else
|
||||
sharpness_level = mid_sharpness + (upper_half_step_size * (discrete_sharpness_level - 5));
|
||||
|
||||
return sharpness_level;
|
||||
}
|
||||
|
||||
void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup,
|
||||
struct adaptive_sharpness sharpness)
|
||||
{
|
||||
uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
|
||||
struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level;
|
||||
int j;
|
||||
int size_1dlut;
|
||||
int sharp_calc_int;
|
||||
uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
|
||||
|
||||
/* Custom sharpnessX1000 value */
|
||||
unsigned int sharpnessX1000 = spl_calculate_sharpness_level(sharpness.sharpness_level,
|
||||
setup, sharpness.sharpness_range);
|
||||
sharp_level = spl_fixpt_from_fraction(sharpnessX1000, 1000);
|
||||
|
||||
/*
|
||||
* Check if pregen 1dlut table is already precalculated
|
||||
* If numer/denom is different, then recalculate
|
||||
*/
|
||||
if ((filter_isharp_1D_lut_pregen[setup].sharpness_numer == sharpnessX1000) &&
|
||||
(filter_isharp_1D_lut_pregen[setup].sharpness_denom == 1000))
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
* Calculate LUT_128_gained with this equation:
|
||||
*
|
||||
* LUT_128_gained[i] = (uint8)(0.5 + min(255,(double)(LUT_128[i])*sharpLevel/iGain))
|
||||
* where LUT_128[i] is contents of 3p0x isharp 1dlut
|
||||
* where sharpLevel is desired sharpness level
|
||||
* where iGain is base sharpness level 3.0
|
||||
* where LUT_128_gained[i] is adjusted 1dlut value based on desired sharpness level
|
||||
*/
|
||||
byte_ptr_1dlut_src = (uint8_t *)filter_isharp_1D_lut_3p0x;
|
||||
byte_ptr_1dlut_dst = (uint8_t *)filter_pregen_store;
|
||||
size_1dlut = sizeof(filter_isharp_1D_lut_3p0x);
|
||||
memset(byte_ptr_1dlut_dst, 0, size_1dlut);
|
||||
for (j = 0; j < size_1dlut; j++) {
|
||||
sharp_base = spl_fixpt_from_int((int)*byte_ptr_1dlut_src);
|
||||
sharp_calc = spl_fixpt_mul(sharp_base, sharp_level);
|
||||
sharp_calc = spl_fixpt_div(sharp_calc, spl_fixpt_from_int(3));
|
||||
sharp_calc = spl_fixpt_min(spl_fixpt_from_int(255), sharp_calc);
|
||||
sharp_calc = spl_fixpt_add(sharp_calc, spl_fixpt_from_fraction(1, 2));
|
||||
sharp_calc_int = spl_fixpt_floor(sharp_calc);
|
||||
/* Clamp it at 0x7F so it doesn't wrap */
|
||||
if (sharp_calc_int > 127)
|
||||
sharp_calc_int = 127;
|
||||
*byte_ptr_1dlut_dst = (uint8_t)sharp_calc_int;
|
||||
|
||||
byte_ptr_1dlut_src++;
|
||||
byte_ptr_1dlut_dst++;
|
||||
}
|
||||
|
||||
/* Update 1dlut table and sharpness level */
|
||||
memcpy((void *)filter_isharp_1D_lut_pregen[setup].value, (void *)filter_pregen_store, size_1dlut);
|
||||
filter_isharp_1D_lut_pregen[setup].sharpness_numer = sharpnessX1000;
|
||||
filter_isharp_1D_lut_pregen[setup].sharpness_denom = 1000;
|
||||
}
|
||||
|
||||
uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup)
|
||||
{
|
||||
return filter_isharp_1D_lut_pregen[setup].value;
|
||||
}
|
||||
|
||||
void spl_init_blur_scale_coeffs(void)
|
||||
{
|
||||
convert_filter_s1_10_to_s1_12(filter_isharp_bs_3tap_64p,
|
||||
filter_isharp_bs_3tap_64p_s1_12, 3);
|
||||
convert_filter_s1_10_to_s1_12(filter_isharp_bs_4tap_64p,
|
||||
filter_isharp_bs_4tap_64p_s1_12, 4);
|
||||
convert_filter_s1_10_to_s1_12(filter_isharp_bs_4tap_in_6_64p,
|
||||
filter_isharp_bs_4tap_in_6_64p_s1_12, 6);
|
||||
}
|
||||
|
||||
uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps)
|
||||
{
|
||||
if (taps == 3)
|
||||
return spl_get_filter_isharp_bs_3tap_64p();
|
||||
else if (taps == 4)
|
||||
return spl_get_filter_isharp_bs_4tap_64p();
|
||||
else if (taps == 6)
|
||||
return spl_get_filter_isharp_bs_4tap_in_6_64p();
|
||||
else {
|
||||
/* should never happen, bug */
|
||||
SPL_BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
|
||||
const struct spl_scaler_data *data)
|
||||
{
|
||||
dscl_prog_data->filter_blur_scale_h =
|
||||
spl_dscl_get_blur_scale_coeffs_64p(data->taps.h_taps);
|
||||
|
||||
dscl_prog_data->filter_blur_scale_v =
|
||||
spl_dscl_get_blur_scale_coeffs_64p(data->taps.v_taps);
|
||||
}
|
||||
|
||||
|
@ -7,11 +7,44 @@
|
||||
|
||||
#include "dc_spl_types.h"
|
||||
|
||||
#define ISHARP_LUT_TABLE_SIZE 32
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_0(void);
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_0p5x(void);
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_1p0x(void);
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_1p5x(void);
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_2p0x(void);
|
||||
const uint16_t *spl_get_filter_isharp_bs_4tap_64p(void);
|
||||
const uint32_t *spl_get_filter_isharp_1D_lut_3p0x(void);
|
||||
uint16_t *spl_get_filter_isharp_bs_4tap_in_6_64p(void);
|
||||
uint16_t *spl_get_filter_isharp_bs_4tap_64p(void);
|
||||
uint16_t *spl_get_filter_isharp_bs_3tap_64p(void);
|
||||
const uint16_t *spl_get_filter_isharp_wide_6tap_64p(void);
|
||||
uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps);
|
||||
|
||||
struct scale_ratio_to_sharpness_level_lookup {
|
||||
unsigned int ratio_numer;
|
||||
unsigned int ratio_denom;
|
||||
unsigned int sharpness_numer;
|
||||
unsigned int sharpness_denom;
|
||||
};
|
||||
|
||||
struct isharp_1D_lut_pregen {
|
||||
unsigned int sharpness_numer;
|
||||
unsigned int sharpness_denom;
|
||||
uint32_t value[ISHARP_LUT_TABLE_SIZE];
|
||||
};
|
||||
|
||||
enum system_setup {
|
||||
SDR_NL = 0,
|
||||
SDR_L,
|
||||
HDR_NL,
|
||||
HDR_L,
|
||||
NUM_SHARPNESS_SETUPS
|
||||
};
|
||||
|
||||
void spl_init_blur_scale_coeffs(void);
|
||||
void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
|
||||
const struct spl_scaler_data *data);
|
||||
|
||||
void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup, struct adaptive_sharpness sharpness);
|
||||
uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup);
|
||||
#endif /* __DC_SPL_ISHARP_FILTERS_H__ */
|
||||
|
1726
drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c
Normal file
1726
drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.c
Normal file
File diff suppressed because it is too large
Load Diff
38
drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h
Normal file
38
drivers/gpu/drm/amd/display/dc/spl/dc_spl_scl_easf_filters.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
/* Copyright 2024 Advanced Micro Devices, Inc. */
|
||||
|
||||
#ifndef __DC_SPL_SCL_EASF_FILTERS_H__
|
||||
#define __DC_SPL_SCL_EASF_FILTERS_H__
|
||||
|
||||
#include "dc_spl_types.h"
|
||||
|
||||
struct scale_ratio_to_reg_value_lookup {
|
||||
int numer;
|
||||
int denom;
|
||||
const uint32_t reg_value;
|
||||
};
|
||||
|
||||
void spl_init_easf_filter_coeffs(void);
|
||||
uint16_t *spl_get_easf_filter_3tap_64p(struct spl_fixed31_32 ratio);
|
||||
uint16_t *spl_get_easf_filter_4tap_64p(struct spl_fixed31_32 ratio);
|
||||
uint16_t *spl_get_easf_filter_6tap_64p(struct spl_fixed31_32 ratio);
|
||||
uint16_t *spl_dscl_get_easf_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio);
|
||||
void spl_set_filters_data(struct dscl_prog_data *dscl_prog_data,
|
||||
const struct spl_scaler_data *data, bool enable_easf_v,
|
||||
bool enable_easf_h);
|
||||
|
||||
uint32_t spl_get_v_bf3_mode(struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_h_bf3_mode(struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_reducer_gain6(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_reducer_gain4(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_gainRing6(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_gainRing4(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_dntilt_uptilt_offset(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt_maxval(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_dntilt_slope(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt1_slope(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt2_slope(int taps, struct spl_fixed31_32 ratio);
|
||||
uint32_t spl_get_3tap_uptilt2_offset(int taps, struct spl_fixed31_32 ratio);
|
||||
|
||||
#endif /* __DC_SPL_SCL_EASF_FILTERS_H__ */
|
@ -2,6 +2,7 @@
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "spl_debug.h"
|
||||
#include "dc_spl_scl_filters.h"
|
||||
//=========================================
|
||||
// <num_taps> = 2
|
||||
@ -1317,97 +1318,97 @@ static const uint16_t filter_8tap_64p_183[264] = {
|
||||
0x3FD4, 0x3F84, 0x0214, 0x0694, 0x0694, 0x0214, 0x3F84, 0x3FD4
|
||||
};
|
||||
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_3tap_16p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_3tap_16p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_3tap_16p_149;
|
||||
else
|
||||
return filter_3tap_16p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_3tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_3tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_3tap_64p_149;
|
||||
else
|
||||
return filter_3tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_4tap_16p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_4tap_16p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_4tap_16p_149;
|
||||
else
|
||||
return filter_4tap_16p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_4tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_4tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_4tap_64p_149;
|
||||
else
|
||||
return filter_4tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_5tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_5tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_5tap_64p_149;
|
||||
else
|
||||
return filter_5tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_6tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_6tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_6tap_64p_149;
|
||||
else
|
||||
return filter_6tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_7tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_7tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_7tap_64p_149;
|
||||
else
|
||||
return filter_7tap_64p_183;
|
||||
}
|
||||
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct fixed31_32 ratio)
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (ratio.value < dc_fixpt_one.value)
|
||||
if (ratio.value < spl_fixpt_one.value)
|
||||
return filter_8tap_64p_upscale;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(4, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(4, 3).value)
|
||||
return filter_8tap_64p_116;
|
||||
else if (ratio.value < dc_fixpt_from_fraction(5, 3).value)
|
||||
else if (ratio.value < spl_fixpt_from_fraction(5, 3).value)
|
||||
return filter_8tap_64p_149;
|
||||
else
|
||||
return filter_8tap_64p_183;
|
||||
@ -1422,3 +1423,29 @@ const uint16_t *spl_get_filter_2tap_64p(void)
|
||||
{
|
||||
return filter_2tap_64p;
|
||||
}
|
||||
|
||||
const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio)
|
||||
{
|
||||
if (taps == 8)
|
||||
return spl_get_filter_8tap_64p(ratio);
|
||||
else if (taps == 7)
|
||||
return spl_get_filter_7tap_64p(ratio);
|
||||
else if (taps == 6)
|
||||
return spl_get_filter_6tap_64p(ratio);
|
||||
else if (taps == 5)
|
||||
return spl_get_filter_5tap_64p(ratio);
|
||||
else if (taps == 4)
|
||||
return spl_get_filter_4tap_64p(ratio);
|
||||
else if (taps == 3)
|
||||
return spl_get_filter_3tap_64p(ratio);
|
||||
else if (taps == 2)
|
||||
return spl_get_filter_2tap_64p();
|
||||
else if (taps == 1)
|
||||
return NULL;
|
||||
else {
|
||||
/* should never happen, bug */
|
||||
SPL_BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,53 +7,16 @@
|
||||
|
||||
#include "dc_spl_types.h"
|
||||
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_3tap_16p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_3tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_16p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_4tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_5tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_6tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_7tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_8tap_64p(struct spl_fixed31_32 ratio);
|
||||
const uint16_t *spl_get_filter_2tap_16p(void);
|
||||
const uint16_t *spl_get_filter_2tap_64p(void);
|
||||
const uint16_t *spl_get_filter_3tap_16p_upscale(void);
|
||||
const uint16_t *spl_get_filter_3tap_16p_116(void);
|
||||
const uint16_t *spl_get_filter_3tap_16p_149(void);
|
||||
const uint16_t *spl_get_filter_3tap_16p_183(void);
|
||||
const uint16_t *spl_dscl_get_filter_coeffs_64p(int taps, struct spl_fixed31_32 ratio);
|
||||
|
||||
const uint16_t *spl_get_filter_4tap_16p_upscale(void);
|
||||
const uint16_t *spl_get_filter_4tap_16p_116(void);
|
||||
const uint16_t *spl_get_filter_4tap_16p_149(void);
|
||||
const uint16_t *spl_get_filter_4tap_16p_183(void);
|
||||
|
||||
const uint16_t *spl_get_filter_3tap_64p_upscale(void);
|
||||
const uint16_t *spl_get_filter_3tap_64p_116(void);
|
||||
const uint16_t *spl_get_filter_3tap_64p_149(void);
|
||||
const uint16_t *spl_get_filter_3tap_64p_183(void);
|
||||
|
||||
const uint16_t *spl_get_filter_4tap_64p_upscale(void);
|
||||
const uint16_t *spl_get_filter_4tap_64p_116(void);
|
||||
const uint16_t *spl_get_filter_4tap_64p_149(void);
|
||||
const uint16_t *spl_get_filter_4tap_64p_183(void);
|
||||
|
||||
const uint16_t *spl_get_filter_5tap_64p_upscale(void);
|
||||
const uint16_t *spl_get_filter_5tap_64p_116(void);
|
||||
const uint16_t *spl_get_filter_5tap_64p_149(void);
|
||||
const uint16_t *spl_get_filter_5tap_64p_183(void);
|
||||
|
||||
const uint16_t *spl_get_filter_6tap_64p_upscale(void);
|
||||
const uint16_t *spl_get_filter_6tap_64p_116(void);
|
||||
const uint16_t *spl_get_filter_6tap_64p_149(void);
|
||||
const uint16_t *spl_get_filter_6tap_64p_183(void);
|
||||
|
||||
const uint16_t *spl_get_filter_7tap_64p_upscale(void);
|
||||
const uint16_t *spl_get_filter_7tap_64p_116(void);
|
||||
const uint16_t *spl_get_filter_7tap_64p_149(void);
|
||||
const uint16_t *spl_get_filter_7tap_64p_183(void);
|
||||
|
||||
const uint16_t *spl_get_filter_8tap_64p_upscale(void);
|
||||
const uint16_t *spl_get_filter_8tap_64p_116(void);
|
||||
const uint16_t *spl_get_filter_8tap_64p_149(void);
|
||||
const uint16_t *spl_get_filter_8tap_64p_183(void);
|
||||
#endif /* __DC_SPL_SCL_FILTERS_H__ */
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-16 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
@ -2,14 +2,16 @@
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "os_types.h" // swap
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(_bool) ((void *)0)
|
||||
#endif
|
||||
#include "include/fixed31_32.h" // fixed31_32 and related functions
|
||||
#ifndef __DC_SPL_TYPES_H__
|
||||
#define __DC_SPL_TYPES_H__
|
||||
|
||||
#include "spl_os_types.h" // swap
|
||||
#ifndef SPL_ASSERT
|
||||
#define SPL_ASSERT(_bool) ((void *)0)
|
||||
#endif
|
||||
#include "spl_fixpt31_32.h" // fixed31_32 and related functions
|
||||
#include "spl_custom_float.h" // custom float and related functions
|
||||
|
||||
struct spl_size {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
@ -22,16 +24,16 @@ struct spl_rect {
|
||||
};
|
||||
|
||||
struct spl_ratios {
|
||||
struct fixed31_32 horz;
|
||||
struct fixed31_32 vert;
|
||||
struct fixed31_32 horz_c;
|
||||
struct fixed31_32 vert_c;
|
||||
struct spl_fixed31_32 horz;
|
||||
struct spl_fixed31_32 vert;
|
||||
struct spl_fixed31_32 horz_c;
|
||||
struct spl_fixed31_32 vert_c;
|
||||
};
|
||||
struct spl_inits {
|
||||
struct fixed31_32 h;
|
||||
struct fixed31_32 h_c;
|
||||
struct fixed31_32 v;
|
||||
struct fixed31_32 v_c;
|
||||
struct spl_fixed31_32 h;
|
||||
struct spl_fixed31_32 h_c;
|
||||
struct spl_fixed31_32 v;
|
||||
struct spl_fixed31_32 v_c;
|
||||
};
|
||||
|
||||
struct spl_taps {
|
||||
@ -64,6 +66,8 @@ enum spl_pixel_format {
|
||||
SPL_PIXEL_FORMAT_420BPP10,
|
||||
/*end of pixel format definition*/
|
||||
SPL_PIXEL_FORMAT_INVALID,
|
||||
SPL_PIXEL_FORMAT_422BPP8,
|
||||
SPL_PIXEL_FORMAT_422BPP10,
|
||||
SPL_PIXEL_FORMAT_GRPH_BEGIN = SPL_PIXEL_FORMAT_INDEX8,
|
||||
SPL_PIXEL_FORMAT_GRPH_END = SPL_PIXEL_FORMAT_FP16,
|
||||
SPL_PIXEL_FORMAT_VIDEO_BEGIN = SPL_PIXEL_FORMAT_420BPP8,
|
||||
@ -135,6 +139,7 @@ struct spl_scaler_data {
|
||||
struct spl_rect viewport_c;
|
||||
struct spl_rect recout;
|
||||
struct spl_ratios ratios;
|
||||
struct spl_ratios recip_ratios;
|
||||
struct spl_inits inits;
|
||||
};
|
||||
|
||||
@ -402,13 +407,19 @@ struct dscl_prog_data {
|
||||
/* blur and scale filter */
|
||||
const uint16_t *filter_blur_scale_v;
|
||||
const uint16_t *filter_blur_scale_h;
|
||||
int sharpness_level; /* Track sharpness level */
|
||||
};
|
||||
|
||||
/* SPL input and output definitions */
|
||||
// SPL scratch struct
|
||||
struct spl_scratch {
|
||||
// Pack all SPL outputs in scl_data
|
||||
struct spl_scaler_data scl_data;
|
||||
};
|
||||
|
||||
/* SPL input and output definitions */
|
||||
// SPL outputs struct
|
||||
struct spl_out {
|
||||
// Pack all SPL outputs in scl_data
|
||||
struct spl_scaler_data scl_data;
|
||||
// Pack all output need to program hw registers
|
||||
struct dscl_prog_data *dscl_prog_data;
|
||||
};
|
||||
@ -450,14 +461,26 @@ struct basic_out {
|
||||
bool alpha_en;
|
||||
bool use_two_pixels_per_container;
|
||||
};
|
||||
enum explicit_sharpness {
|
||||
SHARPNESS_LOW = 0,
|
||||
SHARPNESS_MID,
|
||||
SHARPNESS_HIGH
|
||||
enum sharpness_setting {
|
||||
SHARPNESS_HW_OFF = 0,
|
||||
SHARPNESS_ZERO,
|
||||
SHARPNESS_CUSTOM
|
||||
};
|
||||
struct adaptive_sharpness {
|
||||
struct spl_sharpness_range {
|
||||
int sdr_rgb_min;
|
||||
int sdr_rgb_max;
|
||||
int sdr_rgb_mid;
|
||||
int sdr_yuv_min;
|
||||
int sdr_yuv_max;
|
||||
int sdr_yuv_mid;
|
||||
int hdr_rgb_min;
|
||||
int hdr_rgb_max;
|
||||
int hdr_rgb_mid;
|
||||
};
|
||||
struct adaptive_sharpness {
|
||||
bool enable;
|
||||
enum explicit_sharpness sharpness;
|
||||
int sharpness_level;
|
||||
struct spl_sharpness_range sharpness_range;
|
||||
};
|
||||
enum linear_light_scaling { // convert it in translation logic
|
||||
LLS_PREF_DONT_CARE = 0,
|
||||
@ -491,6 +514,11 @@ struct spl_in {
|
||||
bool prefer_easf;
|
||||
bool disable_easf;
|
||||
struct spl_debug debug;
|
||||
bool is_fullscreen;
|
||||
bool is_hdr_on;
|
||||
int h_active;
|
||||
int v_active;
|
||||
int hdr_multx100;
|
||||
};
|
||||
// end of SPL inputs
|
||||
|
||||
|
151
drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c
Normal file
151
drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.c
Normal file
@ -0,0 +1,151 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "spl_debug.h"
|
||||
#include "spl_custom_float.h"
|
||||
|
||||
static bool spl_build_custom_float(struct spl_fixed31_32 value,
|
||||
const struct spl_custom_float_format *format,
|
||||
bool *negative,
|
||||
uint32_t *mantissa,
|
||||
uint32_t *exponenta)
|
||||
{
|
||||
uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
|
||||
|
||||
const struct spl_fixed31_32 mantissa_constant_plus_max_fraction =
|
||||
spl_fixpt_from_fraction((1LL << (format->mantissa_bits + 1)) - 1,
|
||||
1LL << format->mantissa_bits);
|
||||
|
||||
struct spl_fixed31_32 mantiss;
|
||||
|
||||
if (spl_fixpt_eq(value, spl_fixpt_zero)) {
|
||||
*negative = false;
|
||||
*mantissa = 0;
|
||||
*exponenta = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (spl_fixpt_lt(value, spl_fixpt_zero)) {
|
||||
*negative = format->sign;
|
||||
value = spl_fixpt_neg(value);
|
||||
} else {
|
||||
*negative = false;
|
||||
}
|
||||
|
||||
if (spl_fixpt_lt(value, spl_fixpt_one)) {
|
||||
uint32_t i = 1;
|
||||
|
||||
do {
|
||||
value = spl_fixpt_shl(value, 1);
|
||||
++i;
|
||||
} while (spl_fixpt_lt(value, spl_fixpt_one));
|
||||
|
||||
--i;
|
||||
|
||||
if (exp_offset <= i) {
|
||||
*mantissa = 0;
|
||||
*exponenta = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
*exponenta = exp_offset - i;
|
||||
} else if (spl_fixpt_le(mantissa_constant_plus_max_fraction, value)) {
|
||||
uint32_t i = 1;
|
||||
|
||||
do {
|
||||
value = spl_fixpt_shr(value, 1);
|
||||
++i;
|
||||
} while (spl_fixpt_lt(mantissa_constant_plus_max_fraction, value));
|
||||
|
||||
*exponenta = exp_offset + i - 1;
|
||||
} else {
|
||||
*exponenta = exp_offset;
|
||||
}
|
||||
|
||||
mantiss = spl_fixpt_sub(value, spl_fixpt_one);
|
||||
|
||||
if (spl_fixpt_lt(mantiss, spl_fixpt_zero) ||
|
||||
spl_fixpt_lt(spl_fixpt_one, mantiss))
|
||||
mantiss = spl_fixpt_zero;
|
||||
else
|
||||
mantiss = spl_fixpt_shl(mantiss, format->mantissa_bits);
|
||||
|
||||
*mantissa = spl_fixpt_floor(mantiss);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool spl_setup_custom_float(const struct spl_custom_float_format *format,
|
||||
bool negative,
|
||||
uint32_t mantissa,
|
||||
uint32_t exponenta,
|
||||
uint32_t *result)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t j = 0;
|
||||
uint32_t value = 0;
|
||||
|
||||
/* verification code:
|
||||
* once calculation is ok we can remove it
|
||||
*/
|
||||
|
||||
const uint32_t mantissa_mask =
|
||||
(1 << (format->mantissa_bits + 1)) - 1;
|
||||
|
||||
const uint32_t exponenta_mask =
|
||||
(1 << (format->exponenta_bits + 1)) - 1;
|
||||
|
||||
if (mantissa & ~mantissa_mask) {
|
||||
SPL_BREAK_TO_DEBUGGER();
|
||||
mantissa = mantissa_mask;
|
||||
}
|
||||
|
||||
if (exponenta & ~exponenta_mask) {
|
||||
SPL_BREAK_TO_DEBUGGER();
|
||||
exponenta = exponenta_mask;
|
||||
}
|
||||
|
||||
/* end of verification code */
|
||||
|
||||
while (i < format->mantissa_bits) {
|
||||
uint32_t mask = 1 << i;
|
||||
|
||||
if (mantissa & mask)
|
||||
value |= mask;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
while (j < format->exponenta_bits) {
|
||||
uint32_t mask = 1 << j;
|
||||
|
||||
if (exponenta & mask)
|
||||
value |= mask << i;
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
if (negative && format->sign)
|
||||
value |= 1 << (i + j);
|
||||
|
||||
*result = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spl_convert_to_custom_float_format(struct spl_fixed31_32 value,
|
||||
const struct spl_custom_float_format *format,
|
||||
uint32_t *result)
|
||||
{
|
||||
uint32_t mantissa;
|
||||
uint32_t exponenta;
|
||||
bool negative;
|
||||
|
||||
return spl_build_custom_float(value, format, &negative, &mantissa, &exponenta) &&
|
||||
spl_setup_custom_float(format,
|
||||
negative,
|
||||
mantissa,
|
||||
exponenta,
|
||||
result);
|
||||
}
|
29
drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h
Normal file
29
drivers/gpu/drm/amd/display/dc/spl/spl_custom_float.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
/* Copyright 2024 Advanced Micro Devices, Inc. */
|
||||
|
||||
#ifndef SPL_CUSTOM_FLOAT_H_
|
||||
#define SPL_CUSTOM_FLOAT_H_
|
||||
|
||||
#include "spl_os_types.h"
|
||||
#include "spl_fixpt31_32.h"
|
||||
|
||||
struct spl_custom_float_format {
|
||||
uint32_t mantissa_bits;
|
||||
uint32_t exponenta_bits;
|
||||
bool sign;
|
||||
};
|
||||
|
||||
struct spl_custom_float_value {
|
||||
uint32_t mantissa;
|
||||
uint32_t exponenta;
|
||||
uint32_t value;
|
||||
bool negative;
|
||||
};
|
||||
|
||||
bool spl_convert_to_custom_float_format(
|
||||
struct spl_fixed31_32 value,
|
||||
const struct spl_custom_float_format *format,
|
||||
uint32_t *result);
|
||||
|
||||
#endif //SPL_CUSTOM_FLOAT_H_
|
25
drivers/gpu/drm/amd/display/dc/spl/spl_debug.h
Normal file
25
drivers/gpu/drm/amd/display/dc/spl/spl_debug.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
/* Copyright 2024 Advanced Micro Devices, Inc. */
|
||||
|
||||
#ifndef SPL_DEBUG_H
|
||||
#define SPL_DEBUG_H
|
||||
|
||||
#ifdef SPL_ASSERT
|
||||
#undef SPL_ASSERT
|
||||
#endif
|
||||
#define SPL_ASSERT(b)
|
||||
|
||||
#define SPL_ASSERT_CRITICAL(expr) do {if (expr)/* Do nothing */; } while (0)
|
||||
|
||||
#ifdef SPL_DALMSG
|
||||
#undef SPL_DALMSG
|
||||
#endif
|
||||
#define SPL_DALMSG(b)
|
||||
|
||||
#ifdef SPL_DAL_ASSERT_MSG
|
||||
#undef SPL_DAL_ASSERT_MSG
|
||||
#endif
|
||||
#define SPL_DAL_ASSERT_MSG(b, m)
|
||||
|
||||
#endif // SPL_DEBUG_H
|
497
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c
Normal file
497
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c
Normal file
@ -0,0 +1,497 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright 2024 Advanced Micro Devices, Inc.
|
||||
|
||||
#include "spl_fixpt31_32.h"
|
||||
|
||||
static const struct spl_fixed31_32 spl_fixpt_two_pi = { 26986075409LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_ln2 = { 2977044471LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_ln2_div_2 = { 1488522236LL };
|
||||
|
||||
static inline unsigned long long abs_i64(
|
||||
long long arg)
|
||||
{
|
||||
if (arg > 0)
|
||||
return (unsigned long long)arg;
|
||||
else
|
||||
return (unsigned long long)(-arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = dividend / divisor
|
||||
* *remainder = dividend % divisor
|
||||
*/
|
||||
static inline unsigned long long complete_integer_division_u64(
|
||||
unsigned long long dividend,
|
||||
unsigned long long divisor,
|
||||
unsigned long long *remainder)
|
||||
{
|
||||
unsigned long long result;
|
||||
|
||||
ASSERT(divisor);
|
||||
|
||||
result = spl_div64_u64_rem(dividend, divisor, remainder);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#define FRACTIONAL_PART_MASK \
|
||||
((1ULL << FIXED31_32_BITS_PER_FRACTIONAL_PART) - 1)
|
||||
|
||||
#define GET_INTEGER_PART(x) \
|
||||
((x) >> FIXED31_32_BITS_PER_FRACTIONAL_PART)
|
||||
|
||||
#define GET_FRACTIONAL_PART(x) \
|
||||
(FRACTIONAL_PART_MASK & (x))
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_from_fraction(long long numerator, long long denominator)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
bool arg1_negative = numerator < 0;
|
||||
bool arg2_negative = denominator < 0;
|
||||
|
||||
unsigned long long arg1_value = arg1_negative ? -numerator : numerator;
|
||||
unsigned long long arg2_value = arg2_negative ? -denominator : denominator;
|
||||
|
||||
unsigned long long remainder;
|
||||
|
||||
/* determine integer part */
|
||||
|
||||
unsigned long long res_value = complete_integer_division_u64(
|
||||
arg1_value, arg2_value, &remainder);
|
||||
|
||||
ASSERT(res_value <= LONG_MAX);
|
||||
|
||||
/* determine fractional part */
|
||||
{
|
||||
unsigned int i = FIXED31_32_BITS_PER_FRACTIONAL_PART;
|
||||
|
||||
do {
|
||||
remainder <<= 1;
|
||||
|
||||
res_value <<= 1;
|
||||
|
||||
if (remainder >= arg2_value) {
|
||||
res_value |= 1;
|
||||
remainder -= arg2_value;
|
||||
}
|
||||
} while (--i != 0);
|
||||
}
|
||||
|
||||
/* round up LSB */
|
||||
{
|
||||
unsigned long long summand = (remainder << 1) >= arg2_value;
|
||||
|
||||
ASSERT(res_value <= LLONG_MAX - summand);
|
||||
|
||||
res_value += summand;
|
||||
}
|
||||
|
||||
res.value = (long long)res_value;
|
||||
|
||||
if (arg1_negative ^ arg2_negative)
|
||||
res.value = -res.value;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_mul(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
bool arg1_negative = arg1.value < 0;
|
||||
bool arg2_negative = arg2.value < 0;
|
||||
|
||||
unsigned long long arg1_value = arg1_negative ? -arg1.value : arg1.value;
|
||||
unsigned long long arg2_value = arg2_negative ? -arg2.value : arg2.value;
|
||||
|
||||
unsigned long long arg1_int = GET_INTEGER_PART(arg1_value);
|
||||
unsigned long long arg2_int = GET_INTEGER_PART(arg2_value);
|
||||
|
||||
unsigned long long arg1_fra = GET_FRACTIONAL_PART(arg1_value);
|
||||
unsigned long long arg2_fra = GET_FRACTIONAL_PART(arg2_value);
|
||||
|
||||
unsigned long long tmp;
|
||||
|
||||
res.value = arg1_int * arg2_int;
|
||||
|
||||
ASSERT(res.value <= (long long)LONG_MAX);
|
||||
|
||||
res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
|
||||
|
||||
tmp = arg1_int * arg2_fra;
|
||||
|
||||
ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
|
||||
|
||||
res.value += tmp;
|
||||
|
||||
tmp = arg2_int * arg1_fra;
|
||||
|
||||
ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
|
||||
|
||||
res.value += tmp;
|
||||
|
||||
tmp = arg1_fra * arg2_fra;
|
||||
|
||||
tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
|
||||
(tmp >= (unsigned long long)spl_fixpt_half.value);
|
||||
|
||||
ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
|
||||
|
||||
res.value += tmp;
|
||||
|
||||
if (arg1_negative ^ arg2_negative)
|
||||
res.value = -res.value;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_sqr(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
unsigned long long arg_value = abs_i64(arg.value);
|
||||
|
||||
unsigned long long arg_int = GET_INTEGER_PART(arg_value);
|
||||
|
||||
unsigned long long arg_fra = GET_FRACTIONAL_PART(arg_value);
|
||||
|
||||
unsigned long long tmp;
|
||||
|
||||
res.value = arg_int * arg_int;
|
||||
|
||||
ASSERT(res.value <= (long long)LONG_MAX);
|
||||
|
||||
res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
|
||||
|
||||
tmp = arg_int * arg_fra;
|
||||
|
||||
ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
|
||||
|
||||
res.value += tmp;
|
||||
|
||||
ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
|
||||
|
||||
res.value += tmp;
|
||||
|
||||
tmp = arg_fra * arg_fra;
|
||||
|
||||
tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) +
|
||||
(tmp >= (unsigned long long)spl_fixpt_half.value);
|
||||
|
||||
ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value));
|
||||
|
||||
res.value += tmp;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_recip(struct spl_fixed31_32 arg)
|
||||
{
|
||||
/*
|
||||
* @note
|
||||
* Good idea to use Newton's method
|
||||
*/
|
||||
|
||||
ASSERT(arg.value);
|
||||
|
||||
return spl_fixpt_from_fraction(
|
||||
spl_fixpt_one.value,
|
||||
arg.value);
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_sinc(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_fixed31_32 square;
|
||||
|
||||
struct spl_fixed31_32 res = spl_fixpt_one;
|
||||
|
||||
int n = 27;
|
||||
|
||||
struct spl_fixed31_32 arg_norm = arg;
|
||||
|
||||
if (spl_fixpt_le(
|
||||
spl_fixpt_two_pi,
|
||||
spl_fixpt_abs(arg))) {
|
||||
arg_norm = spl_fixpt_sub(
|
||||
arg_norm,
|
||||
spl_fixpt_mul_int(
|
||||
spl_fixpt_two_pi,
|
||||
(int)spl_div64_s64(
|
||||
arg_norm.value,
|
||||
spl_fixpt_two_pi.value)));
|
||||
}
|
||||
|
||||
square = spl_fixpt_sqr(arg_norm);
|
||||
|
||||
do {
|
||||
res = spl_fixpt_sub(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_div_int(
|
||||
spl_fixpt_mul(
|
||||
square,
|
||||
res),
|
||||
n * (n - 1)));
|
||||
|
||||
n -= 2;
|
||||
} while (n > 2);
|
||||
|
||||
if (arg.value != arg_norm.value)
|
||||
res = spl_fixpt_div(
|
||||
spl_fixpt_mul(res, arg_norm),
|
||||
arg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_sin(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return spl_fixpt_mul(
|
||||
arg,
|
||||
spl_fixpt_sinc(arg));
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_cos(struct spl_fixed31_32 arg)
|
||||
{
|
||||
/* TODO implement argument normalization */
|
||||
|
||||
const struct spl_fixed31_32 square = spl_fixpt_sqr(arg);
|
||||
|
||||
struct spl_fixed31_32 res = spl_fixpt_one;
|
||||
|
||||
int n = 26;
|
||||
|
||||
do {
|
||||
res = spl_fixpt_sub(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_div_int(
|
||||
spl_fixpt_mul(
|
||||
square,
|
||||
res),
|
||||
n * (n - 1)));
|
||||
|
||||
n -= 2;
|
||||
} while (n != 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = exp(arg),
|
||||
* where abs(arg) < 1
|
||||
*
|
||||
* Calculated as Taylor series.
|
||||
*/
|
||||
static struct spl_fixed31_32 fixed31_32_exp_from_taylor_series(struct spl_fixed31_32 arg)
|
||||
{
|
||||
unsigned int n = 9;
|
||||
|
||||
struct spl_fixed31_32 res = spl_fixpt_from_fraction(
|
||||
n + 2,
|
||||
n + 1);
|
||||
/* TODO find correct res */
|
||||
|
||||
ASSERT(spl_fixpt_lt(arg, spl_fixpt_one));
|
||||
|
||||
do
|
||||
res = spl_fixpt_add(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_div_int(
|
||||
spl_fixpt_mul(
|
||||
arg,
|
||||
res),
|
||||
n));
|
||||
while (--n != 1);
|
||||
|
||||
return spl_fixpt_add(
|
||||
spl_fixpt_one,
|
||||
spl_fixpt_mul(
|
||||
arg,
|
||||
res));
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_exp(struct spl_fixed31_32 arg)
|
||||
{
|
||||
/*
|
||||
* @brief
|
||||
* Main equation is:
|
||||
* exp(x) = exp(r + m * ln(2)) = (1 << m) * exp(r),
|
||||
* where m = round(x / ln(2)), r = x - m * ln(2)
|
||||
*/
|
||||
|
||||
if (spl_fixpt_le(
|
||||
spl_fixpt_ln2_div_2,
|
||||
spl_fixpt_abs(arg))) {
|
||||
int m = spl_fixpt_round(
|
||||
spl_fixpt_div(
|
||||
arg,
|
||||
spl_fixpt_ln2));
|
||||
|
||||
struct spl_fixed31_32 r = spl_fixpt_sub(
|
||||
arg,
|
||||
spl_fixpt_mul_int(
|
||||
spl_fixpt_ln2,
|
||||
m));
|
||||
|
||||
ASSERT(m != 0);
|
||||
|
||||
ASSERT(spl_fixpt_lt(
|
||||
spl_fixpt_abs(r),
|
||||
spl_fixpt_one));
|
||||
|
||||
if (m > 0)
|
||||
return spl_fixpt_shl(
|
||||
fixed31_32_exp_from_taylor_series(r),
|
||||
(unsigned char)m);
|
||||
else
|
||||
return spl_fixpt_div_int(
|
||||
fixed31_32_exp_from_taylor_series(r),
|
||||
1LL << -m);
|
||||
} else if (arg.value != 0)
|
||||
return fixed31_32_exp_from_taylor_series(arg);
|
||||
else
|
||||
return spl_fixpt_one;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_log(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_fixed31_32 res = spl_fixpt_neg(spl_fixpt_one);
|
||||
/* TODO improve 1st estimation */
|
||||
|
||||
struct spl_fixed31_32 error;
|
||||
|
||||
ASSERT(arg.value > 0);
|
||||
/* TODO if arg is negative, return NaN */
|
||||
/* TODO if arg is zero, return -INF */
|
||||
|
||||
do {
|
||||
struct spl_fixed31_32 res1 = spl_fixpt_add(
|
||||
spl_fixpt_sub(
|
||||
res,
|
||||
spl_fixpt_one),
|
||||
spl_fixpt_div(
|
||||
arg,
|
||||
spl_fixpt_exp(res)));
|
||||
|
||||
error = spl_fixpt_sub(
|
||||
res,
|
||||
res1);
|
||||
|
||||
res = res1;
|
||||
/* TODO determine max_allowed_error based on quality of exp() */
|
||||
} while (abs_i64(error.value) > 100ULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* this function is a generic helper to translate fixed point value to
|
||||
* specified integer format that will consist of integer_bits integer part and
|
||||
* fractional_bits fractional part. For example it is used in
|
||||
* spl_fixpt_u2d19 to receive 2 bits integer part and 19 bits fractional
|
||||
* part in 32 bits. It is used in hw programming (scaler)
|
||||
*/
|
||||
|
||||
static inline unsigned int ux_dy(
|
||||
long long value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits)
|
||||
{
|
||||
/* 1. create mask of integer part */
|
||||
unsigned int result = (1 << integer_bits) - 1;
|
||||
/* 2. mask out fractional part */
|
||||
unsigned int fractional_part = FRACTIONAL_PART_MASK & value;
|
||||
/* 3. shrink fixed point integer part to be of integer_bits width*/
|
||||
result &= GET_INTEGER_PART(value);
|
||||
/* 4. make space for fractional part to be filled in after integer */
|
||||
result <<= fractional_bits;
|
||||
/* 5. shrink fixed point fractional part to of fractional_bits width*/
|
||||
fractional_part >>= FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits;
|
||||
/* 6. merge the result */
|
||||
return result | fractional_part;
|
||||
}
|
||||
|
||||
static inline unsigned int clamp_ux_dy(
|
||||
long long value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits,
|
||||
unsigned int min_clamp)
|
||||
{
|
||||
unsigned int truncated_val = ux_dy(value, integer_bits, fractional_bits);
|
||||
|
||||
if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART)))
|
||||
return (1 << (integer_bits + fractional_bits)) - 1;
|
||||
else if (truncated_val > min_clamp)
|
||||
return truncated_val;
|
||||
else
|
||||
return min_clamp;
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u4d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 4, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 3, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 2, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return ux_dy(arg.value, 0, 19);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return clamp_ux_dy(arg.value, 0, 14, 1);
|
||||
}
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg)
|
||||
{
|
||||
return clamp_ux_dy(arg.value, 0, 10, 1);
|
||||
}
|
||||
|
||||
int spl_fixpt_s4d19(struct spl_fixed31_32 arg)
|
||||
{
|
||||
if (arg.value < 0)
|
||||
return -(int)ux_dy(spl_fixpt_abs(arg).value, 4, 19);
|
||||
else
|
||||
return ux_dy(arg.value, 4, 19);
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_from_ux_dy(unsigned int value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits)
|
||||
{
|
||||
struct spl_fixed31_32 fixpt_value = spl_fixpt_zero;
|
||||
struct spl_fixed31_32 fixpt_int_value = spl_fixpt_zero;
|
||||
long long frac_mask = ((long long)1 << (long long)integer_bits) - 1;
|
||||
|
||||
fixpt_value.value = (long long)value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
frac_mask = frac_mask << fractional_bits;
|
||||
fixpt_int_value.value = value & frac_mask;
|
||||
fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
fixpt_value.value |= fixpt_int_value.value;
|
||||
return fixpt_value;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_from_int_dy(unsigned int int_value,
|
||||
unsigned int frac_value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits)
|
||||
{
|
||||
struct spl_fixed31_32 fixpt_value = spl_fixpt_from_int(int_value);
|
||||
|
||||
fixpt_value.value |= (long long)frac_value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
|
||||
return fixpt_value;
|
||||
}
|
525
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h
Normal file
525
drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h
Normal file
@ -0,0 +1,525 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
/* Copyright 2024 Advanced Micro Devices, Inc. */
|
||||
|
||||
#ifndef __SPL_FIXED31_32_H__
|
||||
#define __SPL_FIXED31_32_H__
|
||||
|
||||
#include "os_types.h"
|
||||
#include "spl_os_types.h" // swap
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(_bool) ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX 9223372036854775807ll
|
||||
#endif
|
||||
#ifndef LLONG_MIN
|
||||
#define LLONG_MIN (-LLONG_MAX - 1ll)
|
||||
#endif
|
||||
|
||||
#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
|
||||
#ifndef LLONG_MIN
|
||||
#define LLONG_MIN (1LL<<63)
|
||||
#endif
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX (-1LL>>1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Arithmetic operations on real numbers
|
||||
* represented as fixed-point numbers.
|
||||
* There are: 1 bit for sign,
|
||||
* 31 bit for integer part,
|
||||
* 32 bits for fractional part.
|
||||
*
|
||||
* @note
|
||||
* Currently, overflows and underflows are asserted;
|
||||
* no special result returned.
|
||||
*/
|
||||
|
||||
struct spl_fixed31_32 {
|
||||
long long value;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Useful constants
|
||||
*/
|
||||
|
||||
static const struct spl_fixed31_32 spl_fixpt_zero = { 0 };
|
||||
static const struct spl_fixed31_32 spl_fixpt_epsilon = { 1LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_half = { 0x80000000LL };
|
||||
static const struct spl_fixed31_32 spl_fixpt_one = { 0x100000000LL };
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Initialization routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = numerator / denominator
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_from_fraction(long long numerator, long long denominator);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_from_int(int arg)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Unary operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = -arg
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_neg(struct spl_fixed31_32 arg)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
res.value = -arg.value;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = abs(arg) := (arg >= 0) ? arg : -arg
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_abs(struct spl_fixed31_32 arg)
|
||||
{
|
||||
if (arg.value < 0)
|
||||
return spl_fixpt_neg(arg);
|
||||
else
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary relational operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 < arg2
|
||||
*/
|
||||
static inline bool spl_fixpt_lt(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return arg1.value < arg2.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 <= arg2
|
||||
*/
|
||||
static inline bool spl_fixpt_le(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return arg1.value <= arg2.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 == arg2
|
||||
*/
|
||||
static inline bool spl_fixpt_eq(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return arg1.value == arg2.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_min(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
if (arg1.value <= arg2.value)
|
||||
return arg1;
|
||||
else
|
||||
return arg2;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_max(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
if (arg1.value <= arg2.value)
|
||||
return arg2;
|
||||
else
|
||||
return arg1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* | min_value, when arg <= min_value
|
||||
* result = | arg, when min_value < arg < max_value
|
||||
* | max_value, when arg >= max_value
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_clamp(
|
||||
struct spl_fixed31_32 arg,
|
||||
struct spl_fixed31_32 min_value,
|
||||
struct spl_fixed31_32 max_value)
|
||||
{
|
||||
if (spl_fixpt_le(arg, min_value))
|
||||
return min_value;
|
||||
else if (spl_fixpt_le(max_value, arg))
|
||||
return max_value;
|
||||
else
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary shift operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg << shift
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, unsigned char shift)
|
||||
{
|
||||
ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
|
||||
((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
|
||||
|
||||
arg.value = arg.value << shift;
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg >> shift
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_shr(struct spl_fixed31_32 arg, unsigned char shift)
|
||||
{
|
||||
bool negative = arg.value < 0;
|
||||
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
arg.value = arg.value >> shift;
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary additive operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 + arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_add(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
|
||||
((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
|
||||
|
||||
res.value = arg1.value + arg2.value;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 + arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_add_int(struct spl_fixed31_32 arg1, int arg2)
|
||||
{
|
||||
return spl_fixpt_add(arg1, spl_fixpt_from_int(arg2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 - arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_sub(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
struct spl_fixed31_32 res;
|
||||
|
||||
ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
|
||||
((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
|
||||
|
||||
res.value = arg1.value - arg2.value;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 - arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_sub_int(struct spl_fixed31_32 arg1, int arg2)
|
||||
{
|
||||
return spl_fixpt_sub(arg1, spl_fixpt_from_int(arg2));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Binary multiplicative operators
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 * arg2
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_mul(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2);
|
||||
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 * arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_mul_int(struct spl_fixed31_32 arg1, int arg2)
|
||||
{
|
||||
return spl_fixpt_mul(arg1, spl_fixpt_from_int(arg2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = square(arg) := arg * arg
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_sqr(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 / arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_div_int(struct spl_fixed31_32 arg1, long long arg2)
|
||||
{
|
||||
return spl_fixpt_from_fraction(arg1.value, spl_fixpt_from_int((int)arg2).value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = arg1 / arg2
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_div(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
return spl_fixpt_from_fraction(arg1.value, arg2.value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Reciprocal function
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = reciprocal(arg) := 1 / arg
|
||||
*
|
||||
* @note
|
||||
* No special actions taken in case argument is zero.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_recip(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Trigonometric functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = sinc(arg) := sin(arg) / arg
|
||||
*
|
||||
* @note
|
||||
* Argument specified in radians,
|
||||
* internally it's normalized to [-2pi...2pi] range.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_sinc(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = sin(arg)
|
||||
*
|
||||
* @note
|
||||
* Argument specified in radians,
|
||||
* internally it's normalized to [-2pi...2pi] range.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_sin(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = cos(arg)
|
||||
*
|
||||
* @note
|
||||
* Argument specified in radians
|
||||
* and should be in [-2pi...2pi] range -
|
||||
* passing arguments outside that range
|
||||
* will cause incorrect result!
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_cos(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Transcendent functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = exp(arg)
|
||||
*
|
||||
* @note
|
||||
* Currently, function is verified for abs(arg) <= 1.
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_exp(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = log(arg)
|
||||
*
|
||||
* @note
|
||||
* Currently, abs(arg) should be less than 1.
|
||||
* No normalization is done.
|
||||
* Currently, no special actions taken
|
||||
* in case of invalid argument(s). Take care!
|
||||
*/
|
||||
struct spl_fixed31_32 spl_fixpt_log(struct spl_fixed31_32 arg);
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Power function
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = pow(arg1, arg2)
|
||||
*
|
||||
* @note
|
||||
* Currently, abs(arg1) should be less than 1. Take care!
|
||||
*/
|
||||
static inline struct spl_fixed31_32 spl_fixpt_pow(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)
|
||||
{
|
||||
if (arg1.value == 0)
|
||||
return arg2.value == 0 ? spl_fixpt_one : spl_fixpt_zero;
|
||||
|
||||
return spl_fixpt_exp(
|
||||
spl_fixpt_mul(
|
||||
spl_fixpt_log(arg1),
|
||||
arg2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* Rounding functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = floor(arg) := greatest integer lower than or equal to arg
|
||||
*/
|
||||
static inline int spl_fixpt_floor(struct spl_fixed31_32 arg)
|
||||
{
|
||||
unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
|
||||
|
||||
if (arg.value >= 0)
|
||||
return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
else
|
||||
return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = round(arg) := integer nearest to arg
|
||||
*/
|
||||
static inline int spl_fixpt_round(struct spl_fixed31_32 arg)
|
||||
{
|
||||
unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
|
||||
|
||||
const long long summand = spl_fixpt_half.value;
|
||||
|
||||
ASSERT(LLONG_MAX - (long long)arg_value >= summand);
|
||||
|
||||
arg_value += summand;
|
||||
|
||||
if (arg.value >= 0)
|
||||
return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
else
|
||||
return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief
|
||||
* result = ceil(arg) := lowest integer greater than or equal to arg
|
||||
*/
|
||||
static inline int spl_fixpt_ceil(struct spl_fixed31_32 arg)
|
||||
{
|
||||
unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
|
||||
|
||||
const long long summand = spl_fixpt_one.value -
|
||||
spl_fixpt_epsilon.value;
|
||||
|
||||
ASSERT(LLONG_MAX - (long long)arg_value >= summand);
|
||||
|
||||
arg_value += summand;
|
||||
|
||||
if (arg.value >= 0)
|
||||
return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
else
|
||||
return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
}
|
||||
|
||||
/* the following two function are used in scaler hw programming to convert fixed
|
||||
* point value to format 2 bits from integer part and 19 bits from fractional
|
||||
* part. The same applies for u0d19, 0 bits from integer part and 19 bits from
|
||||
* fractional
|
||||
*/
|
||||
|
||||
unsigned int spl_fixpt_u4d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_u3d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_u2d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_u0d19(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg);
|
||||
|
||||
unsigned int spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg);
|
||||
|
||||
int spl_fixpt_s4d19(struct spl_fixed31_32 arg);
|
||||
|
||||
static inline struct spl_fixed31_32 spl_fixpt_truncate(struct spl_fixed31_32 arg, unsigned int frac_bits)
|
||||
{
|
||||
bool negative = arg.value < 0;
|
||||
|
||||
if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
|
||||
ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
|
||||
return arg;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
arg.value &= (~0ULL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
|
||||
if (negative)
|
||||
arg.value = -arg.value;
|
||||
return arg;
|
||||
}
|
||||
|
||||
struct spl_fixed31_32 spl_fixpt_from_ux_dy(unsigned int value, unsigned int integer_bits, unsigned int fractional_bits);
|
||||
struct spl_fixed31_32 spl_fixpt_from_int_dy(unsigned int int_value,
|
||||
unsigned int frac_value,
|
||||
unsigned int integer_bits,
|
||||
unsigned int fractional_bits);
|
||||
|
||||
#endif
|
@ -1,28 +1,7 @@
|
||||
/*
|
||||
* Copyright 2012-16 Advanced Micro Devices, Inc.
|
||||
* Copyright 2019 Raptor Engineering, LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
/* Copyright 2024 Advanced Micro Devices, Inc. */
|
||||
/* Copyright 2019 Raptor Engineering, LLC */
|
||||
|
||||
#ifndef _SPL_OS_TYPES_H_
|
||||
#define _SPL_OS_TYPES_H_
|
||||
@ -39,7 +18,6 @@
|
||||
* general debug capabilities
|
||||
*
|
||||
*/
|
||||
// TODO: need backport
|
||||
#define SPL_BREAK_TO_DEBUGGER() ASSERT(0)
|
||||
|
||||
static inline uint64_t spl_div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
|
||||
|
@ -111,7 +111,7 @@
|
||||
#define DMUB_MAX_PHANTOM_PLANES ((DMUB_MAX_PLANES) / 2)
|
||||
|
||||
/* Trace buffer offset for entry */
|
||||
#define TRACE_BUFFER_ENTRY_OFFSET 16
|
||||
#define TRACE_BUFFER_ENTRY_OFFSET 16
|
||||
|
||||
/**
|
||||
* Maximum number of dirty rects supported by FW.
|
||||
@ -1879,7 +1879,12 @@ enum dmub_cmd_idle_opt_type {
|
||||
/**
|
||||
* DCN hardware notify idle.
|
||||
*/
|
||||
DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE = 2
|
||||
DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE = 2,
|
||||
|
||||
/**
|
||||
* DCN hardware notify power state.
|
||||
*/
|
||||
DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1906,6 +1911,33 @@ struct dmub_rb_cmd_idle_opt_dcn_notify_idle {
|
||||
struct dmub_dcn_notify_idle_cntl_data cntl_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dmub_idle_opt_dc_power_state - DC power states.
|
||||
*/
|
||||
enum dmub_idle_opt_dc_power_state {
|
||||
DMUB_IDLE_OPT_DC_POWER_STATE_UNKNOWN = 0,
|
||||
DMUB_IDLE_OPT_DC_POWER_STATE_D0 = 1,
|
||||
DMUB_IDLE_OPT_DC_POWER_STATE_D1 = 2,
|
||||
DMUB_IDLE_OPT_DC_POWER_STATE_D2 = 4,
|
||||
DMUB_IDLE_OPT_DC_POWER_STATE_D3 = 8,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dmub_idle_opt_set_dc_power_state_data - Data passed to FW in a DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE command.
|
||||
*/
|
||||
struct dmub_idle_opt_set_dc_power_state_data {
|
||||
uint8_t power_state; /**< power state */
|
||||
uint8_t pad[3]; /**< padding */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dmub_rb_cmd_idle_opt_set_dc_power_state - Data passed to FW in a DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE command.
|
||||
*/
|
||||
struct dmub_rb_cmd_idle_opt_set_dc_power_state {
|
||||
struct dmub_cmd_header header; /**< header */
|
||||
struct dmub_idle_opt_set_dc_power_state_data data;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dmub_clocks - Clock update notification.
|
||||
*/
|
||||
@ -5298,6 +5330,10 @@ union dmub_rb_cmd {
|
||||
* Definition of a DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE command.
|
||||
*/
|
||||
struct dmub_rb_cmd_idle_opt_dcn_notify_idle idle_opt_notify_idle;
|
||||
/**
|
||||
* Definition of a DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE command.
|
||||
*/
|
||||
struct dmub_rb_cmd_idle_opt_set_dc_power_state idle_opt_set_dc_power_state;
|
||||
/*
|
||||
* Definition of a DMUB_CMD__REPLAY_COPY_SETTINGS command.
|
||||
*/
|
||||
|
@ -61,7 +61,7 @@ enum amd_apu_flags {
|
||||
* acquires the list of IP blocks for the GPU in use on initialization.
|
||||
* It can then operate on this list to perform standard driver operations
|
||||
* such as: init, fini, suspend, resume, etc.
|
||||
*
|
||||
*
|
||||
*
|
||||
* IP block implementations are named using the following convention:
|
||||
* <functionality>_v<version> (E.g.: gfx_v6_0).
|
||||
@ -251,19 +251,92 @@ enum DC_FEATURE_MASK {
|
||||
DC_REPLAY_MASK = (1 << 9), //0x200, disabled by default for dcn < 3.1.4
|
||||
};
|
||||
|
||||
/**
|
||||
* enum DC_DEBUG_MASK - Bits that are useful for debugging the Display Core IP
|
||||
*/
|
||||
enum DC_DEBUG_MASK {
|
||||
/**
|
||||
* @DC_DISABLE_PIPE_SPLIT: If set, disable pipe-splitting
|
||||
*/
|
||||
DC_DISABLE_PIPE_SPLIT = 0x1,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_STUTTER: If set, disable memory stutter mode
|
||||
*/
|
||||
DC_DISABLE_STUTTER = 0x2,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_DSC: If set, disable display stream compression
|
||||
*/
|
||||
DC_DISABLE_DSC = 0x4,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_CLOCK_GATING: If set, disable clock gating optimizations
|
||||
*/
|
||||
DC_DISABLE_CLOCK_GATING = 0x8,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_PSR: If set, disable Panel self refresh v1 and PSR-SU
|
||||
*/
|
||||
DC_DISABLE_PSR = 0x10,
|
||||
|
||||
/**
|
||||
* @DC_FORCE_SUBVP_MCLK_SWITCH: If set, force mclk switch in subvp, even
|
||||
* if mclk switch in vblank is possible
|
||||
*/
|
||||
DC_FORCE_SUBVP_MCLK_SWITCH = 0x20,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_MPO: If set, disable multi-plane offloading
|
||||
*/
|
||||
DC_DISABLE_MPO = 0x40,
|
||||
|
||||
/**
|
||||
* @DC_ENABLE_DPIA_TRACE: If set, enable trace logging for DPIA
|
||||
*/
|
||||
DC_ENABLE_DPIA_TRACE = 0x80,
|
||||
|
||||
/**
|
||||
* @DC_ENABLE_DML2: If set, force usage of DML2, even if the DCN version
|
||||
* does not default to it.
|
||||
*/
|
||||
DC_ENABLE_DML2 = 0x100,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_PSR_SU: If set, disable PSR SU
|
||||
*/
|
||||
DC_DISABLE_PSR_SU = 0x200,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_REPLAY: If set, disable Panel Replay
|
||||
*/
|
||||
DC_DISABLE_REPLAY = 0x400,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_IPS: If set, disable all Idle Power States, all the time.
|
||||
* If more than one IPS debug bit is set, the lowest bit takes
|
||||
* precedence. For example, if DC_FORCE_IPS_ENABLE and
|
||||
* DC_DISABLE_IPS_DYNAMIC are set, then DC_DISABLE_IPS_DYNAMIC takes
|
||||
* precedence.
|
||||
*/
|
||||
DC_DISABLE_IPS = 0x800,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_IPS_DYNAMIC: If set, disable all IPS, all the time,
|
||||
* *except* when driver goes into suspend.
|
||||
*/
|
||||
DC_DISABLE_IPS_DYNAMIC = 0x1000,
|
||||
|
||||
/**
|
||||
* @DC_DISABLE_IPS2_DYNAMIC: If set, disable IPS2 (IPS1 allowed) if
|
||||
* there is an enabled display. Otherwise, enable all IPS.
|
||||
*/
|
||||
DC_DISABLE_IPS2_DYNAMIC = 0x2000,
|
||||
|
||||
/**
|
||||
* @DC_FORCE_IPS_ENABLE: If set, force enable all IPS, all the time.
|
||||
*/
|
||||
DC_FORCE_IPS_ENABLE = 0x4000,
|
||||
};
|
||||
|
||||
enum amd_dpm_forced_level;
|
||||
|
@ -1257,7 +1257,6 @@ static int smu_sw_init(void *handle)
|
||||
atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);
|
||||
atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1);
|
||||
|
||||
smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
|
||||
smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
|
||||
smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
|
||||
smu->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
|
||||
@ -1265,6 +1264,7 @@ static int smu_sw_init(void *handle)
|
||||
smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;
|
||||
smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
|
||||
smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
|
||||
smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
|
||||
|
||||
smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
|
||||
smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
|
||||
@ -2224,8 +2224,9 @@ static int smu_bump_power_profile_mode(struct smu_context *smu,
|
||||
}
|
||||
|
||||
static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
enum amd_dpm_forced_level level,
|
||||
bool skip_display_settings)
|
||||
enum amd_dpm_forced_level level,
|
||||
bool skip_display_settings,
|
||||
bool force_update)
|
||||
{
|
||||
int ret = 0;
|
||||
int index = 0;
|
||||
@ -2254,7 +2255,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
}
|
||||
}
|
||||
|
||||
if (smu_dpm_ctx->dpm_level != level) {
|
||||
if (force_update || smu_dpm_ctx->dpm_level != level) {
|
||||
ret = smu_asic_set_performance_level(smu, level);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "Failed to set performance level!");
|
||||
@ -2271,7 +2272,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
|
||||
workload[0] = smu->workload_setting[index];
|
||||
|
||||
if (smu->power_profile_mode != workload[0])
|
||||
if (force_update || smu->power_profile_mode != workload[0])
|
||||
smu_bump_power_profile_mode(smu, workload, 0);
|
||||
}
|
||||
|
||||
@ -2292,11 +2293,13 @@ static int smu_handle_task(struct smu_context *smu,
|
||||
ret = smu_pre_display_config_changed(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, false);
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, false, false);
|
||||
break;
|
||||
case AMD_PP_TASK_COMPLETE_INIT:
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, true, true);
|
||||
break;
|
||||
case AMD_PP_TASK_READJUST_POWER_STATE:
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, true);
|
||||
ret = smu_adjust_power_state_dynamic(smu, level, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2378,7 +2378,7 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
|
||||
|
||||
size += sysfs_emit_at(buf, size, " ");
|
||||
for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++)
|
||||
size += sysfs_emit_at(buf, size, "%-14s%s", amdgpu_pp_profile_name[i],
|
||||
size += sysfs_emit_at(buf, size, "%d %-14s%s", i, amdgpu_pp_profile_name[i],
|
||||
(i == smu->power_profile_mode) ? "* " : " ");
|
||||
|
||||
size += sysfs_emit_at(buf, size, "\n");
|
||||
@ -2408,7 +2408,7 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
|
||||
do { \
|
||||
size += sysfs_emit_at(buf, size, "%-30s", #field); \
|
||||
for (j = 0; j <= PP_SMC_POWER_PROFILE_WINDOW3D; j++) \
|
||||
size += sysfs_emit_at(buf, size, "%-16d", activity_monitor_external[j].DpmActivityMonitorCoeffInt.field); \
|
||||
size += sysfs_emit_at(buf, size, "%-18d", activity_monitor_external[j].DpmActivityMonitorCoeffInt.field); \
|
||||
size += sysfs_emit_at(buf, size, "\n"); \
|
||||
} while (0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user