drm fixes for 6.1-rc1
amdgpu: - DC mutex fix - DC SubVP fixes - DCN 3.2.x fixes - DCN 3.1.x fixes - SDMA 6.x fixes - Enable DPIA for 3.1.4 - VRR fixes - VRAM BO swapping fix - Revert dirty fb helper change - SR-IOV suspend/resume fixes - Work around GCC array bounds check fail warning - UMC 8.10 fixes - Misc fixes and cleanups i915: - Round to closest in g4x+ HDMI clock readout - Update MOCS table for EHL - Fix PSR_IMR/IIR field handling - Fix watermark calculations for gen12+/DG2 modifiers - Reject excessive dotclocks early - Fix revocation of non-persistent contexts - Handle migration for dpt - Fix display problems after resume - Allow control over the flags when migrating - Consider DG2_RC_CCS_CC when migrating buffers -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmNIrI0ACgkQDHTzWXnE hr4muRAAm6mywF0G9LhtVuYhpl5A8EZR5as4PxE1nSdLs4t1+OSJ6MfJoY/Ihvc6 LMzMadDMHoZbY/9z0MZDJEfeBSTRjTu1+g8u63d0tMf0YqI8/3D53sOodlULftc4 9YwjyB4G2xol/fk81Z5IgIcFilW5M8OjqMHuswxb0k92aF3arkHkVT+w0Njd26dK Fqxm7Z8FbdQFlWeZLaY43K4CGQUqMtg2Xcc+F/ciNAs9a6QwTudaenchSdXMBzCW OMv14KLDG3YO+tndOESmKVE9qJ0X/7J8mzUpxfzbcAalGJQpctTGPiy/UBLQvOzx BKOSCVRg+1LPRnpnj9nZWCrs5oWCaDWr1XjYNP7za8wukHIr3sGRST1sDkVqzeKw Ct62V9H5ix3I9UG/QXSguY30Vq/w7zPJQuQy+CWNKGjsXR8hVyCc2NTIk1FlDMww vRjOD9stbSdX5hGS/lSi2xZ9ERPi2L73bPQblosKl3Gi65kScvdzl2F9PSuMGsik rK1PB2I7dj1gJp4f8RmQZCrN0UlfH/YAVn5rpZSejAE+mFGG0/qzgBkIkNhAHB9s 3cg/EiDRbGQ6zxffE6GGP4HN6E9vVtuOVJl8sGR90aDRvVyTXKgTXiXRfHGc9BZj xc6sRPQjjWvHVopN354A9bJs3InT9rwEOw/0PHhK1GXE4htkGpc= =X1UY -----END PGP SIGNATURE----- Merge tag 'drm-next-2022-10-14' of git://anongit.freedesktop.org/drm/drm Pull more drm updates from Dave Airlie: "Round of fixes for the merge window stuff, bunch of amdgpu and i915 changes, this should have the gcc11 warning fix, amongst other changes. amdgpu: - DC mutex fix - DC SubVP fixes - DCN 3.2.x fixes - DCN 3.1.x fixes - SDMA 6.x fixes - Enable DPIA for 3.1.4 - VRR fixes - VRAM BO swapping fix - Revert dirty fb helper change - SR-IOV suspend/resume fixes - Work around GCC array bounds check fail warning - UMC 8.10 fixes - Misc fixes and cleanups i915: - Round to closest in g4x+ HDMI clock readout - Update MOCS table for EHL - Fix PSR_IMR/IIR field handling - Fix watermark calculations for gen12+/DG2 modifiers - Reject excessive dotclocks early - Fix revocation of non-persistent contexts - Handle migration for dpt - Fix display problems after resume - Allow control over the flags when migrating - Consider DG2_RC_CCS_CC when migrating buffers" * tag 'drm-next-2022-10-14' of git://anongit.freedesktop.org/drm/drm: (110 commits) drm/amd/display: Add HUBP surface flip interrupt handler drm/i915/display: consider DG2_RC_CCS_CC when migrating buffers drm/i915: allow control over the flags when migrating drm/amd/display: Simplify bool conversion drm/amd/display: fix transfer function passed to build_coefficients() drm/amd/display: add a license to cursor_reg_cache.h drm/amd/display: make virtual_disable_link_output static drm/amd/display: fix indentation in dc.c drm/amd/display: make dcn32_split_stream_for_mpc_or_odm static drm/amd/display: fix build error on arm64 drm/amd/display: 3.2.207 drm/amd/display: Clean some DCN32 macros drm/amdgpu: Add poison mode query for umc v8_10_0 drm/amdgpu: Update umc v8_10_0 headers drm/amdgpu: fix coding style issue for mca notifier drm/amdgpu: define convert_error_address for umc v8.7 drm/amdgpu: define RAS convert_error_address API drm/amdgpu: remove check for CE in RAS error address query drm/i915: Fix display problems after resume drm/amd/display: fix array-bounds error in dc_stream_remove_writeback() [take 2] ...
This commit is contained in:
Коммит
9c9155a350
|
@ -75,9 +75,6 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
|
|||
return;
|
||||
|
||||
adev->kfd.dev = kgd2kfd_probe(adev, vf);
|
||||
|
||||
if (adev->kfd.dev)
|
||||
amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,6 +198,8 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
|||
adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev,
|
||||
adev_to_drm(adev), &gpu_resources);
|
||||
|
||||
amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
|
||||
|
||||
INIT_WORK(&adev->kfd.reset_work, amdgpu_amdkfd_reset_work);
|
||||
}
|
||||
}
|
||||
|
@ -210,6 +209,7 @@ void amdgpu_amdkfd_device_fini_sw(struct amdgpu_device *adev)
|
|||
if (adev->kfd.dev) {
|
||||
kgd2kfd_device_exit(adev->kfd.dev);
|
||||
adev->kfd.dev = NULL;
|
||||
amdgpu_amdkfd_total_mem_size -= adev->gmc.real_vram_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_damage_helper.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
|
@ -500,12 +498,6 @@ static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
|
|||
.create_handle = drm_gem_fb_create_handle,
|
||||
};
|
||||
|
||||
static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = {
|
||||
.destroy = drm_gem_fb_destroy,
|
||||
.create_handle = drm_gem_fb_create_handle,
|
||||
.dirty = drm_atomic_helper_dirtyfb,
|
||||
};
|
||||
|
||||
uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
||||
uint64_t bo_flags)
|
||||
{
|
||||
|
@ -1108,10 +1100,8 @@ static int amdgpu_display_gem_fb_verify_and_init(struct drm_device *dev,
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (drm_drv_uses_atomic_modeset(dev))
|
||||
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs_atomic);
|
||||
else
|
||||
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
|
||||
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -688,13 +688,16 @@ int amdgpu_bo_create_vm(struct amdgpu_device *adev,
|
|||
* num of amdgpu_vm_pt entries.
|
||||
*/
|
||||
BUG_ON(bp->bo_ptr_size < sizeof(struct amdgpu_bo_vm));
|
||||
bp->destroy = &amdgpu_bo_vm_destroy;
|
||||
r = amdgpu_bo_create(adev, bp, &bo_ptr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
*vmbo_ptr = to_amdgpu_bo_vm(bo_ptr);
|
||||
INIT_LIST_HEAD(&(*vmbo_ptr)->shadow_list);
|
||||
/* Set destroy callback to amdgpu_bo_vm_destroy after vmbo->shadow_list
|
||||
* is initialized.
|
||||
*/
|
||||
bo_ptr->tbo.destroy = &amdgpu_bo_vm_destroy;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -2877,9 +2877,9 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
|||
err_data.err_addr =
|
||||
kcalloc(adev->umc.max_ras_err_cnt_per_query,
|
||||
sizeof(struct eeprom_table_record), GFP_KERNEL);
|
||||
if(!err_data.err_addr) {
|
||||
dev_warn(adev->dev, "Failed to alloc memory for "
|
||||
"umc error address record in mca notifier!\n");
|
||||
if (!err_data.err_addr) {
|
||||
dev_warn(adev->dev,
|
||||
"Failed to alloc memory for umc error record in mca notifier!\n");
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
@ -2889,7 +2889,7 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
|||
if (adev->umc.ras &&
|
||||
adev->umc.ras->convert_ras_error_address)
|
||||
adev->umc.ras->convert_ras_error_address(adev,
|
||||
&err_data, 0, ch_inst, umc_inst, m->addr);
|
||||
&err_data, m->addr, ch_inst, umc_inst);
|
||||
|
||||
if (amdgpu_bad_page_threshold != 0) {
|
||||
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
|
||||
|
|
|
@ -222,8 +222,10 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
|
|||
adev->sdma.instance[instance].fw->data;
|
||||
version_major = le16_to_cpu(header->header_version_major);
|
||||
|
||||
if ((duplicate && instance) || (!duplicate && version_major > 1))
|
||||
return -EINVAL;
|
||||
if ((duplicate && instance) || (!duplicate && version_major > 1)) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = amdgpu_sdma_init_inst_ctx(&adev->sdma.instance[instance]);
|
||||
if (err)
|
||||
|
@ -272,7 +274,7 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
|
|||
ALIGN(le32_to_cpu(sdma_hdr->ctl_ucode_size_bytes), PAGE_SIZE);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,3 +285,24 @@ out:
|
|||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
if (adev->sdma.has_page_queue) {
|
||||
sdma = &adev->sdma.instance[i].page;
|
||||
if (adev->mman.buffer_funcs_ring == sdma) {
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sdma = &adev->sdma.instance[i].ring;
|
||||
if (adev->mman.buffer_funcs_ring == sdma) {
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,4 +128,6 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
|
|||
char *fw_name, u32 instance, bool duplicate);
|
||||
void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
|
||||
bool duplicate);
|
||||
void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -424,8 +424,9 @@ error:
|
|||
static bool amdgpu_mem_visible(struct amdgpu_device *adev,
|
||||
struct ttm_resource *mem)
|
||||
{
|
||||
uint64_t mem_size = (u64)mem->num_pages << PAGE_SHIFT;
|
||||
u64 mem_size = (u64)mem->num_pages << PAGE_SHIFT;
|
||||
struct amdgpu_res_cursor cursor;
|
||||
u64 end;
|
||||
|
||||
if (mem->mem_type == TTM_PL_SYSTEM ||
|
||||
mem->mem_type == TTM_PL_TT)
|
||||
|
@ -434,12 +435,18 @@ static bool amdgpu_mem_visible(struct amdgpu_device *adev,
|
|||
return false;
|
||||
|
||||
amdgpu_res_first(mem, 0, mem_size, &cursor);
|
||||
end = cursor.start + cursor.size;
|
||||
while (cursor.remaining) {
|
||||
amdgpu_res_next(&cursor, cursor.size);
|
||||
|
||||
/* ttm_resource_ioremap only supports contiguous memory */
|
||||
if (cursor.size != mem_size)
|
||||
return false;
|
||||
/* ttm_resource_ioremap only supports contiguous memory */
|
||||
if (end != cursor.start)
|
||||
return false;
|
||||
|
||||
return cursor.start + cursor.size <= adev->gmc.visible_vram_size;
|
||||
end = cursor.start + cursor.size;
|
||||
}
|
||||
|
||||
return end <= adev->gmc.visible_vram_size;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#define __AMDGPU_UMC_H__
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
#define UMC_INVALID_ADDR 0x1ULL
|
||||
|
||||
/*
|
||||
* (addr / 256) * 4096, the higher 26 bits in ErrorAddr
|
||||
* is the index of 4KB block
|
||||
|
@ -54,9 +52,8 @@ struct amdgpu_umc_ras {
|
|||
void (*err_cnt_init)(struct amdgpu_device *adev);
|
||||
bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
|
||||
void (*convert_ras_error_address)(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data,
|
||||
uint32_t umc_reg_offset, uint32_t ch_inst,
|
||||
uint32_t umc_inst, uint64_t mca_addr);
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst);
|
||||
void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev,
|
||||
|
|
|
@ -309,14 +309,10 @@ static void cik_sdma_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq
|
|||
*/
|
||||
static void cik_sdma_gfx_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].ring;
|
||||
struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].ring;
|
||||
u32 rb_cntl;
|
||||
int i;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma0) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma1))
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]);
|
||||
|
|
|
@ -342,14 +342,10 @@ static void sdma_v2_4_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
*/
|
||||
static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].ring;
|
||||
struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].ring;
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma0) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma1))
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]);
|
||||
|
|
|
@ -516,14 +516,10 @@ static void sdma_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
*/
|
||||
static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].ring;
|
||||
struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].ring;
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma0) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma1))
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]);
|
||||
|
|
|
@ -915,18 +915,12 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
*/
|
||||
static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i, unset = 0;
|
||||
int i;
|
||||
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sdma[i] = &adev->sdma.instance[i].ring;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma[i]) && unset != 1) {
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
unset = 1;
|
||||
}
|
||||
|
||||
rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL);
|
||||
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
|
||||
WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl);
|
||||
|
@ -957,20 +951,12 @@ static void sdma_v4_0_rlc_stop(struct amdgpu_device *adev)
|
|||
*/
|
||||
static void sdma_v4_0_page_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i;
|
||||
bool unset = false;
|
||||
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sdma[i] = &adev->sdma.instance[i].page;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma[i]) &&
|
||||
(!unset)) {
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
unset = true;
|
||||
}
|
||||
|
||||
rb_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL);
|
||||
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_PAGE_RB_CNTL,
|
||||
RB_ENABLE, 0);
|
||||
|
@ -1954,8 +1940,11 @@ static int sdma_v4_0_hw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* disable the scheduler for SDMA */
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
|
||||
|
|
|
@ -584,14 +584,10 @@ static void sdma_v5_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
*/
|
||||
static void sdma_v5_0_gfx_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].ring;
|
||||
struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].ring;
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma0) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma1))
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL));
|
||||
|
@ -1460,8 +1456,11 @@ static int sdma_v5_0_hw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* disable the scheduler for SDMA */
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdma_v5_0_ctx_switch_enable(adev, false);
|
||||
sdma_v5_0_enable(adev, false);
|
||||
|
|
|
@ -414,18 +414,10 @@ static void sdma_v5_2_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
*/
|
||||
static void sdma_v5_2_gfx_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].ring;
|
||||
struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].ring;
|
||||
struct amdgpu_ring *sdma2 = &adev->sdma.instance[2].ring;
|
||||
struct amdgpu_ring *sdma3 = &adev->sdma.instance[3].ring;
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma0) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma1) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma2) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma3))
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL));
|
||||
|
@ -1357,8 +1349,11 @@ static int sdma_v5_2_hw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* disable the scheduler for SDMA */
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdma_v5_2_ctx_switch_enable(adev, false);
|
||||
sdma_v5_2_enable(adev, false);
|
||||
|
|
|
@ -398,14 +398,10 @@ static void sdma_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
*/
|
||||
static void sdma_v6_0_gfx_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].ring;
|
||||
struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].ring;
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i;
|
||||
|
||||
if ((adev->mman.buffer_funcs_ring == sdma0) ||
|
||||
(adev->mman.buffer_funcs_ring == sdma1))
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
rb_cntl = RREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_CNTL));
|
||||
|
@ -415,9 +411,6 @@ static void sdma_v6_0_gfx_stop(struct amdgpu_device *adev)
|
|||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_QUEUE0_IB_CNTL, IB_ENABLE, 0);
|
||||
WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_IB_CNTL), ib_cntl);
|
||||
}
|
||||
|
||||
sdma0->sched.ready = false;
|
||||
sdma1->sched.ready = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -846,7 +839,8 @@ static int sdma_v6_0_mqd_init(struct amdgpu_device *adev, void *mqd,
|
|||
m->sdmax_rlcx_rb_cntl =
|
||||
order_base_2(prop->queue_size / 4) << SDMA0_QUEUE0_RB_CNTL__RB_SIZE__SHIFT |
|
||||
1 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
|
||||
4 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
|
||||
4 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT |
|
||||
1 << SDMA0_QUEUE0_RB_CNTL__F32_WPTR_POLL_ENABLE__SHIFT;
|
||||
|
||||
m->sdmax_rlcx_rb_base = lower_32_bits(prop->hqd_base_gpu_addr >> 8);
|
||||
m->sdmax_rlcx_rb_base_hi = upper_32_bits(prop->hqd_base_gpu_addr >> 8);
|
||||
|
@ -1317,8 +1311,11 @@ static int sdma_v6_0_hw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* disable the scheduler for SDMA */
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdma_v6_0_ctx_switch_enable(adev, false);
|
||||
sdma_v6_0_enable(adev, false);
|
||||
|
|
|
@ -116,15 +116,14 @@ static void si_dma_stop(struct amdgpu_device *adev)
|
|||
u32 rb_cntl;
|
||||
unsigned i;
|
||||
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
ring = &adev->sdma.instance[i].ring;
|
||||
/* dma0 */
|
||||
rb_cntl = RREG32(DMA_RB_CNTL + sdma_offsets[i]);
|
||||
rb_cntl &= ~DMA_RB_ENABLE;
|
||||
WREG32(DMA_RB_CNTL + sdma_offsets[i], rb_cntl);
|
||||
|
||||
if (adev->mman.buffer_funcs_ring == ring)
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -629,6 +629,7 @@ static int soc21_common_early_init(void *handle)
|
|||
AMD_CG_SUPPORT_JPEG_MGCG;
|
||||
adev->pg_flags =
|
||||
AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
adev->external_rev_id = adev->rev_id + 0x1;
|
||||
|
|
|
@ -327,10 +327,9 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
|
|||
return;
|
||||
}
|
||||
|
||||
/* calculate error address if ue/ce error is detected */
|
||||
/* calculate error address if ue error is detected */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1) {
|
||||
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
/* the lowest lsb bits should be ignored */
|
||||
|
@ -343,10 +342,7 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
|
|||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(err_addr);
|
||||
|
||||
/* we only save ue error information currently, ce is skipped */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
|
||||
== 1)
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,20 +187,51 @@ static void umc_v6_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
static void umc_v6_7_convert_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst)
|
||||
{
|
||||
uint32_t channel_index;
|
||||
uint64_t soc_pa, retired_page, column;
|
||||
|
||||
channel_index =
|
||||
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
/* translate umc channel address to soc pa, 3 parts are included */
|
||||
soc_pa = ADDR_OF_8KB_BLOCK(err_addr) |
|
||||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(err_addr);
|
||||
|
||||
/* The umc channel bits are not original values, they are hashed */
|
||||
SET_CHANNEL_HASH(channel_index, soc_pa);
|
||||
|
||||
/* clear [C4 C3 C2] in soc physical address */
|
||||
soc_pa &= ~(0x7ULL << UMC_V6_7_PA_C2_BIT);
|
||||
|
||||
/* loop for all possibilities of [C4 C3 C2] */
|
||||
for (column = 0; column < UMC_V6_7_NA_MAP_PA_NUM; column++) {
|
||||
retired_page = soc_pa | (column << UMC_V6_7_PA_C2_BIT);
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
|
||||
/* shift R14 bit */
|
||||
retired_page ^= (0x1ULL << UMC_V6_7_PA_R14_BIT);
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
}
|
||||
}
|
||||
|
||||
static void umc_v6_7_ecc_info_query_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data,
|
||||
uint32_t ch_inst,
|
||||
uint32_t umc_inst)
|
||||
{
|
||||
uint64_t mc_umc_status, err_addr, soc_pa, retired_page, column;
|
||||
uint32_t channel_index;
|
||||
uint64_t mc_umc_status, err_addr;
|
||||
uint32_t eccinfo_table_idx;
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
|
||||
eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
|
||||
channel_index =
|
||||
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
|
||||
mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
|
||||
|
||||
if (mc_umc_status == 0)
|
||||
|
@ -209,42 +240,15 @@ static void umc_v6_7_ecc_info_query_error_address(struct amdgpu_device *adev,
|
|||
if (!err_data->err_addr)
|
||||
return;
|
||||
|
||||
/* calculate error address if ue/ce error is detected */
|
||||
/* calculate error address if ue error is detected */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1) {
|
||||
|
||||
err_addr = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_addr;
|
||||
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
|
||||
/* translate umc channel address to soc pa, 3 parts are included */
|
||||
soc_pa = ADDR_OF_8KB_BLOCK(err_addr) |
|
||||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(err_addr);
|
||||
|
||||
/* The umc channel bits are not original values, they are hashed */
|
||||
SET_CHANNEL_HASH(channel_index, soc_pa);
|
||||
|
||||
/* clear [C4 C3 C2] in soc physical address */
|
||||
soc_pa &= ~(0x7ULL << UMC_V6_7_PA_C2_BIT);
|
||||
|
||||
/* we only save ue error information currently, ce is skipped */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
|
||||
== 1) {
|
||||
/* loop for all possibilities of [C4 C3 C2] */
|
||||
for (column = 0; column < UMC_V6_7_NA_MAP_PA_NUM; column++) {
|
||||
retired_page = soc_pa | (column << UMC_V6_7_PA_C2_BIT);
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
|
||||
/* shift R14 bit */
|
||||
retired_page ^= (0x1ULL << UMC_V6_7_PA_R14_BIT);
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
}
|
||||
}
|
||||
umc_v6_7_convert_error_address(adev, err_data, err_addr,
|
||||
ch_inst, umc_inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,81 +457,40 @@ static void umc_v6_7_query_ras_error_count(struct amdgpu_device *adev,
|
|||
static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data,
|
||||
uint32_t umc_reg_offset, uint32_t ch_inst,
|
||||
uint32_t umc_inst, uint64_t mca_addr)
|
||||
uint32_t umc_inst)
|
||||
{
|
||||
uint32_t mc_umc_status_addr;
|
||||
uint32_t channel_index;
|
||||
uint64_t mc_umc_status = 0, mc_umc_addrt0;
|
||||
uint64_t err_addr, soc_pa, retired_page, column;
|
||||
uint64_t mc_umc_status = 0, mc_umc_addrt0, err_addr;
|
||||
|
||||
if (mca_addr == UMC_INVALID_ADDR) {
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
|
||||
mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
|
||||
mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
|
||||
|
||||
if (mc_umc_status == 0)
|
||||
return;
|
||||
if (mc_umc_status == 0)
|
||||
return;
|
||||
|
||||
if (!err_data->err_addr) {
|
||||
/* clear umc status */
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
return;
|
||||
}
|
||||
if (!err_data->err_addr) {
|
||||
/* clear umc status */
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
return;
|
||||
}
|
||||
|
||||
channel_index =
|
||||
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
/* calculate error address if ue error is detected */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1) {
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
err_addr =
|
||||
REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
|
||||
/* calculate error address if ue/ce error is detected */
|
||||
if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) ||
|
||||
mca_addr != UMC_INVALID_ADDR) {
|
||||
if (mca_addr == UMC_INVALID_ADDR) {
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
err_addr =
|
||||
REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
} else {
|
||||
err_addr = mca_addr;
|
||||
}
|
||||
|
||||
/* translate umc channel address to soc pa, 3 parts are included */
|
||||
soc_pa = ADDR_OF_8KB_BLOCK(err_addr) |
|
||||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(err_addr);
|
||||
|
||||
/* The umc channel bits are not original values, they are hashed */
|
||||
SET_CHANNEL_HASH(channel_index, soc_pa);
|
||||
|
||||
/* clear [C4 C3 C2] in soc physical address */
|
||||
soc_pa &= ~(0x7ULL << UMC_V6_7_PA_C2_BIT);
|
||||
|
||||
/* we only save ue error information currently, ce is skipped */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
|
||||
== 1 ||
|
||||
mca_addr != UMC_INVALID_ADDR) {
|
||||
/* loop for all possibilities of [C4 C3 C2] */
|
||||
for (column = 0; column < UMC_V6_7_NA_MAP_PA_NUM; column++) {
|
||||
retired_page = soc_pa | (column << UMC_V6_7_PA_C2_BIT);
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
|
||||
/* shift R14 bit */
|
||||
retired_page ^= (0x1ULL << UMC_V6_7_PA_R14_BIT);
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
}
|
||||
}
|
||||
umc_v6_7_convert_error_address(adev, err_data, err_addr,
|
||||
ch_inst, umc_inst);
|
||||
}
|
||||
|
||||
/* clear umc status */
|
||||
if (mca_addr == UMC_INVALID_ADDR)
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
}
|
||||
|
||||
static void umc_v6_7_query_ras_error_address(struct amdgpu_device *adev,
|
||||
|
@ -549,7 +512,7 @@ static void umc_v6_7_query_ras_error_address(struct amdgpu_device *adev,
|
|||
umc_v6_7_query_error_address(adev,
|
||||
err_data,
|
||||
umc_reg_offset, ch_inst,
|
||||
umc_inst, UMC_INVALID_ADDR);
|
||||
umc_inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,5 +553,5 @@ struct amdgpu_umc_ras umc_v6_7_ras = {
|
|||
.query_ras_poison_mode = umc_v6_7_query_ras_poison_mode,
|
||||
.ecc_info_query_ras_error_count = umc_v6_7_ecc_info_query_ras_error_count,
|
||||
.ecc_info_query_ras_error_address = umc_v6_7_ecc_info_query_ras_error_address,
|
||||
.convert_ras_error_address = umc_v6_7_query_error_address,
|
||||
.convert_ras_error_address = umc_v6_7_convert_error_address,
|
||||
};
|
||||
|
|
|
@ -208,7 +208,10 @@ static void umc_v8_10_query_error_address(struct amdgpu_device *adev,
|
|||
{
|
||||
uint64_t mc_umc_status_addr;
|
||||
uint64_t mc_umc_status, err_addr;
|
||||
uint32_t channel_index;
|
||||
uint64_t mc_umc_addrt0, na_err_addr_base;
|
||||
uint64_t na_err_addr, retired_page_addr;
|
||||
uint32_t channel_index, addr_lsb, col = 0;
|
||||
int ret = 0;
|
||||
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
|
@ -229,13 +232,10 @@ static void umc_v8_10_query_error_address(struct amdgpu_device *adev,
|
|||
umc_inst * adev->umc.channel_inst_num +
|
||||
ch_inst];
|
||||
|
||||
/* calculate error address if ue/ce error is detected */
|
||||
/* calculate error address if ue error is detected */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, AddrV) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
|
||||
uint32_t addr_lsb;
|
||||
uint64_t mc_umc_addrt0;
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1) {
|
||||
|
||||
mc_umc_addrt0 = SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
|
@ -243,32 +243,24 @@ static void umc_v8_10_query_error_address(struct amdgpu_device *adev,
|
|||
|
||||
/* the lowest lsb bits should be ignored */
|
||||
addr_lsb = REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, AddrLsb);
|
||||
|
||||
err_addr &= ~((0x1ULL << addr_lsb) - 1);
|
||||
na_err_addr_base = err_addr & ~(0x3ULL << UMC_V8_10_NA_C5_BIT);
|
||||
|
||||
/* we only save ue error information currently, ce is skipped */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1) {
|
||||
uint64_t na_err_addr_base = err_addr & ~(0x3ULL << UMC_V8_10_NA_C5_BIT);
|
||||
uint64_t na_err_addr, retired_page_addr;
|
||||
uint32_t col = 0;
|
||||
int ret = 0;
|
||||
/* loop for all possibilities of [C6 C5] in normal address. */
|
||||
for (col = 0; col < UMC_V8_10_NA_COL_2BITS_POWER_OF_2_NUM; col++) {
|
||||
na_err_addr = na_err_addr_base | (col << UMC_V8_10_NA_C5_BIT);
|
||||
|
||||
/* loop for all possibilities of [C6 C5] in normal address. */
|
||||
for (col = 0; col < UMC_V8_10_NA_COL_2BITS_POWER_OF_2_NUM; col++) {
|
||||
na_err_addr = na_err_addr_base | (col << UMC_V8_10_NA_C5_BIT);
|
||||
|
||||
/* Mapping normal error address to retired soc physical address. */
|
||||
ret = umc_v8_10_swizzle_mode_na_to_pa(adev, channel_index,
|
||||
na_err_addr, &retired_page_addr);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to map pa from umc na.\n");
|
||||
break;
|
||||
}
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n",
|
||||
retired_page_addr);
|
||||
amdgpu_umc_fill_error_record(err_data, na_err_addr,
|
||||
retired_page_addr, channel_index, umc_inst);
|
||||
/* Mapping normal error address to retired soc physical address. */
|
||||
ret = umc_v8_10_swizzle_mode_na_to_pa(adev, channel_index,
|
||||
na_err_addr, &retired_page_addr);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to map pa from umc na.\n");
|
||||
break;
|
||||
}
|
||||
dev_info(adev->dev, "Error Address(PA): 0x%llx\n",
|
||||
retired_page_addr);
|
||||
amdgpu_umc_fill_error_record(err_data, na_err_addr,
|
||||
retired_page_addr, channel_index, umc_inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,6 +330,31 @@ static void umc_v8_10_err_cnt_init(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t umc_v8_10_query_ras_poison_mode_per_channel(
|
||||
struct amdgpu_device *adev,
|
||||
uint32_t umc_reg_offset)
|
||||
{
|
||||
uint32_t ecc_ctrl_addr, ecc_ctrl;
|
||||
|
||||
ecc_ctrl_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regUMCCH0_0_GeccCtrl);
|
||||
ecc_ctrl = RREG32_PCIE((ecc_ctrl_addr +
|
||||
umc_reg_offset) * 4);
|
||||
|
||||
return REG_GET_FIELD(ecc_ctrl, UMCCH0_0_GeccCtrl, UCFatalEn);
|
||||
}
|
||||
|
||||
static bool umc_v8_10_query_ras_poison_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t umc_reg_offset = 0;
|
||||
|
||||
/* Enabling fatal error in umc node0 instance0 channel0 will be
|
||||
* considered as fatal error mode
|
||||
*/
|
||||
umc_reg_offset = get_umc_v8_10_reg_offset(adev, 0, 0, 0);
|
||||
return !umc_v8_10_query_ras_poison_mode_per_channel(adev, umc_reg_offset);
|
||||
}
|
||||
|
||||
const struct amdgpu_ras_block_hw_ops umc_v8_10_ras_hw_ops = {
|
||||
.query_ras_error_count = umc_v8_10_query_ras_error_count,
|
||||
.query_ras_error_address = umc_v8_10_query_ras_error_address,
|
||||
|
@ -348,4 +365,5 @@ struct amdgpu_umc_ras umc_v8_10_ras = {
|
|||
.hw_ops = &umc_v8_10_ras_hw_ops,
|
||||
},
|
||||
.err_cnt_init = umc_v8_10_err_cnt_init,
|
||||
.query_ras_poison_mode = umc_v8_10_query_ras_poison_mode,
|
||||
};
|
||||
|
|
|
@ -108,20 +108,35 @@ static void umc_v8_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
static void umc_v8_7_convert_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst)
|
||||
{
|
||||
uint64_t retired_page;
|
||||
uint32_t channel_index;
|
||||
|
||||
channel_index =
|
||||
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
|
||||
/* translate umc channel address to soc pa, 3 parts are included */
|
||||
retired_page = ADDR_OF_4KB_BLOCK(err_addr) |
|
||||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(err_addr);
|
||||
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
}
|
||||
|
||||
static void umc_v8_7_ecc_info_query_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data,
|
||||
uint32_t ch_inst,
|
||||
uint32_t umc_inst)
|
||||
{
|
||||
uint64_t mc_umc_status, err_addr, retired_page;
|
||||
uint32_t channel_index;
|
||||
uint64_t mc_umc_status, err_addr;
|
||||
uint32_t eccinfo_table_idx;
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
|
||||
eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
|
||||
channel_index =
|
||||
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
|
||||
mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
|
||||
|
||||
if (mc_umc_status == 0)
|
||||
|
@ -130,24 +145,15 @@ static void umc_v8_7_ecc_info_query_error_address(struct amdgpu_device *adev,
|
|||
if (!err_data->err_addr)
|
||||
return;
|
||||
|
||||
/* calculate error address if ue/ce error is detected */
|
||||
/* calculate error address if ue error is detected */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1) {
|
||||
|
||||
err_addr = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_addr;
|
||||
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
|
||||
/* translate umc channel address to soc pa, 3 parts are included */
|
||||
retired_page = ADDR_OF_4KB_BLOCK(err_addr) |
|
||||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(err_addr);
|
||||
|
||||
/* we only save ue error information currently, ce is skipped */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
|
||||
== 1)
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
umc_v8_7_convert_error_address(adev, err_data, err_addr,
|
||||
ch_inst, umc_inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,14 +330,12 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev,
|
|||
uint32_t umc_inst)
|
||||
{
|
||||
uint32_t lsb, mc_umc_status_addr;
|
||||
uint64_t mc_umc_status, err_addr, retired_page, mc_umc_addrt0;
|
||||
uint32_t channel_index = adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
uint64_t mc_umc_status, err_addr, mc_umc_addrt0;
|
||||
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
|
||||
mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
|
||||
|
||||
if (mc_umc_status == 0)
|
||||
|
@ -343,10 +347,9 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev,
|
|||
return;
|
||||
}
|
||||
|
||||
/* calculate error address if ue/ce error is detected */
|
||||
/* calculate error address if ue error is detected */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1) {
|
||||
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
/* the lowest lsb bits should be ignored */
|
||||
|
@ -354,16 +357,8 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev,
|
|||
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
err_addr &= ~((0x1ULL << lsb) - 1);
|
||||
|
||||
/* translate umc channel address to soc pa, 3 parts are included */
|
||||
retired_page = ADDR_OF_4KB_BLOCK(err_addr) |
|
||||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(err_addr);
|
||||
|
||||
/* we only save ue error information currently, ce is skipped */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
|
||||
== 1)
|
||||
amdgpu_umc_fill_error_record(err_data, err_addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
umc_v8_7_convert_error_address(adev, err_data, err_addr,
|
||||
ch_inst, umc_inst);
|
||||
}
|
||||
|
||||
/* clear umc status */
|
||||
|
|
|
@ -333,7 +333,8 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
|
|||
<< SDMA0_QUEUE0_RB_CNTL__RB_SIZE__SHIFT |
|
||||
q->vmid << SDMA0_QUEUE0_RB_CNTL__RB_VMID__SHIFT |
|
||||
1 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
|
||||
6 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
|
||||
6 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT |
|
||||
1 << SDMA0_QUEUE0_RB_CNTL__F32_WPTR_POLL_ENABLE__SHIFT;
|
||||
|
||||
m->sdmax_rlcx_rb_base = lower_32_bits(q->queue_address >> 8);
|
||||
m->sdmax_rlcx_rb_base_hi = upper_32_bits(q->queue_address >> 8);
|
||||
|
|
|
@ -1110,7 +1110,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
|
|||
hw_params.fb[i] = &fb_info->fb[i];
|
||||
|
||||
switch (adev->ip_versions[DCE_HWIP][0]) {
|
||||
case IP_VERSION(3, 1, 3): /* Only for this asic hw internal rev B0 */
|
||||
case IP_VERSION(3, 1, 3):
|
||||
case IP_VERSION(3, 1, 4):
|
||||
hw_params.dpia_supported = true;
|
||||
hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
|
||||
break;
|
||||
|
@ -7478,15 +7479,15 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state,
|
|||
* We also need vupdate irq for the actual core vblank handling
|
||||
* at end of vblank.
|
||||
*/
|
||||
dm_set_vupdate_irq(new_state->base.crtc, true);
|
||||
drm_crtc_vblank_get(new_state->base.crtc);
|
||||
WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, true) != 0);
|
||||
WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0);
|
||||
DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n",
|
||||
__func__, new_state->base.crtc->base.id);
|
||||
} else if (old_vrr_active && !new_vrr_active) {
|
||||
/* Transition VRR active -> inactive:
|
||||
* Allow vblank irq disable again for fixed refresh rate.
|
||||
*/
|
||||
dm_set_vupdate_irq(new_state->base.crtc, false);
|
||||
WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, false) != 0);
|
||||
drm_crtc_vblank_put(new_state->base.crtc);
|
||||
DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n",
|
||||
__func__, new_state->base.crtc->base.id);
|
||||
|
@ -8242,23 +8243,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
mutex_unlock(&dm->dc_lock);
|
||||
}
|
||||
|
||||
/* Count number of newly disabled CRTCs for dropping PM refs later. */
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
if (old_crtc_state->active && !new_crtc_state->active)
|
||||
crtc_disable_count++;
|
||||
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
|
||||
/* For freesync config update on crtc state and params for irq */
|
||||
update_stream_irq_parameters(dm, dm_new_crtc_state);
|
||||
|
||||
/* Handle vrr on->off / off->on transitions */
|
||||
amdgpu_dm_handle_vrr_transition(dm_old_crtc_state,
|
||||
dm_new_crtc_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable interrupts for CRTCs that are newly enabled or went through
|
||||
* a modeset. It was intentionally deferred until after the front end
|
||||
|
@ -8268,16 +8252,29 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
bool configure_crc = false;
|
||||
enum amdgpu_dm_pipe_crc_source cur_crc_src;
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
struct crc_rd_work *crc_rd_wrk = dm->crc_rd_wrk;
|
||||
struct crc_rd_work *crc_rd_wrk;
|
||||
#endif
|
||||
#endif
|
||||
/* Count number of newly disabled CRTCs for dropping PM refs later. */
|
||||
if (old_crtc_state->active && !new_crtc_state->active)
|
||||
crtc_disable_count++;
|
||||
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
|
||||
/* For freesync config update on crtc state and params for irq */
|
||||
update_stream_irq_parameters(dm, dm_new_crtc_state);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
crc_rd_wrk = dm->crc_rd_wrk;
|
||||
#endif
|
||||
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
||||
cur_crc_src = acrtc->dm_irq_params.crc_src;
|
||||
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
|
||||
#endif
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
|
||||
if (new_crtc_state->active &&
|
||||
(!old_crtc_state->active ||
|
||||
|
@ -8285,16 +8282,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
dc_stream_retain(dm_new_crtc_state->stream);
|
||||
acrtc->dm_irq_params.stream = dm_new_crtc_state->stream;
|
||||
manage_dm_interrupts(adev, acrtc, true);
|
||||
}
|
||||
/* Handle vrr on->off / off->on transitions */
|
||||
amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, dm_new_crtc_state);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
if (new_crtc_state->active &&
|
||||
(!old_crtc_state->active ||
|
||||
drm_atomic_crtc_needs_modeset(new_crtc_state))) {
|
||||
/**
|
||||
* Frontend may have changed so reapply the CRC capture
|
||||
* settings for the stream.
|
||||
*/
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
|
||||
if (amdgpu_dm_is_valid_crc_source(cur_crc_src)) {
|
||||
configure_crc = true;
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
if (amdgpu_dm_crc_window_is_activated(crtc)) {
|
||||
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
||||
|
@ -8306,12 +8306,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (configure_crc)
|
||||
if (amdgpu_dm_crtc_configure_crc_source(
|
||||
crtc, dm_new_crtc_state, cur_crc_src))
|
||||
DRM_DEBUG_DRIVER("Failed to configure crc source");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -9392,10 +9390,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!pre_validate_dsc(state, &dm_state, vars)) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
|
@ -9529,6 +9523,15 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dc_resource_is_dsc_encoding_supported(dc)) {
|
||||
if (!pre_validate_dsc(state, &dm_state, vars)) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Run this here since we want to validate the streams we created */
|
||||
ret = drm_atomic_helper_check_planes(dev, state);
|
||||
if (ret) {
|
||||
|
|
|
@ -60,11 +60,15 @@ static bool link_supports_psrsu(struct dc_link *link)
|
|||
*/
|
||||
void amdgpu_dm_set_psr_caps(struct dc_link *link)
|
||||
{
|
||||
if (!(link->connector_signal & SIGNAL_TYPE_EDP))
|
||||
if (!(link->connector_signal & SIGNAL_TYPE_EDP)) {
|
||||
link->psr_settings.psr_feature_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (link->type == dc_connection_none)
|
||||
if (link->type == dc_connection_none) {
|
||||
link->psr_settings.psr_feature_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (link->dpcd_caps.psr_info.psr_version == 0) {
|
||||
link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
|
||||
|
|
|
@ -51,13 +51,6 @@
|
|||
#define LAST_RECORD_TYPE 0xff
|
||||
#define SMU9_SYSPLL0_ID 0
|
||||
|
||||
struct i2c_id_config_access {
|
||||
uint8_t bfI2C_LineMux:4;
|
||||
uint8_t bfHW_EngineID:3;
|
||||
uint8_t bfHW_Capable:1;
|
||||
uint8_t ucAccess;
|
||||
};
|
||||
|
||||
static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
|
||||
struct atom_i2c_record *record,
|
||||
struct graphics_object_i2c_info *info);
|
||||
|
|
|
@ -179,7 +179,7 @@ void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr, struct
|
|||
} else if (dispclk_wdivider == 127 && current_dispclk_wdivider != 127) {
|
||||
REG_UPDATE(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DISPCLK_WDIVIDER, 126);
|
||||
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 100);
|
||||
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
|
||||
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
struct dccg *dccg = clk_mgr->base.ctx->dc->res_pool->dccg;
|
||||
|
@ -206,7 +206,7 @@ void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr, struct
|
|||
|
||||
REG_UPDATE(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DISPCLK_WDIVIDER, dispclk_wdivider);
|
||||
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 1000);
|
||||
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
|
||||
REG_UPDATE(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider);
|
||||
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100);
|
||||
|
|
|
@ -339,29 +339,24 @@ void dcn314_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zs
|
|||
if (!clk_mgr->smu_present)
|
||||
return;
|
||||
|
||||
if (!clk_mgr->base.ctx->dc->debug.enable_z9_disable_interface &&
|
||||
(support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY))
|
||||
support = DCN_ZSTATE_SUPPORT_DISALLOW;
|
||||
|
||||
|
||||
// Arg[15:0] = 8/9/0 for Z8/Z9/disallow -> existing bits
|
||||
// Arg[16] = Disallow Z9 -> new bit
|
||||
switch (support) {
|
||||
|
||||
case DCN_ZSTATE_SUPPORT_ALLOW:
|
||||
msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
|
||||
param = 9;
|
||||
param = (1 << 10) | (1 << 9) | (1 << 8);
|
||||
break;
|
||||
|
||||
case DCN_ZSTATE_SUPPORT_DISALLOW:
|
||||
msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
|
||||
param = 8;
|
||||
param = 0;
|
||||
break;
|
||||
|
||||
|
||||
case DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY:
|
||||
msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
|
||||
param = 0x00010008;
|
||||
param = (1 << 10);
|
||||
break;
|
||||
|
||||
default: //DCN_ZSTATE_SUPPORT_UNKNOWN
|
||||
|
|
|
@ -156,7 +156,7 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
|
|||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
unsigned int num_levels;
|
||||
unsigned int num_dcfclk_levels, num_dtbclk_levels, num_dispclk_levels;
|
||||
struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
|
||||
|
||||
memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
|
||||
clk_mgr_base->clks.p_state_change_support = true;
|
||||
|
@ -180,27 +180,28 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
|
|||
/* DCFCLK */
|
||||
dcn32_init_single_clock(clk_mgr, PPCLK_DCFCLK,
|
||||
&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
|
||||
&num_levels);
|
||||
num_dcfclk_levels = num_levels;
|
||||
&num_entries_per_clk->num_dcfclk_levels);
|
||||
|
||||
/* SOCCLK */
|
||||
dcn32_init_single_clock(clk_mgr, PPCLK_SOCCLK,
|
||||
&clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz,
|
||||
&num_levels);
|
||||
&num_entries_per_clk->num_socclk_levels);
|
||||
|
||||
/* DTBCLK */
|
||||
if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch)
|
||||
dcn32_init_single_clock(clk_mgr, PPCLK_DTBCLK,
|
||||
&clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz,
|
||||
&num_levels);
|
||||
num_dtbclk_levels = num_levels;
|
||||
&num_entries_per_clk->num_dtbclk_levels);
|
||||
|
||||
/* DISPCLK */
|
||||
dcn32_init_single_clock(clk_mgr, PPCLK_DISPCLK,
|
||||
&clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz,
|
||||
&num_levels);
|
||||
num_dispclk_levels = num_levels;
|
||||
&num_entries_per_clk->num_dispclk_levels);
|
||||
num_levels = num_entries_per_clk->num_dispclk_levels;
|
||||
|
||||
if (num_dcfclk_levels && num_dtbclk_levels && num_dispclk_levels)
|
||||
if (num_entries_per_clk->num_dcfclk_levels &&
|
||||
num_entries_per_clk->num_dtbclk_levels &&
|
||||
num_entries_per_clk->num_dispclk_levels)
|
||||
clk_mgr->dpm_present = true;
|
||||
|
||||
if (clk_mgr_base->ctx->dc->debug.min_disp_clk_khz) {
|
||||
|
@ -333,6 +334,21 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
if (enter_display_off == safe_to_lower)
|
||||
dcn30_smu_set_num_of_displays(clk_mgr, display_count);
|
||||
|
||||
clk_mgr_base->clks.fclk_prev_p_state_change_support = clk_mgr_base->clks.fclk_p_state_change_support;
|
||||
|
||||
total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context);
|
||||
fclk_p_state_change_support = new_clocks->fclk_p_state_change_support || (total_plane_count == 0);
|
||||
|
||||
if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_p_state_change_support)) {
|
||||
clk_mgr_base->clks.fclk_p_state_change_support = fclk_p_state_change_support;
|
||||
|
||||
/* To enable FCLK P-state switching, send FCLK_PSTATE_SUPPORTED message to PMFW */
|
||||
if (clk_mgr_base->ctx->dce_version != DCN_VERSION_3_21 && clk_mgr_base->clks.fclk_p_state_change_support) {
|
||||
/* Handle the code for sending a message to PMFW that FCLK P-state change is supported */
|
||||
dcn32_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc->debug.force_min_dcfclk_mhz > 0)
|
||||
new_clocks->dcfclk_khz = (new_clocks->dcfclk_khz > (dc->debug.force_min_dcfclk_mhz * 1000)) ?
|
||||
new_clocks->dcfclk_khz : (dc->debug.force_min_dcfclk_mhz * 1000);
|
||||
|
@ -352,7 +368,6 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz;
|
||||
|
||||
clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
|
||||
clk_mgr_base->clks.fclk_prev_p_state_change_support = clk_mgr_base->clks.fclk_p_state_change_support;
|
||||
clk_mgr_base->clks.prev_num_ways = clk_mgr_base->clks.num_ways;
|
||||
|
||||
if (clk_mgr_base->clks.num_ways != new_clocks->num_ways &&
|
||||
|
@ -361,27 +376,25 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
dcn32_smu_send_cab_for_uclk_message(clk_mgr, clk_mgr_base->clks.num_ways);
|
||||
}
|
||||
|
||||
total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context);
|
||||
|
||||
p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0);
|
||||
fclk_p_state_change_support = new_clocks->fclk_p_state_change_support || (total_plane_count == 0);
|
||||
if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
|
||||
clk_mgr_base->clks.p_state_change_support = p_state_change_support;
|
||||
|
||||
/* to disable P-State switching, set UCLK min = max */
|
||||
if (!clk_mgr_base->clks.p_state_change_support)
|
||||
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
|
||||
clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
|
||||
clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
|
||||
}
|
||||
|
||||
if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_p_state_change_support) &&
|
||||
clk_mgr_base->ctx->dce_version != DCN_VERSION_3_21) {
|
||||
clk_mgr_base->clks.fclk_p_state_change_support = fclk_p_state_change_support;
|
||||
/* Always update saved value, even if new value not set due to P-State switching unsupported. Also check safe_to_lower for FCLK */
|
||||
if (safe_to_lower && (clk_mgr_base->clks.fclk_p_state_change_support != clk_mgr_base->clks.fclk_prev_p_state_change_support)) {
|
||||
update_fclk = true;
|
||||
}
|
||||
|
||||
/* To disable FCLK P-state switching, send FCLK_PSTATE_NOTSUPPORTED message to PMFW */
|
||||
if (clk_mgr_base->ctx->dce_version != DCN_VERSION_3_21 && !clk_mgr_base->clks.fclk_p_state_change_support) {
|
||||
/* Handle code for sending a message to PMFW that FCLK P-state change is not supported */
|
||||
dcn32_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_NOTSUPPORTED);
|
||||
}
|
||||
if (clk_mgr_base->ctx->dce_version != DCN_VERSION_3_21 && !clk_mgr_base->clks.fclk_p_state_change_support && update_fclk) {
|
||||
/* Handle code for sending a message to PMFW that FCLK P-state change is not supported */
|
||||
dcn32_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_NOTSUPPORTED);
|
||||
}
|
||||
|
||||
/* Always update saved value, even if new value not set due to P-State switching unsupported */
|
||||
|
@ -390,21 +403,11 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
update_uclk = true;
|
||||
}
|
||||
|
||||
/* Always update saved value, even if new value not set due to P-State switching unsupported. Also check safe_to_lower for FCLK */
|
||||
if (safe_to_lower && (clk_mgr_base->clks.fclk_p_state_change_support != clk_mgr_base->clks.fclk_prev_p_state_change_support)) {
|
||||
update_fclk = true;
|
||||
}
|
||||
|
||||
/* set UCLK to requested value if P-State switching is supported, or to re-enable P-State switching */
|
||||
if (clk_mgr_base->clks.p_state_change_support &&
|
||||
(update_uclk || !clk_mgr_base->clks.prev_p_state_change_support))
|
||||
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
|
||||
|
||||
if (clk_mgr_base->ctx->dce_version != DCN_VERSION_3_21 && clk_mgr_base->clks.fclk_p_state_change_support && update_fclk) {
|
||||
/* Handle the code for sending a message to PMFW that FCLK P-state change is supported */
|
||||
dcn32_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_SUPPORTED);
|
||||
}
|
||||
|
||||
if (clk_mgr_base->clks.num_ways != new_clocks->num_ways &&
|
||||
clk_mgr_base->clks.num_ways > new_clocks->num_ways) {
|
||||
clk_mgr_base->clks.num_ways = new_clocks->num_ways;
|
||||
|
@ -632,7 +635,7 @@ static void dcn32_set_hard_min_memclk(struct clk_mgr *clk_mgr_base, bool current
|
|||
khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
|
||||
else
|
||||
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
|
||||
clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
|
||||
clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
|
||||
} else {
|
||||
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
|
||||
clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz);
|
||||
|
@ -648,22 +651,34 @@ static void dcn32_set_hard_max_memclk(struct clk_mgr *clk_mgr_base)
|
|||
return;
|
||||
|
||||
dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK,
|
||||
clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
|
||||
clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
|
||||
}
|
||||
|
||||
/* Get current memclk states, update bounding box */
|
||||
static void dcn32_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
|
||||
unsigned int num_levels;
|
||||
|
||||
if (!clk_mgr->smu_present)
|
||||
return;
|
||||
|
||||
/* Refresh memclk states */
|
||||
/* Refresh memclk and fclk states */
|
||||
dcn32_init_single_clock(clk_mgr, PPCLK_UCLK,
|
||||
&clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz,
|
||||
&num_levels);
|
||||
&num_entries_per_clk->num_memclk_levels);
|
||||
|
||||
dcn32_init_single_clock(clk_mgr, PPCLK_FCLK,
|
||||
&clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz,
|
||||
&num_entries_per_clk->num_fclk_levels);
|
||||
|
||||
if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) {
|
||||
num_levels = num_entries_per_clk->num_memclk_levels;
|
||||
} else {
|
||||
num_levels = num_entries_per_clk->num_fclk_levels;
|
||||
}
|
||||
|
||||
clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1;
|
||||
|
||||
if (clk_mgr->dpm_present && !num_levels)
|
||||
|
|
|
@ -1734,10 +1734,20 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||
int i, k, l;
|
||||
struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
|
||||
struct dc_state *old_state;
|
||||
bool subvp_prev_use = false;
|
||||
|
||||
dc_z10_restore(dc);
|
||||
dc_allow_idle_optimizations(dc, false);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
/* Check old context for SubVP */
|
||||
subvp_prev_use |= (old_pipe->stream && old_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM);
|
||||
if (subvp_prev_use)
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < context->stream_count; i++)
|
||||
dc_streams[i] = context->streams[i];
|
||||
|
||||
|
@ -1777,6 +1787,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
|
||||
}
|
||||
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);
|
||||
|
||||
result = dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
|
||||
if (result != DC_OK) {
|
||||
|
@ -1794,6 +1807,12 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||
dc->hwss.interdependent_update_lock(dc, context, false);
|
||||
dc->hwss.post_unlock_program_front_end(dc, context);
|
||||
}
|
||||
|
||||
if (dc->hwss.commit_subvp_config)
|
||||
dc->hwss.commit_subvp_config(dc, context);
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, false, true, NULL, subvp_prev_use);
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
const struct dc_link *link = context->streams[i]->link;
|
||||
|
||||
|
@ -2927,6 +2946,12 @@ static bool update_planes_and_stream_state(struct dc *dc,
|
|||
dc_resource_state_copy_construct(
|
||||
dc->current_state, context);
|
||||
|
||||
/* For each full update, remove all existing phantom pipes first.
|
||||
* Ensures that we have enough pipes for newly added MPO planes
|
||||
*/
|
||||
if (dc->res_pool->funcs->remove_phantom_pipes)
|
||||
dc->res_pool->funcs->remove_phantom_pipes(dc, context);
|
||||
|
||||
/*remove old surfaces from context */
|
||||
if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
|
||||
|
||||
|
@ -3334,8 +3359,14 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
/* Since phantom pipe programming is moved to post_unlock_program_front_end,
|
||||
* move the SubVP lock to after the phantom pipes have been setup
|
||||
*/
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
|
||||
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
|
||||
} else {
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3495,6 +3526,9 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
|
||||
if (update_type != UPDATE_TYPE_FAST)
|
||||
dc->hwss.post_unlock_program_front_end(dc, context);
|
||||
if (update_type != UPDATE_TYPE_FAST)
|
||||
if (dc->hwss.commit_subvp_config)
|
||||
dc->hwss.commit_subvp_config(dc, context);
|
||||
|
||||
if (update_type != UPDATE_TYPE_FAST)
|
||||
if (dc->hwss.commit_subvp_config)
|
||||
|
@ -3542,6 +3576,7 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
|||
|
||||
struct dc_stream_status *cur_stream_status = stream_get_status(dc->current_state, stream);
|
||||
bool force_minimal_pipe_splitting = false;
|
||||
uint32_t i;
|
||||
|
||||
*is_plane_addition = false;
|
||||
|
||||
|
@ -3573,6 +3608,36 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
|||
}
|
||||
}
|
||||
|
||||
/* For SubVP pipe split case when adding MPO video
|
||||
* we need to add a minimal transition. In this case
|
||||
* there will be 2 streams (1 main stream, 1 phantom
|
||||
* stream).
|
||||
*/
|
||||
if (cur_stream_status &&
|
||||
dc->current_state->stream_count == 2 &&
|
||||
stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
bool is_pipe_split = false;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream &&
|
||||
(dc->current_state->res_ctx.pipe_ctx[i].bottom_pipe ||
|
||||
dc->current_state->res_ctx.pipe_ctx[i].next_odm_pipe)) {
|
||||
is_pipe_split = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* determine if minimal transition is required due to SubVP*/
|
||||
if (surface_count > 0 && is_pipe_split) {
|
||||
if (cur_stream_status->plane_count > surface_count) {
|
||||
force_minimal_pipe_splitting = true;
|
||||
} else if (cur_stream_status->plane_count < surface_count) {
|
||||
force_minimal_pipe_splitting = true;
|
||||
*is_plane_addition = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return force_minimal_pipe_splitting;
|
||||
}
|
||||
|
||||
|
@ -3582,6 +3647,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
|
|||
struct dc_state *transition_context = dc_create_state(dc);
|
||||
enum pipe_split_policy tmp_mpc_policy;
|
||||
bool temp_dynamic_odm_policy;
|
||||
bool temp_subvp_policy;
|
||||
enum dc_status ret = DC_ERROR_UNEXPECTED;
|
||||
unsigned int i, j;
|
||||
|
||||
|
@ -3596,6 +3662,9 @@ static bool commit_minimal_transition_state(struct dc *dc,
|
|||
temp_dynamic_odm_policy = dc->debug.enable_single_display_2to1_odm_policy;
|
||||
dc->debug.enable_single_display_2to1_odm_policy = false;
|
||||
|
||||
temp_subvp_policy = dc->debug.force_disable_subvp;
|
||||
dc->debug.force_disable_subvp = true;
|
||||
|
||||
dc_resource_state_copy_construct(transition_base_context, transition_context);
|
||||
|
||||
//commit minimal state
|
||||
|
@ -3624,6 +3693,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
|
|||
dc->debug.pipe_split_policy = tmp_mpc_policy;
|
||||
|
||||
dc->debug.enable_single_display_2to1_odm_policy = temp_dynamic_odm_policy;
|
||||
dc->debug.force_disable_subvp = temp_subvp_policy;
|
||||
|
||||
if (ret != DC_OK) {
|
||||
/*this should never happen*/
|
||||
|
@ -4586,6 +4656,37 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
|
|||
return DC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_process_dmub_dpia_hpd_int_enable
|
||||
*
|
||||
* @brief
|
||||
* Submits dpia hpd int enable command to dmub via inbox message
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
* [in] hpd_int_enable: 1 for hpd int enable, 0 to disable
|
||||
*
|
||||
* @return
|
||||
* None
|
||||
*****************************************************************************
|
||||
*/
|
||||
void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
|
||||
uint32_t hpd_int_enable)
|
||||
{
|
||||
union dmub_rb_cmd cmd = {0};
|
||||
struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
|
||||
|
||||
cmd.dpia_hpd_int_enable.header.type = DMUB_CMD__DPIA_HPD_INT_ENABLE;
|
||||
cmd.dpia_hpd_int_enable.enable = hpd_int_enable;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dmub_srv);
|
||||
|
||||
DC_LOG_DEBUG("%s: hpd_int_enable(%d)\n", __func__, hpd_int_enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_disable_accelerated_mode - disable accelerated mode
|
||||
* @dc: dc structure
|
||||
|
|
|
@ -1307,7 +1307,10 @@ static bool detect_link_and_local_sink(struct dc_link *link,
|
|||
}
|
||||
|
||||
if (link->connector_signal == SIGNAL_TYPE_EDP) {
|
||||
// Init dc_panel_config
|
||||
/* Init dc_panel_config by HW config */
|
||||
if (dc_ctx->dc->res_pool->funcs->get_panel_config_defaults)
|
||||
dc_ctx->dc->res_pool->funcs->get_panel_config_defaults(&link->panel_config);
|
||||
/* Pickup base DM settings */
|
||||
dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink);
|
||||
// Override dc_panel_config if system has specific settings
|
||||
dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
|
||||
|
@ -3143,7 +3146,7 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active
|
|||
if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
|
||||
return false;
|
||||
|
||||
if (allow_active && link->type == dc_connection_none) {
|
||||
if ((allow_active != NULL) && (*allow_active == true) && (link->type == dc_connection_none)) {
|
||||
// Don't enter PSR if panel is not connected
|
||||
return false;
|
||||
}
|
||||
|
@ -3375,8 +3378,8 @@ bool dc_link_setup_psr(struct dc_link *link,
|
|||
case FAMILY_YELLOW_CARP:
|
||||
case AMDGPU_FAMILY_GC_10_3_6:
|
||||
case AMDGPU_FAMILY_GC_11_0_1:
|
||||
if(!dc->debug.disable_z10)
|
||||
psr_context->psr_level.bits.SKIP_CRTC_DISABLE = false;
|
||||
if (dc->debug.disable_z10)
|
||||
psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
|
||||
break;
|
||||
default:
|
||||
psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
|
||||
|
|
|
@ -944,6 +944,23 @@ enum dc_status dp_get_lane_status_and_lane_adjust(
|
|||
return status;
|
||||
}
|
||||
|
||||
static enum dc_status dpcd_128b_132b_set_lane_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_training_setting)
|
||||
{
|
||||
enum dc_status status = core_link_write_dpcd(link,
|
||||
DP_TRAINING_LANE0_SET,
|
||||
(uint8_t *)(link_training_setting->dpcd_lane_settings),
|
||||
sizeof(link_training_setting->dpcd_lane_settings));
|
||||
|
||||
DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
|
||||
__func__,
|
||||
DP_TRAINING_LANE0_SET,
|
||||
link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum dc_status dpcd_set_lane_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_training_setting,
|
||||
|
@ -964,16 +981,6 @@ enum dc_status dpcd_set_lane_settings(
|
|||
link_training_setting->link_settings.lane_count);
|
||||
|
||||
if (is_repeater(link_training_setting, offset)) {
|
||||
if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
|
||||
DP_128b_132b_ENCODING)
|
||||
DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
|
||||
" 0x%X TX_FFE_PRESET_VALUE = %x\n",
|
||||
__func__,
|
||||
offset,
|
||||
lane0_set_address,
|
||||
link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
|
||||
else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
|
||||
DP_8b_10b_ENCODING)
|
||||
DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n"
|
||||
" 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
|
||||
__func__,
|
||||
|
@ -985,14 +992,6 @@ enum dc_status dpcd_set_lane_settings(
|
|||
link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
|
||||
|
||||
} else {
|
||||
if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
|
||||
DP_128b_132b_ENCODING)
|
||||
DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
|
||||
__func__,
|
||||
lane0_set_address,
|
||||
link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
|
||||
else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
|
||||
DP_8b_10b_ENCODING)
|
||||
DC_LOG_HW_LINK_TRAINING("%s\n 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
|
||||
__func__,
|
||||
lane0_set_address,
|
||||
|
@ -2023,7 +2022,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
|
|||
result = DP_128b_132b_LT_FAILED;
|
||||
} else {
|
||||
dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
|
||||
dpcd_set_lane_settings(link, lt_settings, DPRX);
|
||||
dpcd_128b_132b_set_lane_settings(link, lt_settings);
|
||||
}
|
||||
loop_count++;
|
||||
}
|
||||
|
@ -5090,6 +5089,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
|
|||
(dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == 0)) {
|
||||
ASSERT(0);
|
||||
link->dpcd_caps.lttpr_caps.phy_repeater_cnt = 0x80;
|
||||
DC_LOG_DC("lttpr_caps forced phy_repeater_cnt = %d\n", link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
|
||||
}
|
||||
|
||||
/* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */
|
||||
|
@ -5098,6 +5098,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
|
|||
if (is_lttpr_present)
|
||||
CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
|
||||
|
||||
DC_LOG_DC("is_lttpr_present = %d\n", is_lttpr_present);
|
||||
return is_lttpr_present;
|
||||
}
|
||||
|
||||
|
@ -5134,6 +5135,7 @@ void dp_get_lttpr_mode_override(struct dc_link *link, enum lttpr_mode *override)
|
|||
} else if (link->dc->debug.lttpr_mode_override == LTTPR_MODE_NON_LTTPR) {
|
||||
*override = LTTPR_MODE_NON_LTTPR;
|
||||
}
|
||||
DC_LOG_DC("lttpr_mode_override chose LTTPR_MODE = %d\n", (uint8_t)(*override));
|
||||
}
|
||||
|
||||
enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link)
|
||||
|
@ -5146,22 +5148,34 @@ enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link)
|
|||
return LTTPR_MODE_NON_LTTPR;
|
||||
|
||||
if (vbios_lttpr_aware) {
|
||||
if (vbios_lttpr_force_non_transparent)
|
||||
if (vbios_lttpr_force_non_transparent) {
|
||||
DC_LOG_DC("chose LTTPR_MODE_NON_TRANSPARENT due to VBIOS DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE set to 1.\n");
|
||||
return LTTPR_MODE_NON_TRANSPARENT;
|
||||
else
|
||||
} else {
|
||||
DC_LOG_DC("chose LTTPR_MODE_NON_TRANSPARENT by default due to VBIOS not set DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE set to 1.\n");
|
||||
return LTTPR_MODE_TRANSPARENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (link->dc->config.allow_lttpr_non_transparent_mode.bits.DP1_4A &&
|
||||
link->dc->caps.extended_aux_timeout_support)
|
||||
link->dc->caps.extended_aux_timeout_support) {
|
||||
DC_LOG_DC("chose LTTPR_MODE_NON_TRANSPARENT by default and dc->config.allow_lttpr_non_transparent_mode.bits.DP1_4A set to 1.\n");
|
||||
return LTTPR_MODE_NON_TRANSPARENT;
|
||||
}
|
||||
|
||||
DC_LOG_DC("chose LTTPR_MODE_NON_LTTPR.\n");
|
||||
return LTTPR_MODE_NON_LTTPR;
|
||||
}
|
||||
|
||||
enum lttpr_mode dp_decide_128b_132b_lttpr_mode(struct dc_link *link)
|
||||
{
|
||||
return dp_is_lttpr_present(link) ? LTTPR_MODE_NON_TRANSPARENT : LTTPR_MODE_NON_LTTPR;
|
||||
enum lttpr_mode mode = LTTPR_MODE_NON_LTTPR;
|
||||
|
||||
if (dp_is_lttpr_present(link))
|
||||
mode = LTTPR_MODE_NON_TRANSPARENT;
|
||||
|
||||
DC_LOG_DC("128b_132b chose LTTPR_MODE %d.\n", mode);
|
||||
return mode;
|
||||
}
|
||||
|
||||
static bool get_usbc_cable_id(struct dc_link *link, union dp_cable_id *cable_id)
|
||||
|
@ -5179,9 +5193,10 @@ static bool get_usbc_cable_id(struct dc_link *link, union dp_cable_id *cable_id)
|
|||
cmd.cable_id.data.input.phy_inst = resource_transmitter_to_phy_idx(
|
||||
link->dc, link->link_enc->transmitter);
|
||||
if (dc_dmub_srv_cmd_with_reply_data(link->ctx->dmub_srv, &cmd) &&
|
||||
cmd.cable_id.header.ret_status == 1)
|
||||
cmd.cable_id.header.ret_status == 1) {
|
||||
cable_id->raw = cmd.cable_id.data.output_raw;
|
||||
|
||||
DC_LOG_DC("usbc_cable_id = %d.\n", cable_id->raw);
|
||||
}
|
||||
return cmd.cable_id.header.ret_status == 1;
|
||||
}
|
||||
|
||||
|
@ -5228,6 +5243,7 @@ static enum dc_status wa_try_to_wake_dprx(struct dc_link *link, uint64_t timeout
|
|||
|
||||
lttpr_present = dp_is_lttpr_present(link) ||
|
||||
(!vbios_lttpr_interop || !link->dc->caps.extended_aux_timeout_support);
|
||||
DC_LOG_DC("lttpr_present = %d.\n", lttpr_present ? 1 : 0);
|
||||
|
||||
/* Issue an AUX read to test DPRX responsiveness. If LTTPR is supported the first read is expected to
|
||||
* be to determine LTTPR capabilities. Otherwise trying to read power state should be an innocuous AUX read.
|
||||
|
@ -5795,7 +5811,7 @@ void detect_edp_sink_caps(struct dc_link *link)
|
|||
* Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
|
||||
*/
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_13 &&
|
||||
(link->dc->debug.optimize_edp_link_rate ||
|
||||
(link->panel_config.ilr.optimize_edp_link_rate ||
|
||||
link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)) {
|
||||
// Read DPCD 00010h - 0001Fh 16 bytes at one shot
|
||||
core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
|
||||
|
@ -6744,7 +6760,7 @@ bool is_edp_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timin
|
|||
ASSERT(link || crtc_timing); // invalid input
|
||||
|
||||
if (link->dpcd_caps.edp_supported_link_rates_count == 0 ||
|
||||
!link->dc->debug.optimize_edp_link_rate)
|
||||
!link->panel_config.ilr.optimize_edp_link_rate)
|
||||
return false;
|
||||
|
||||
|
||||
|
|
|
@ -1747,7 +1747,6 @@ bool dc_remove_plane_from_context(
|
|||
|
||||
for (i = 0; i < stream_status->plane_count; i++) {
|
||||
if (stream_status->plane_states[i] == plane_state) {
|
||||
|
||||
dc_plane_state_release(stream_status->plane_states[i]);
|
||||
break;
|
||||
}
|
||||
|
@ -3683,4 +3682,56 @@ bool is_h_timing_divisible_by_2(struct dc_stream_state *stream)
|
|||
(stream->timing.h_sync_width % 2 == 0);
|
||||
}
|
||||
return divisible;
|
||||
}
|
||||
|
||||
bool dc_resource_acquire_secondary_pipe_for_mpc_odm(
|
||||
const struct dc *dc,
|
||||
struct dc_state *state,
|
||||
struct pipe_ctx *pri_pipe,
|
||||
struct pipe_ctx *sec_pipe,
|
||||
bool odm)
|
||||
{
|
||||
int pipe_idx = sec_pipe->pipe_idx;
|
||||
struct pipe_ctx *sec_top, *sec_bottom, *sec_next, *sec_prev;
|
||||
const struct resource_pool *pool = dc->res_pool;
|
||||
|
||||
sec_top = sec_pipe->top_pipe;
|
||||
sec_bottom = sec_pipe->bottom_pipe;
|
||||
sec_next = sec_pipe->next_odm_pipe;
|
||||
sec_prev = sec_pipe->prev_odm_pipe;
|
||||
|
||||
*sec_pipe = *pri_pipe;
|
||||
|
||||
sec_pipe->top_pipe = sec_top;
|
||||
sec_pipe->bottom_pipe = sec_bottom;
|
||||
sec_pipe->next_odm_pipe = sec_next;
|
||||
sec_pipe->prev_odm_pipe = sec_prev;
|
||||
|
||||
sec_pipe->pipe_idx = pipe_idx;
|
||||
sec_pipe->plane_res.mi = pool->mis[pipe_idx];
|
||||
sec_pipe->plane_res.hubp = pool->hubps[pipe_idx];
|
||||
sec_pipe->plane_res.ipp = pool->ipps[pipe_idx];
|
||||
sec_pipe->plane_res.xfm = pool->transforms[pipe_idx];
|
||||
sec_pipe->plane_res.dpp = pool->dpps[pipe_idx];
|
||||
sec_pipe->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst;
|
||||
sec_pipe->stream_res.dsc = NULL;
|
||||
if (odm) {
|
||||
if (!sec_pipe->top_pipe)
|
||||
sec_pipe->stream_res.opp = pool->opps[pipe_idx];
|
||||
else
|
||||
sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp;
|
||||
if (sec_pipe->stream->timing.flags.DSC == 1) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
dcn20_acquire_dsc(dc, &state->res_ctx, &sec_pipe->stream_res.dsc, pipe_idx);
|
||||
#endif
|
||||
ASSERT(sec_pipe->stream_res.dsc);
|
||||
if (sec_pipe->stream_res.dsc == NULL)
|
||||
return false;
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
dcn20_build_mapped_resource(dc, state, sec_pipe->stream);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -276,6 +276,8 @@ static void program_cursor_attributes(
|
|||
}
|
||||
|
||||
dc->hwss.set_cursor_attribute(pipe_ctx);
|
||||
|
||||
dc_send_update_cursor_info_to_dmu(pipe_ctx, i);
|
||||
if (dc->hwss.set_cursor_sdr_white_level)
|
||||
dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
|
||||
}
|
||||
|
@ -382,6 +384,8 @@ static void program_cursor_position(
|
|||
}
|
||||
|
||||
dc->hwss.set_cursor_position(pipe_ctx);
|
||||
|
||||
dc_send_update_cursor_info_to_dmu(pipe_ctx, i);
|
||||
}
|
||||
|
||||
if (pipe_to_program)
|
||||
|
@ -520,9 +524,9 @@ bool dc_stream_remove_writeback(struct dc *dc,
|
|||
}
|
||||
|
||||
/* remove writeback info for disabled writeback pipes from stream */
|
||||
for (i = 0, j = 0; i < stream->num_wb_info && j < MAX_DWB_PIPES; i++) {
|
||||
for (i = 0, j = 0; i < stream->num_wb_info; i++) {
|
||||
if (stream->writeback_info[i].wb_enabled) {
|
||||
if (i != j)
|
||||
if (j < i)
|
||||
/* trim the array */
|
||||
stream->writeback_info[j] = stream->writeback_info[i];
|
||||
j++;
|
||||
|
|
|
@ -47,7 +47,7 @@ struct aux_payload;
|
|||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.205"
|
||||
#define DC_VER "3.2.207"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
@ -821,7 +821,6 @@ struct dc_debug_options {
|
|||
/* Enable dmub aux for legacy ddc */
|
||||
bool enable_dmub_aux_for_legacy_ddc;
|
||||
bool disable_fams;
|
||||
bool optimize_edp_link_rate; /* eDP ILR */
|
||||
/* FEC/PSR1 sequence enable delay in 100us */
|
||||
uint8_t fec_enable_delay_in100us;
|
||||
bool enable_driver_sequence_debug;
|
||||
|
@ -1192,6 +1191,8 @@ struct dc_plane_state {
|
|||
enum dc_irq_source irq_source;
|
||||
struct kref refcount;
|
||||
struct tg_color visual_confirm_color;
|
||||
|
||||
bool is_statically_allocated;
|
||||
};
|
||||
|
||||
struct dc_plane_info {
|
||||
|
@ -1611,6 +1612,9 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
|
|||
uint8_t mst_alloc_slots,
|
||||
uint8_t *mst_slots_in_use);
|
||||
|
||||
void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
|
||||
uint32_t hpd_int_enable);
|
||||
|
||||
/*******************************************************************************
|
||||
* DSC Interfaces
|
||||
******************************************************************************/
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "dc_hw_types.h"
|
||||
#include "core_types.h"
|
||||
#include "../basics/conversion.h"
|
||||
#include "cursor_reg_cache.h"
|
||||
|
||||
#define CTX dc_dmub_srv->ctx
|
||||
#define DC_LOGGER CTX->logger
|
||||
|
@ -780,7 +781,7 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
|
|||
// Store the original watermark value for this SubVP config so we can lower it when the
|
||||
// MCLK switch starts
|
||||
wm_val_refclk = context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns *
|
||||
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 / 1000;
|
||||
(dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000) / 1000;
|
||||
|
||||
cmd.fw_assisted_mclk_switch_v2.config_data.watermark_a_cache = wm_val_refclk < 0xFFFF ? wm_val_refclk : 0xFFFF;
|
||||
}
|
||||
|
@ -880,3 +881,147 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
|
|||
diag_data.is_cw0_enabled,
|
||||
diag_data.is_cw6_enabled);
|
||||
}
|
||||
|
||||
static bool dc_dmub_should_update_cursor_data(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
if (pipe_ctx->plane_state != NULL) {
|
||||
if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 ||
|
||||
pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) &&
|
||||
pipe_ctx->stream->ctx->dce_version >= DCN_VERSION_3_1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dc_build_cursor_update_payload0(
|
||||
struct pipe_ctx *pipe_ctx, uint8_t p_idx,
|
||||
struct dmub_cmd_update_cursor_payload0 *payload)
|
||||
{
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
unsigned int panel_inst = 0;
|
||||
|
||||
if (!dc_get_edp_link_panel_inst(hubp->ctx->dc,
|
||||
pipe_ctx->stream->link, &panel_inst))
|
||||
return;
|
||||
|
||||
/* Payload: Cursor Rect is built from position & attribute
|
||||
* x & y are obtained from postion
|
||||
*/
|
||||
payload->cursor_rect.x = hubp->cur_rect.x;
|
||||
payload->cursor_rect.y = hubp->cur_rect.y;
|
||||
/* w & h are obtained from attribute */
|
||||
payload->cursor_rect.width = hubp->cur_rect.w;
|
||||
payload->cursor_rect.height = hubp->cur_rect.h;
|
||||
|
||||
payload->enable = hubp->pos.cur_ctl.bits.cur_enable;
|
||||
payload->pipe_idx = p_idx;
|
||||
payload->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
|
||||
payload->panel_inst = panel_inst;
|
||||
}
|
||||
|
||||
static void dc_send_cmd_to_dmu(struct dc_dmub_srv *dmub_srv,
|
||||
union dmub_rb_cmd *cmd)
|
||||
{
|
||||
dc_dmub_srv_cmd_queue(dmub_srv, cmd);
|
||||
dc_dmub_srv_cmd_execute(dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dmub_srv);
|
||||
}
|
||||
|
||||
static void dc_build_cursor_position_update_payload0(
|
||||
struct dmub_cmd_update_cursor_payload0 *pl, const uint8_t p_idx,
|
||||
const struct hubp *hubp, const struct dpp *dpp)
|
||||
{
|
||||
/* Hubp */
|
||||
pl->position_cfg.pHubp.cur_ctl.raw = hubp->pos.cur_ctl.raw;
|
||||
pl->position_cfg.pHubp.position.raw = hubp->pos.position.raw;
|
||||
pl->position_cfg.pHubp.hot_spot.raw = hubp->pos.hot_spot.raw;
|
||||
pl->position_cfg.pHubp.dst_offset.raw = hubp->pos.dst_offset.raw;
|
||||
|
||||
/* dpp */
|
||||
pl->position_cfg.pDpp.cur0_ctl.raw = dpp->pos.cur0_ctl.raw;
|
||||
pl->position_cfg.pipe_idx = p_idx;
|
||||
}
|
||||
|
||||
static void dc_build_cursor_attribute_update_payload1(
|
||||
struct dmub_cursor_attributes_cfg *pl_A, const uint8_t p_idx,
|
||||
const struct hubp *hubp, const struct dpp *dpp)
|
||||
{
|
||||
/* Hubp */
|
||||
pl_A->aHubp.SURFACE_ADDR_HIGH = hubp->att.SURFACE_ADDR_HIGH;
|
||||
pl_A->aHubp.SURFACE_ADDR = hubp->att.SURFACE_ADDR;
|
||||
pl_A->aHubp.cur_ctl.raw = hubp->att.cur_ctl.raw;
|
||||
pl_A->aHubp.size.raw = hubp->att.size.raw;
|
||||
pl_A->aHubp.settings.raw = hubp->att.settings.raw;
|
||||
|
||||
/* dpp */
|
||||
pl_A->aDpp.cur0_ctl.raw = dpp->att.cur0_ctl.raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* ***************************************************************************************
|
||||
* dc_send_update_cursor_info_to_dmu: Populate the DMCUB Cursor update info command
|
||||
*
|
||||
* This function would store the cursor related information and pass it into dmub
|
||||
*
|
||||
* @param [in] pCtx: pipe context
|
||||
* @param [in] pipe_idx: pipe index
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* ***************************************************************************************
|
||||
*/
|
||||
|
||||
void dc_send_update_cursor_info_to_dmu(
|
||||
struct pipe_ctx *pCtx, uint8_t pipe_idx)
|
||||
{
|
||||
union dmub_rb_cmd cmd = { 0 };
|
||||
union dmub_cmd_update_cursor_info_data *update_cursor_info =
|
||||
&cmd.update_cursor_info.update_cursor_info_data;
|
||||
|
||||
if (!dc_dmub_should_update_cursor_data(pCtx))
|
||||
return;
|
||||
/*
|
||||
* Since we use multi_cmd_pending for dmub command, the 2nd command is
|
||||
* only assigned to store cursor attributes info.
|
||||
* 1st command can view as 2 parts, 1st is for PSR/Replay data, the other
|
||||
* is to store cursor position info.
|
||||
*
|
||||
* Command heaer type must be the same type if using multi_cmd_pending.
|
||||
* Besides, while process 2nd command in DMU, the sub type is useless.
|
||||
* So it's meanless to pass the sub type header with different type.
|
||||
*/
|
||||
|
||||
{
|
||||
/* Build Payload#0 Header */
|
||||
cmd.update_cursor_info.header.type = DMUB_CMD__UPDATE_CURSOR_INFO;
|
||||
cmd.update_cursor_info.header.payload_bytes =
|
||||
sizeof(cmd.update_cursor_info.update_cursor_info_data);
|
||||
cmd.update_cursor_info.header.multi_cmd_pending = 1; /* To combine multi dmu cmd, 1st cmd */
|
||||
|
||||
/* Prepare Payload */
|
||||
dc_build_cursor_update_payload0(pCtx, pipe_idx, &update_cursor_info->payload0);
|
||||
|
||||
dc_build_cursor_position_update_payload0(&update_cursor_info->payload0, pipe_idx,
|
||||
pCtx->plane_res.hubp, pCtx->plane_res.dpp);
|
||||
/* Send update_curosr_info to queue */
|
||||
dc_dmub_srv_cmd_queue(pCtx->stream->ctx->dmub_srv, &cmd);
|
||||
}
|
||||
{
|
||||
/* Build Payload#1 Header */
|
||||
memset(update_cursor_info, 0, sizeof(union dmub_cmd_update_cursor_info_data));
|
||||
cmd.update_cursor_info.header.type = DMUB_CMD__UPDATE_CURSOR_INFO;
|
||||
cmd.update_cursor_info.header.payload_bytes = sizeof(struct cursor_attributes_cfg);
|
||||
cmd.update_cursor_info.header.multi_cmd_pending = 0; /* Indicate it's the last command. */
|
||||
|
||||
dc_build_cursor_attribute_update_payload1(
|
||||
&cmd.update_cursor_info.update_cursor_info_data.payload1.attribute_cfg,
|
||||
pipe_idx, pCtx->plane_res.hubp, pCtx->plane_res.dpp);
|
||||
|
||||
/* Combine 2nd cmds update_curosr_info to DMU */
|
||||
dc_send_cmd_to_dmu(pCtx->stream->ctx->dmub_srv, &cmd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,4 +88,5 @@ bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmu
|
|||
void dc_dmub_setup_subvp_dmub_command(struct dc *dc, struct dc_state *context, bool enable);
|
||||
void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv);
|
||||
|
||||
void dc_send_update_cursor_info_to_dmu(struct pipe_ctx *pCtx, uint8_t pipe_idx);
|
||||
#endif /* _DMUB_DC_SRV_H_ */
|
||||
|
|
|
@ -138,6 +138,10 @@ struct dc_panel_config {
|
|||
bool disable_dsc_edp;
|
||||
unsigned int force_dsc_edp_policy;
|
||||
} dsc;
|
||||
/* eDP ILR */
|
||||
struct ilr {
|
||||
bool optimize_edp_link_rate; /* eDP ILR */
|
||||
} ilr;
|
||||
};
|
||||
/*
|
||||
* A link contains one or more sinks and their connected status.
|
||||
|
|
|
@ -942,10 +942,6 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
|
|||
case AUX_RET_ERROR_ENGINE_ACQUIRE:
|
||||
case AUX_RET_ERROR_UNKNOWN:
|
||||
default:
|
||||
DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
|
||||
LOG_FLAG_I2cAux_DceAux,
|
||||
"dce_aux_transfer_with_retries: Failure: operation_result=%d",
|
||||
(int)operation_result);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -953,14 +949,11 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
|
|||
fail:
|
||||
DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
|
||||
LOG_FLAG_Error_I2cAux,
|
||||
"dce_aux_transfer_with_retries: FAILURE");
|
||||
"%s: Failure: operation_result=%d",
|
||||
__func__,
|
||||
(int)operation_result);
|
||||
if (!payload_reply)
|
||||
payload->reply = NULL;
|
||||
|
||||
DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
|
||||
WPP_BIT_FLAG_DC_ERROR,
|
||||
"AUX transaction failed. Result: %d",
|
||||
operation_result);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -469,6 +469,7 @@ void dpp1_set_cursor_position(
|
|||
REG_UPDATE(CURSOR0_CONTROL,
|
||||
CUR0_ENABLE, cur_en);
|
||||
|
||||
dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
|
||||
}
|
||||
|
||||
void dpp1_cnv_set_optional_cursor_attributes(
|
||||
|
|
|
@ -2244,6 +2244,9 @@ void dcn10_enable_timing_synchronization(
|
|||
DC_SYNC_INFO("Setting up OTG reset trigger\n");
|
||||
|
||||
for (i = 1; i < group_size; i++) {
|
||||
if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
opp = grouped_pipes[i]->stream_res.opp;
|
||||
tg = grouped_pipes[i]->stream_res.tg;
|
||||
tg->funcs->get_otg_active_size(tg, &width, &height);
|
||||
|
@ -2254,13 +2257,21 @@ void dcn10_enable_timing_synchronization(
|
|||
for (i = 0; i < group_size; i++) {
|
||||
if (grouped_pipes[i]->stream == NULL)
|
||||
continue;
|
||||
|
||||
if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
grouped_pipes[i]->stream->vblank_synchronized = false;
|
||||
}
|
||||
|
||||
for (i = 1; i < group_size; i++)
|
||||
for (i = 1; i < group_size; i++) {
|
||||
if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
|
||||
grouped_pipes[i]->stream_res.tg,
|
||||
grouped_pipes[0]->stream_res.tg->inst);
|
||||
}
|
||||
|
||||
DC_SYNC_INFO("Waiting for trigger\n");
|
||||
|
||||
|
@ -2268,12 +2279,21 @@ void dcn10_enable_timing_synchronization(
|
|||
* synchronized. Look at last pipe programmed to reset.
|
||||
*/
|
||||
|
||||
wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[1]->stream_res.tg);
|
||||
for (i = 1; i < group_size; i++)
|
||||
grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
|
||||
grouped_pipes[i]->stream_res.tg);
|
||||
if (grouped_pipes[1]->stream && grouped_pipes[1]->stream->mall_stream_config.type != SUBVP_PHANTOM)
|
||||
wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[1]->stream_res.tg);
|
||||
|
||||
for (i = 1; i < group_size; i++) {
|
||||
if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
|
||||
grouped_pipes[i]->stream_res.tg);
|
||||
}
|
||||
|
||||
for (i = 1; i < group_size; i++) {
|
||||
if (grouped_pipes[i]->stream && grouped_pipes[i]->stream->mall_stream_config.type == SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
opp = grouped_pipes[i]->stream_res.opp;
|
||||
tg = grouped_pipes[i]->stream_res.tg;
|
||||
tg->funcs->get_otg_active_size(tg, &width, &height);
|
||||
|
@ -3005,6 +3025,7 @@ void dcn10_prepare_bandwidth(
|
|||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct hubbub *hubbub = dc->res_pool->hubbub;
|
||||
int min_fclk_khz, min_dcfclk_khz, socclk_khz;
|
||||
|
||||
if (dc->debug.sanity_checks)
|
||||
hws->funcs.verify_allow_pstate_change_high(dc);
|
||||
|
@ -3027,8 +3048,11 @@ void dcn10_prepare_bandwidth(
|
|||
|
||||
if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
|
||||
DC_FP_START();
|
||||
dcn_bw_notify_pplib_of_wm_ranges(dc);
|
||||
dcn_get_soc_clks(
|
||||
dc, &min_fclk_khz, &min_dcfclk_khz, &socclk_khz);
|
||||
DC_FP_END();
|
||||
dcn_bw_notify_pplib_of_wm_ranges(
|
||||
dc, min_fclk_khz, min_dcfclk_khz, socclk_khz);
|
||||
}
|
||||
|
||||
if (dc->debug.sanity_checks)
|
||||
|
@ -3041,6 +3065,7 @@ void dcn10_optimize_bandwidth(
|
|||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct hubbub *hubbub = dc->res_pool->hubbub;
|
||||
int min_fclk_khz, min_dcfclk_khz, socclk_khz;
|
||||
|
||||
if (dc->debug.sanity_checks)
|
||||
hws->funcs.verify_allow_pstate_change_high(dc);
|
||||
|
@ -3064,8 +3089,11 @@ void dcn10_optimize_bandwidth(
|
|||
|
||||
if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
|
||||
DC_FP_START();
|
||||
dcn_bw_notify_pplib_of_wm_ranges(dc);
|
||||
dcn_get_soc_clks(
|
||||
dc, &min_fclk_khz, &min_dcfclk_khz, &socclk_khz);
|
||||
DC_FP_END();
|
||||
dcn_bw_notify_pplib_of_wm_ranges(
|
||||
dc, min_fclk_khz, min_dcfclk_khz, socclk_khz);
|
||||
}
|
||||
|
||||
if (dc->debug.sanity_checks)
|
||||
|
@ -3344,127 +3372,6 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool dcn10_dmub_should_update_cursor_data(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_debug_options *debug)
|
||||
{
|
||||
if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
return false;
|
||||
|
||||
if (dcn10_can_pipe_disable_cursor(pipe_ctx))
|
||||
return false;
|
||||
|
||||
if ((pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 || pipe_ctx->stream->link->psr_settings.psr_version == DC_PSR_VERSION_1)
|
||||
&& pipe_ctx->stream->ctx->dce_version >= DCN_VERSION_3_1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dcn10_dmub_update_cursor_data(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct hubp *hubp,
|
||||
const struct dc_cursor_mi_param *param,
|
||||
const struct dc_cursor_position *cur_pos,
|
||||
const struct dc_cursor_attributes *cur_attr)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dmub_cmd_update_cursor_info_data *update_cursor_info;
|
||||
const struct dc_cursor_position *pos;
|
||||
const struct dc_cursor_attributes *attr;
|
||||
int src_x_offset = 0;
|
||||
int src_y_offset = 0;
|
||||
int x_hotspot = 0;
|
||||
int cursor_height = 0;
|
||||
int cursor_width = 0;
|
||||
uint32_t cur_en = 0;
|
||||
unsigned int panel_inst = 0;
|
||||
|
||||
struct dc_debug_options *debug = &hubp->ctx->dc->debug;
|
||||
|
||||
if (!dcn10_dmub_should_update_cursor_data(pipe_ctx, debug))
|
||||
return;
|
||||
/**
|
||||
* if cur_pos == NULL means the caller is from cursor_set_attribute
|
||||
* then driver use previous cursor position data
|
||||
* if cur_attr == NULL means the caller is from cursor_set_position
|
||||
* then driver use previous cursor attribute
|
||||
* if cur_pos or cur_attr is not NULL then update it
|
||||
*/
|
||||
if (cur_pos != NULL)
|
||||
pos = cur_pos;
|
||||
else
|
||||
pos = &hubp->curs_pos;
|
||||
|
||||
if (cur_attr != NULL)
|
||||
attr = cur_attr;
|
||||
else
|
||||
attr = &hubp->curs_attr;
|
||||
|
||||
if (!dc_get_edp_link_panel_inst(hubp->ctx->dc, pipe_ctx->stream->link, &panel_inst))
|
||||
return;
|
||||
|
||||
src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
|
||||
src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
|
||||
x_hotspot = pos->x_hotspot;
|
||||
cursor_height = (int)attr->height;
|
||||
cursor_width = (int)attr->width;
|
||||
cur_en = pos->enable ? 1:0;
|
||||
|
||||
// Rotated cursor width/height and hotspots tweaks for offset calculation
|
||||
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
|
||||
swap(cursor_height, cursor_width);
|
||||
if (param->rotation == ROTATION_ANGLE_90) {
|
||||
src_x_offset = pos->x - pos->y_hotspot - param->viewport.x;
|
||||
src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
|
||||
}
|
||||
} else if (param->rotation == ROTATION_ANGLE_180) {
|
||||
src_x_offset = pos->x - param->viewport.x;
|
||||
src_y_offset = pos->y - param->viewport.y;
|
||||
}
|
||||
|
||||
if (param->mirror) {
|
||||
x_hotspot = param->viewport.width - x_hotspot;
|
||||
src_x_offset = param->viewport.x + param->viewport.width - src_x_offset;
|
||||
}
|
||||
|
||||
if (src_x_offset >= (int)param->viewport.width)
|
||||
cur_en = 0; /* not visible beyond right edge*/
|
||||
|
||||
if (src_x_offset + cursor_width <= 0)
|
||||
cur_en = 0; /* not visible beyond left edge*/
|
||||
|
||||
if (src_y_offset >= (int)param->viewport.height)
|
||||
cur_en = 0; /* not visible beyond bottom edge*/
|
||||
|
||||
if (src_y_offset + cursor_height <= 0)
|
||||
cur_en = 0; /* not visible beyond top edge*/
|
||||
|
||||
// Cursor bitmaps have different hotspot values
|
||||
// There's a possibility that the above logic returns a negative value, so we clamp them to 0
|
||||
if (src_x_offset < 0)
|
||||
src_x_offset = 0;
|
||||
if (src_y_offset < 0)
|
||||
src_y_offset = 0;
|
||||
|
||||
memset(&cmd, 0x0, sizeof(cmd));
|
||||
cmd.update_cursor_info.header.type = DMUB_CMD__UPDATE_CURSOR_INFO;
|
||||
cmd.update_cursor_info.header.payload_bytes =
|
||||
sizeof(cmd.update_cursor_info.update_cursor_info_data);
|
||||
update_cursor_info = &cmd.update_cursor_info.update_cursor_info_data;
|
||||
update_cursor_info->cursor_rect.x = src_x_offset + param->viewport.x;
|
||||
update_cursor_info->cursor_rect.y = src_y_offset + param->viewport.y;
|
||||
update_cursor_info->cursor_rect.width = attr->width;
|
||||
update_cursor_info->cursor_rect.height = attr->height;
|
||||
update_cursor_info->enable = cur_en;
|
||||
update_cursor_info->pipe_idx = pipe_ctx->pipe_idx;
|
||||
update_cursor_info->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
|
||||
update_cursor_info->panel_inst = panel_inst;
|
||||
dc_dmub_srv_cmd_queue(pipe_ctx->stream->ctx->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(pipe_ctx->stream->ctx->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(pipe_ctx->stream->ctx->dmub_srv);
|
||||
}
|
||||
|
||||
void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
|
||||
|
@ -3699,7 +3606,6 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
|||
pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.y;
|
||||
}
|
||||
|
||||
dcn10_dmub_update_cursor_data(pipe_ctx, hubp, ¶m, &pos_cpy, NULL);
|
||||
hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m);
|
||||
dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width, hubp->curs_attr.height);
|
||||
}
|
||||
|
@ -3707,25 +3613,6 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
|||
void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
|
||||
struct dc_cursor_mi_param param = { 0 };
|
||||
|
||||
/**
|
||||
* If enter PSR without cursor attribute update
|
||||
* the cursor attribute of dmub_restore_plane
|
||||
* are initial value. call dmub to exit PSR and
|
||||
* restore plane then update cursor attribute to
|
||||
* avoid override with initial value
|
||||
*/
|
||||
if (pipe_ctx->plane_state != NULL) {
|
||||
param.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
|
||||
param.ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz;
|
||||
param.viewport = pipe_ctx->plane_res.scl_data.viewport;
|
||||
param.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz;
|
||||
param.v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert;
|
||||
param.rotation = pipe_ctx->plane_state->rotation;
|
||||
param.mirror = pipe_ctx->plane_state->horizontal_mirror;
|
||||
dcn10_dmub_update_cursor_data(pipe_ctx, pipe_ctx->plane_res.hubp, ¶m, NULL, attributes);
|
||||
}
|
||||
|
||||
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.hubp, attributes);
|
||||
|
@ -3810,28 +3697,14 @@ void dcn10_calc_vupdate_position(
|
|||
uint32_t *start_line,
|
||||
uint32_t *end_line)
|
||||
{
|
||||
const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;
|
||||
int vline_int_offset_from_vupdate =
|
||||
pipe_ctx->stream->periodic_interrupt.lines_offset;
|
||||
int vupdate_offset_from_vsync = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
|
||||
int start_position;
|
||||
const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
|
||||
int vupdate_pos = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
|
||||
|
||||
if (vline_int_offset_from_vupdate > 0)
|
||||
vline_int_offset_from_vupdate--;
|
||||
else if (vline_int_offset_from_vupdate < 0)
|
||||
vline_int_offset_from_vupdate++;
|
||||
|
||||
start_position = vline_int_offset_from_vupdate + vupdate_offset_from_vsync;
|
||||
|
||||
if (start_position >= 0)
|
||||
*start_line = start_position;
|
||||
if (vupdate_pos >= 0)
|
||||
*start_line = vupdate_pos - ((vupdate_pos / timing->v_total) * timing->v_total);
|
||||
else
|
||||
*start_line = dc_crtc_timing->v_total + start_position - 1;
|
||||
|
||||
*end_line = *start_line + 2;
|
||||
|
||||
if (*end_line >= dc_crtc_timing->v_total)
|
||||
*end_line = 2;
|
||||
*start_line = vupdate_pos + ((-vupdate_pos / timing->v_total) + 1) * timing->v_total - 1;
|
||||
*end_line = (*start_line + 2) % timing->v_total;
|
||||
}
|
||||
|
||||
static void dcn10_cal_vline_position(
|
||||
|
@ -3840,23 +3713,27 @@ static void dcn10_cal_vline_position(
|
|||
uint32_t *start_line,
|
||||
uint32_t *end_line)
|
||||
{
|
||||
switch (pipe_ctx->stream->periodic_interrupt.ref_point) {
|
||||
case START_V_UPDATE:
|
||||
dcn10_calc_vupdate_position(
|
||||
dc,
|
||||
pipe_ctx,
|
||||
start_line,
|
||||
end_line);
|
||||
break;
|
||||
case START_V_SYNC:
|
||||
const struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
|
||||
int vline_pos = pipe_ctx->stream->periodic_interrupt.lines_offset;
|
||||
|
||||
if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_UPDATE) {
|
||||
if (vline_pos > 0)
|
||||
vline_pos--;
|
||||
else if (vline_pos < 0)
|
||||
vline_pos++;
|
||||
|
||||
vline_pos += dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
|
||||
if (vline_pos >= 0)
|
||||
*start_line = vline_pos - ((vline_pos / timing->v_total) * timing->v_total);
|
||||
else
|
||||
*start_line = vline_pos + ((-vline_pos / timing->v_total) + 1) * timing->v_total - 1;
|
||||
*end_line = (*start_line + 2) % timing->v_total;
|
||||
} else if (pipe_ctx->stream->periodic_interrupt.ref_point == START_V_SYNC) {
|
||||
// vsync is line 0 so start_line is just the requested line offset
|
||||
*start_line = pipe_ctx->stream->periodic_interrupt.lines_offset;
|
||||
*end_line = *start_line + 2;
|
||||
break;
|
||||
default:
|
||||
*start_line = vline_pos;
|
||||
*end_line = (*start_line + 2) % timing->v_total;
|
||||
} else
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dcn10_setup_periodic_interrupt(
|
||||
|
|
|
@ -207,10 +207,7 @@ void optc1_program_timing(
|
|||
/* In case of V_TOTAL_CONTROL is on, make sure OTG_V_TOTAL_MAX and
|
||||
* OTG_V_TOTAL_MIN are equal to V_TOTAL.
|
||||
*/
|
||||
REG_SET(OTG_V_TOTAL_MAX, 0,
|
||||
OTG_V_TOTAL_MAX, v_total);
|
||||
REG_SET(OTG_V_TOTAL_MIN, 0,
|
||||
OTG_V_TOTAL_MIN, v_total);
|
||||
optc->funcs->set_vtotal_min_max(optc, v_total, v_total);
|
||||
|
||||
/* v_sync_start = 0, v_sync_end = v_sync_width */
|
||||
v_sync_end = patched_crtc_timing.v_sync_width;
|
||||
|
@ -649,13 +646,6 @@ uint32_t optc1_get_vblank_counter(struct timing_generator *optc)
|
|||
void optc1_lock(struct timing_generator *optc)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
uint32_t regval = 0;
|
||||
|
||||
regval = REG_READ(OTG_CONTROL);
|
||||
|
||||
/* otg is not running, do not need to be locked */
|
||||
if ((regval & 0x1) == 0x0)
|
||||
return;
|
||||
|
||||
REG_SET(OTG_GLOBAL_CONTROL0, 0,
|
||||
OTG_MASTER_UPDATE_LOCK_SEL, optc->inst);
|
||||
|
@ -663,12 +653,10 @@ void optc1_lock(struct timing_generator *optc)
|
|||
OTG_MASTER_UPDATE_LOCK, 1);
|
||||
|
||||
/* Should be fast, status does not update on maximus */
|
||||
if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS) {
|
||||
|
||||
if (optc->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
|
||||
REG_WAIT(OTG_MASTER_UPDATE_LOCK,
|
||||
UPDATE_LOCK_STATUS, 1,
|
||||
1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
void optc1_unlock(struct timing_generator *optc)
|
||||
|
@ -679,16 +667,6 @@ void optc1_unlock(struct timing_generator *optc)
|
|||
OTG_MASTER_UPDATE_LOCK, 0);
|
||||
}
|
||||
|
||||
bool optc1_is_locked(struct timing_generator *optc)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
uint32_t locked;
|
||||
|
||||
REG_GET(OTG_MASTER_UPDATE_LOCK, UPDATE_LOCK_STATUS, &locked);
|
||||
|
||||
return (locked == 1);
|
||||
}
|
||||
|
||||
void optc1_get_position(struct timing_generator *optc,
|
||||
struct crtc_position *position)
|
||||
{
|
||||
|
@ -941,11 +919,7 @@ void optc1_set_drr(
|
|||
|
||||
}
|
||||
|
||||
REG_SET(OTG_V_TOTAL_MAX, 0,
|
||||
OTG_V_TOTAL_MAX, params->vertical_total_max - 1);
|
||||
|
||||
REG_SET(OTG_V_TOTAL_MIN, 0,
|
||||
OTG_V_TOTAL_MIN, params->vertical_total_min - 1);
|
||||
optc->funcs->set_vtotal_min_max(optc, params->vertical_total_min - 1, params->vertical_total_max - 1);
|
||||
|
||||
REG_UPDATE_5(OTG_V_TOTAL_CONTROL,
|
||||
OTG_V_TOTAL_MIN_SEL, 1,
|
||||
|
@ -964,11 +938,7 @@ void optc1_set_drr(
|
|||
OTG_V_TOTAL_MAX_SEL, 0,
|
||||
OTG_FORCE_LOCK_ON_EVENT, 0);
|
||||
|
||||
REG_SET(OTG_V_TOTAL_MIN, 0,
|
||||
OTG_V_TOTAL_MIN, 0);
|
||||
|
||||
REG_SET(OTG_V_TOTAL_MAX, 0,
|
||||
OTG_V_TOTAL_MAX, 0);
|
||||
optc->funcs->set_vtotal_min_max(optc, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1583,11 +1553,11 @@ static const struct timing_generator_funcs dcn10_tg_funcs = {
|
|||
.enable_crtc_reset = optc1_enable_crtc_reset,
|
||||
.disable_reset_trigger = optc1_disable_reset_trigger,
|
||||
.lock = optc1_lock,
|
||||
.is_locked = optc1_is_locked,
|
||||
.unlock = optc1_unlock,
|
||||
.enable_optc_clock = optc1_enable_optc_clock,
|
||||
.set_drr = optc1_set_drr,
|
||||
.get_last_used_drr_vtotal = NULL,
|
||||
.set_vtotal_min_max = optc1_set_vtotal_min_max,
|
||||
.set_static_screen_control = optc1_set_static_screen_control,
|
||||
.set_test_pattern = optc1_set_test_pattern,
|
||||
.program_stereo = optc1_program_stereo,
|
||||
|
|
|
@ -654,7 +654,6 @@ void optc1_set_blank(struct timing_generator *optc,
|
|||
bool enable_blanking);
|
||||
|
||||
bool optc1_is_blanked(struct timing_generator *optc);
|
||||
bool optc1_is_locked(struct timing_generator *optc);
|
||||
|
||||
void optc1_program_blank_color(
|
||||
struct timing_generator *optc,
|
||||
|
|
|
@ -1336,6 +1336,21 @@ static noinline void dcn10_resource_construct_fp(
|
|||
}
|
||||
}
|
||||
|
||||
static bool verify_clock_values(struct dm_pp_clock_levels_with_voltage *clks)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (clks->num_levels == 0)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < clks->num_levels; i++)
|
||||
/* Ensure that the result is sane */
|
||||
if (clks->data[i].clocks_in_khz == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dcn10_resource_construct(
|
||||
uint8_t num_virtual_links,
|
||||
struct dc *dc,
|
||||
|
@ -1345,6 +1360,9 @@ static bool dcn10_resource_construct(
|
|||
int j;
|
||||
struct dc_context *ctx = dc->ctx;
|
||||
uint32_t pipe_fuses = read_pipe_fuses(ctx);
|
||||
struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};
|
||||
int min_fclk_khz, min_dcfclk_khz, socclk_khz;
|
||||
bool res;
|
||||
|
||||
ctx->dc_bios->regs = &bios_regs;
|
||||
|
||||
|
@ -1523,15 +1541,53 @@ static bool dcn10_resource_construct(
|
|||
&& pool->base.pp_smu->rv_funcs.set_pme_wa_enable != NULL)
|
||||
dc->debug.az_endpoint_mute_only = false;
|
||||
|
||||
DC_FP_START();
|
||||
if (!dc->debug.disable_pplib_clock_request)
|
||||
dcn_bw_update_from_pplib(dc);
|
||||
|
||||
if (!dc->debug.disable_pplib_clock_request) {
|
||||
/*
|
||||
* TODO: This is not the proper way to obtain
|
||||
* fabric_and_dram_bandwidth, should be min(fclk, memclk).
|
||||
*/
|
||||
res = dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks);
|
||||
|
||||
DC_FP_START();
|
||||
|
||||
if (res)
|
||||
res = verify_clock_values(&fclks);
|
||||
|
||||
if (res)
|
||||
dcn_bw_update_from_pplib_fclks(dc, &fclks);
|
||||
else
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
||||
DC_FP_END();
|
||||
|
||||
res = dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks);
|
||||
|
||||
DC_FP_START();
|
||||
|
||||
if (res)
|
||||
res = verify_clock_values(&dcfclks);
|
||||
|
||||
if (res)
|
||||
dcn_bw_update_from_pplib_dcfclks(dc, &dcfclks);
|
||||
else
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
||||
DC_FP_END();
|
||||
}
|
||||
|
||||
dcn_bw_sync_calcs_and_dml(dc);
|
||||
if (!dc->debug.disable_pplib_wm_range) {
|
||||
dc->res_pool = &pool->base;
|
||||
dcn_bw_notify_pplib_of_wm_ranges(dc);
|
||||
DC_FP_START();
|
||||
dcn_get_soc_clks(
|
||||
dc, &min_fclk_khz, &min_dcfclk_khz, &socclk_khz);
|
||||
DC_FP_END();
|
||||
dcn_bw_notify_pplib_of_wm_ranges(
|
||||
dc, min_fclk_khz, min_dcfclk_khz, socclk_khz);
|
||||
}
|
||||
DC_FP_END();
|
||||
|
||||
{
|
||||
struct irq_service_init_data init_data;
|
||||
|
|
|
@ -617,6 +617,17 @@ void hubp2_cursor_set_attributes(
|
|||
CURSOR0_DST_Y_OFFSET, 0,
|
||||
/* used to shift the cursor chunk request deadline */
|
||||
CURSOR0_CHUNK_HDL_ADJUST, 3);
|
||||
|
||||
hubp->att.SURFACE_ADDR_HIGH = attr->address.high_part;
|
||||
hubp->att.SURFACE_ADDR = attr->address.low_part;
|
||||
hubp->att.size.bits.width = attr->width;
|
||||
hubp->att.size.bits.height = attr->height;
|
||||
hubp->att.cur_ctl.bits.mode = attr->color_format;
|
||||
hubp->att.cur_ctl.bits.pitch = hw_pitch;
|
||||
hubp->att.cur_ctl.bits.line_per_chunk = lpc;
|
||||
hubp->att.cur_ctl.bits.cur_2x_magnify = attr->attribute_flags.bits.ENABLE_MAGNIFICATION;
|
||||
hubp->att.settings.bits.dst_y_offset = 0;
|
||||
hubp->att.settings.bits.chunk_hdl_adjust = 3;
|
||||
}
|
||||
|
||||
void hubp2_dmdata_set_attributes(
|
||||
|
@ -1033,6 +1044,25 @@ void hubp2_cursor_set_position(
|
|||
REG_SET(CURSOR_DST_OFFSET, 0,
|
||||
CURSOR_DST_X_OFFSET, dst_x_offset);
|
||||
/* TODO Handle surface pixel formats other than 4:4:4 */
|
||||
/* Cursor Position Register Config */
|
||||
hubp->pos.cur_ctl.bits.cur_enable = cur_en;
|
||||
hubp->pos.position.bits.x_pos = pos->x;
|
||||
hubp->pos.position.bits.y_pos = pos->y;
|
||||
hubp->pos.hot_spot.bits.x_hot = x_hotspot;
|
||||
hubp->pos.hot_spot.bits.y_hot = y_hotspot;
|
||||
hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset;
|
||||
/* Cursor Rectangle Cache
|
||||
* Cursor bitmaps have different hotspot values
|
||||
* There's a possibility that the above logic returns a negative value,
|
||||
* so we clamp them to 0
|
||||
*/
|
||||
if (src_x_offset < 0)
|
||||
src_x_offset = 0;
|
||||
if (src_y_offset < 0)
|
||||
src_y_offset = 0;
|
||||
/* Save necessary cursor info x, y position. w, h is saved in attribute func. */
|
||||
hubp->cur_rect.x = src_x_offset + param->viewport.x;
|
||||
hubp->cur_rect.y = src_y_offset + param->viewport.y;
|
||||
}
|
||||
|
||||
void hubp2_clk_cntl(struct hubp *hubp, bool enable)
|
||||
|
|
|
@ -1860,24 +1860,6 @@ void dcn20_post_unlock_program_front_end(
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *mpcc_pipe;
|
||||
|
||||
if (pipe->vtp_locked) {
|
||||
dc->hwseq->funcs.wait_for_blank_complete(pipe->stream_res.opp);
|
||||
pipe->plane_res.hubp->funcs->set_blank(pipe->plane_res.hubp, true);
|
||||
pipe->vtp_locked = false;
|
||||
|
||||
for (mpcc_pipe = pipe->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe)
|
||||
mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, true);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable)
|
||||
dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
@ -2018,6 +2000,10 @@ void dcn20_optimize_bandwidth(
|
|||
context->bw_ctx.bw.dcn.clk.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
|
||||
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
|
||||
|
||||
/* increase compbuf size */
|
||||
if (hubbub->funcs->program_compbuf_size)
|
||||
hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
|
||||
|
||||
dc->clk_mgr->funcs->update_clocks(
|
||||
dc->clk_mgr,
|
||||
context,
|
||||
|
@ -2033,9 +2019,6 @@ void dcn20_optimize_bandwidth(
|
|||
pipe_ctx->dlg_regs.optimized_min_dst_y_next_start);
|
||||
}
|
||||
}
|
||||
/* increase compbuf size */
|
||||
if (hubbub->funcs->program_compbuf_size)
|
||||
hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
|
||||
}
|
||||
|
||||
bool dcn20_update_bandwidth(
|
||||
|
|
|
@ -529,6 +529,7 @@ static struct timing_generator_funcs dcn20_tg_funcs = {
|
|||
.enable_optc_clock = optc1_enable_optc_clock,
|
||||
.set_drr = optc1_set_drr,
|
||||
.get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal,
|
||||
.set_vtotal_min_max = optc1_set_vtotal_min_max,
|
||||
.set_static_screen_control = optc1_set_static_screen_control,
|
||||
.program_stereo = optc1_program_stereo,
|
||||
.is_stereo_left_eye = optc1_is_stereo_left_eye,
|
||||
|
|
|
@ -67,15 +67,9 @@ static uint32_t convert_and_clamp(
|
|||
void dcn21_dchvm_init(struct hubbub *hubbub)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t riommu_active, prefetch_done;
|
||||
uint32_t riommu_active;
|
||||
int i;
|
||||
|
||||
REG_GET(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, &prefetch_done);
|
||||
|
||||
if (prefetch_done) {
|
||||
hubbub->riommu_active = true;
|
||||
return;
|
||||
}
|
||||
//Init DCHVM block
|
||||
REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1);
|
||||
|
||||
|
|
|
@ -657,7 +657,6 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.usbc_combo_phy_reset_wa = true,
|
||||
.dmub_command_table = true,
|
||||
.use_max_lb = true,
|
||||
.optimize_edp_link_rate = true
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_diags = {
|
||||
|
@ -677,6 +676,12 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.ilr = {
|
||||
.optimize_edp_link_rate = true,
|
||||
},
|
||||
};
|
||||
|
||||
enum dcn20_clk_src_array_id {
|
||||
DCN20_CLK_SRC_PLL0,
|
||||
DCN20_CLK_SRC_PLL1,
|
||||
|
@ -1367,6 +1372,11 @@ static struct panel_cntl *dcn21_panel_cntl_create(const struct panel_cntl_init_d
|
|||
return &panel_cntl->base;
|
||||
}
|
||||
|
||||
static void dcn21_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
#define CTX ctx
|
||||
|
||||
#define REG(reg_name) \
|
||||
|
@ -1408,6 +1418,7 @@ static const struct resource_funcs dcn21_res_pool_funcs = {
|
|||
.set_mcif_arb_params = dcn20_set_mcif_arb_params,
|
||||
.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
|
||||
.update_bw_bounding_box = dcn21_update_bw_bounding_box,
|
||||
.get_panel_config_defaults = dcn21_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
static bool dcn21_resource_construct(
|
||||
|
|
|
@ -372,6 +372,10 @@ void dpp3_set_cursor_attributes(
|
|||
REG_UPDATE(CURSOR0_COLOR1,
|
||||
CUR0_COLOR1, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
dpp_base->att.cur0_ctl.bits.expansion_mode = 0;
|
||||
dpp_base->att.cur0_ctl.bits.cur0_rom_en = cur_rom_en;
|
||||
dpp_base->att.cur0_ctl.bits.mode = color_format;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -319,13 +319,13 @@ static struct timing_generator_funcs dcn30_tg_funcs = {
|
|||
.enable_crtc_reset = optc1_enable_crtc_reset,
|
||||
.disable_reset_trigger = optc1_disable_reset_trigger,
|
||||
.lock = optc3_lock,
|
||||
.is_locked = optc1_is_locked,
|
||||
.unlock = optc1_unlock,
|
||||
.lock_doublebuffer_enable = optc3_lock_doublebuffer_enable,
|
||||
.lock_doublebuffer_disable = optc3_lock_doublebuffer_disable,
|
||||
.enable_optc_clock = optc1_enable_optc_clock,
|
||||
.set_drr = optc1_set_drr,
|
||||
.get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal,
|
||||
.set_vtotal_min_max = optc3_set_vtotal_min_max,
|
||||
.set_static_screen_control = optc1_set_static_screen_control,
|
||||
.program_stereo = optc1_program_stereo,
|
||||
.is_stereo_left_eye = optc1_is_stereo_left_eye,
|
||||
|
@ -366,4 +366,3 @@ void dcn30_timing_generator_init(struct optc *optc1)
|
|||
optc1->min_h_sync_width = 4;
|
||||
optc1->min_v_sync_width = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1655,6 +1655,9 @@ noinline bool dcn30_internal_validate_bw(
|
|||
if (!pipes)
|
||||
return false;
|
||||
|
||||
context->bw_ctx.dml.vba.maxMpcComb = 0;
|
||||
context->bw_ctx.dml.vba.VoltageLevel = 0;
|
||||
context->bw_ctx.dml.vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
|
||||
dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
|
||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
|
||||
|
||||
|
@ -1873,6 +1876,7 @@ noinline bool dcn30_internal_validate_bw(
|
|||
|
||||
if (repopulate_pipes)
|
||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
|
||||
context->bw_ctx.dml.vba.VoltageLevel = vlevel;
|
||||
*vlevel_out = vlevel;
|
||||
*pipe_cnt_out = pipe_cnt;
|
||||
|
||||
|
|
|
@ -852,7 +852,7 @@ static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx)
|
|||
vmid->masks = &vmid_masks;
|
||||
}
|
||||
|
||||
hubbub3->num_vmid = res_cap_dcn301.num_vmid;
|
||||
hubbub3->num_vmid = res_cap_dcn301.num_vmid;
|
||||
|
||||
return &hubbub3->base;
|
||||
}
|
||||
|
|
|
@ -197,7 +197,7 @@ static void dcn31_hpo_dp_stream_enc_set_stream_attribute(
|
|||
uint32_t h_back_porch;
|
||||
uint32_t h_width;
|
||||
uint32_t v_height;
|
||||
unsigned long long v_freq;
|
||||
uint64_t v_freq;
|
||||
uint8_t misc0 = 0;
|
||||
uint8_t misc1 = 0;
|
||||
uint8_t hsp;
|
||||
|
@ -360,7 +360,7 @@ static void dcn31_hpo_dp_stream_enc_set_stream_attribute(
|
|||
v_height = hw_crtc_timing.v_border_top + hw_crtc_timing.v_addressable + hw_crtc_timing.v_border_bottom;
|
||||
hsp = hw_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ? 0 : 0x80;
|
||||
vsp = hw_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ? 0 : 0x80;
|
||||
v_freq = hw_crtc_timing.pix_clk_100hz * 100;
|
||||
v_freq = (uint64_t)hw_crtc_timing.pix_clk_100hz * 100;
|
||||
|
||||
/* MSA Packet Mapping to 32-bit Link Symbols - DP2 spec, section 2.7.4.1
|
||||
*
|
||||
|
@ -436,32 +436,28 @@ static void dcn31_hpo_dp_stream_enc_update_dp_info_packets(
|
|||
{
|
||||
struct dcn31_hpo_dp_stream_encoder *enc3 = DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(enc);
|
||||
uint32_t dmdata_packet_enabled = 0;
|
||||
bool sdp_stream_enable = false;
|
||||
|
||||
if (info_frame->vsc.valid) {
|
||||
if (info_frame->vsc.valid)
|
||||
enc->vpg->funcs->update_generic_info_packet(
|
||||
enc->vpg,
|
||||
0, /* packetIndex */
|
||||
&info_frame->vsc,
|
||||
true);
|
||||
sdp_stream_enable = true;
|
||||
}
|
||||
if (info_frame->spd.valid) {
|
||||
|
||||
if (info_frame->spd.valid)
|
||||
enc->vpg->funcs->update_generic_info_packet(
|
||||
enc->vpg,
|
||||
2, /* packetIndex */
|
||||
&info_frame->spd,
|
||||
true);
|
||||
sdp_stream_enable = true;
|
||||
}
|
||||
if (info_frame->hdrsmd.valid) {
|
||||
|
||||
if (info_frame->hdrsmd.valid)
|
||||
enc->vpg->funcs->update_generic_info_packet(
|
||||
enc->vpg,
|
||||
3, /* packetIndex */
|
||||
&info_frame->hdrsmd,
|
||||
true);
|
||||
sdp_stream_enable = true;
|
||||
}
|
||||
|
||||
/* enable/disable transmission of packet(s).
|
||||
* If enabled, packet transmission begins on the next frame
|
||||
*/
|
||||
|
|
|
@ -201,7 +201,6 @@ void optc31_set_drr(
|
|||
|
||||
// Setup manual flow control for EOF via TRIG_A
|
||||
optc->funcs->setup_manual_trigger(optc);
|
||||
|
||||
} else {
|
||||
REG_UPDATE_4(OTG_V_TOTAL_CONTROL,
|
||||
OTG_SET_V_TOTAL_MIN_MASK, 0,
|
||||
|
@ -260,7 +259,6 @@ static struct timing_generator_funcs dcn31_tg_funcs = {
|
|||
.enable_crtc_reset = optc1_enable_crtc_reset,
|
||||
.disable_reset_trigger = optc1_disable_reset_trigger,
|
||||
.lock = optc3_lock,
|
||||
.is_locked = optc1_is_locked,
|
||||
.unlock = optc1_unlock,
|
||||
.lock_doublebuffer_enable = optc3_lock_doublebuffer_enable,
|
||||
.lock_doublebuffer_disable = optc3_lock_doublebuffer_disable,
|
||||
|
|
|
@ -888,9 +888,8 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
}
|
||||
},
|
||||
.disable_z10 = true,
|
||||
.optimize_edp_link_rate = true,
|
||||
.enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/
|
||||
.dml_hostvm_override = DML_HOSTVM_NO_OVERRIDE,
|
||||
.dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE,
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_diags = {
|
||||
|
@ -911,6 +910,12 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.ilr = {
|
||||
.optimize_edp_link_rate = true,
|
||||
},
|
||||
};
|
||||
|
||||
static void dcn31_dpp_destroy(struct dpp **dpp)
|
||||
{
|
||||
kfree(TO_DCN20_DPP(*dpp));
|
||||
|
@ -1803,6 +1808,11 @@ validate_out:
|
|||
return out;
|
||||
}
|
||||
|
||||
static void dcn31_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
static struct dc_cap_funcs cap_funcs = {
|
||||
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
|
||||
};
|
||||
|
@ -1829,6 +1839,7 @@ static struct resource_funcs dcn31_res_pool_funcs = {
|
|||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn31_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
|
||||
.get_panel_config_defaults = dcn31_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
static struct clock_source *dcn30_clock_source_create(
|
||||
|
|
|
@ -262,7 +262,7 @@ static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
|
|||
return two_pix;
|
||||
}
|
||||
|
||||
void enc314_stream_encoder_dp_blank(
|
||||
static void enc314_stream_encoder_dp_blank(
|
||||
struct dc_link *link,
|
||||
struct stream_encoder *enc)
|
||||
{
|
||||
|
|
|
@ -881,7 +881,8 @@ static const struct dc_plane_cap plane_cap = {
|
|||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_drv = {
|
||||
.disable_z10 = true, /*hw not support it*/
|
||||
.disable_z10 = false,
|
||||
.enable_z9_disable_interface = true,
|
||||
.disable_dmcu = true,
|
||||
.force_abm_enable = false,
|
||||
.timing_trace = false,
|
||||
|
@ -914,7 +915,6 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.afmt = true,
|
||||
}
|
||||
},
|
||||
.optimize_edp_link_rate = true,
|
||||
.seamless_boot_odm_combine = true
|
||||
};
|
||||
|
||||
|
@ -936,6 +936,12 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.ilr = {
|
||||
.optimize_edp_link_rate = true,
|
||||
},
|
||||
};
|
||||
|
||||
static void dcn31_dpp_destroy(struct dpp **dpp)
|
||||
{
|
||||
kfree(TO_DCN20_DPP(*dpp));
|
||||
|
@ -1675,6 +1681,11 @@ static void dcn314_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *b
|
|||
DC_FP_END();
|
||||
}
|
||||
|
||||
static void dcn314_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
static struct resource_funcs dcn314_res_pool_funcs = {
|
||||
.destroy = dcn314_destroy_resource_pool,
|
||||
.link_enc_create = dcn31_link_encoder_create,
|
||||
|
@ -1697,6 +1708,7 @@ static struct resource_funcs dcn314_res_pool_funcs = {
|
|||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn314_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
|
||||
.get_panel_config_defaults = dcn314_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
static struct clock_source *dcn30_clock_source_create(
|
||||
|
|
|
@ -885,7 +885,6 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.afmt = true,
|
||||
}
|
||||
},
|
||||
.optimize_edp_link_rate = true,
|
||||
.psr_power_use_phy_fsm = 0,
|
||||
};
|
||||
|
||||
|
@ -907,6 +906,12 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.ilr = {
|
||||
.optimize_edp_link_rate = true,
|
||||
},
|
||||
};
|
||||
|
||||
static void dcn31_dpp_destroy(struct dpp **dpp)
|
||||
{
|
||||
kfree(TO_DCN20_DPP(*dpp));
|
||||
|
@ -1708,6 +1713,11 @@ static int dcn315_populate_dml_pipes_from_context(
|
|||
return pipe_cnt;
|
||||
}
|
||||
|
||||
static void dcn315_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
static struct dc_cap_funcs cap_funcs = {
|
||||
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
|
||||
};
|
||||
|
@ -1721,7 +1731,7 @@ static struct resource_funcs dcn315_res_pool_funcs = {
|
|||
.panel_cntl_create = dcn31_panel_cntl_create,
|
||||
.validate_bandwidth = dcn31_validate_bandwidth,
|
||||
.calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
|
||||
.update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
|
||||
.update_soc_for_wm_a = dcn315_update_soc_for_wm_a,
|
||||
.populate_dml_pipes = dcn315_populate_dml_pipes_from_context,
|
||||
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
|
||||
.add_stream_to_ctx = dcn30_add_stream_to_ctx,
|
||||
|
@ -1734,6 +1744,7 @@ static struct resource_funcs dcn315_res_pool_funcs = {
|
|||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn315_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
|
||||
.get_panel_config_defaults = dcn315_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
static bool dcn315_resource_construct(
|
||||
|
|
|
@ -885,7 +885,6 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.afmt = true,
|
||||
}
|
||||
},
|
||||
.optimize_edp_link_rate = true,
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_diags = {
|
||||
|
@ -906,6 +905,12 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.ilr = {
|
||||
.optimize_edp_link_rate = true,
|
||||
},
|
||||
};
|
||||
|
||||
static void dcn31_dpp_destroy(struct dpp **dpp)
|
||||
{
|
||||
kfree(TO_DCN20_DPP(*dpp));
|
||||
|
@ -1710,6 +1715,11 @@ static int dcn316_populate_dml_pipes_from_context(
|
|||
return pipe_cnt;
|
||||
}
|
||||
|
||||
static void dcn316_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
static struct dc_cap_funcs cap_funcs = {
|
||||
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
|
||||
};
|
||||
|
@ -1736,6 +1746,7 @@ static struct resource_funcs dcn316_res_pool_funcs = {
|
|||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn316_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
|
||||
.get_panel_config_defaults = dcn316_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
static bool dcn316_resource_construct(
|
||||
|
|
|
@ -150,12 +150,6 @@ static void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
|||
|
||||
}
|
||||
|
||||
void enc32_set_dig_output_mode(struct link_encoder *enc, uint8_t pix_per_container)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_OUTPUT_PIXEL_MODE, pix_per_container);
|
||||
}
|
||||
|
||||
static const struct link_encoder_funcs dcn32_link_enc_funcs = {
|
||||
.read_state = link_enc2_read_state,
|
||||
.validate_output_with_stream =
|
||||
|
@ -186,7 +180,6 @@ static const struct link_encoder_funcs dcn32_link_enc_funcs = {
|
|||
.is_in_alt_mode = dcn32_link_encoder_is_in_alt_mode,
|
||||
.get_max_link_cap = dcn32_link_encoder_get_max_link_cap,
|
||||
.set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
|
||||
.set_dig_output_mode = enc32_set_dig_output_mode,
|
||||
};
|
||||
|
||||
void dcn32_link_encoder_construct(
|
||||
|
|
|
@ -53,8 +53,4 @@ void dcn32_link_encoder_enable_dp_output(
|
|||
const struct dc_link_settings *link_settings,
|
||||
enum clock_source_id clock_source);
|
||||
|
||||
void enc32_set_dig_output_mode(
|
||||
struct link_encoder *enc,
|
||||
uint8_t pix_per_container);
|
||||
|
||||
#endif /* __DC_LINK_ENCODER__DCN32_H__ */
|
||||
|
|
|
@ -243,6 +243,39 @@ static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
|
|||
return two_pix;
|
||||
}
|
||||
|
||||
static bool is_h_timing_divisible_by_2(const struct dc_crtc_timing *timing)
|
||||
{
|
||||
/* math borrowed from function of same name in inc/resource
|
||||
* checks if h_timing is divisible by 2
|
||||
*/
|
||||
|
||||
bool divisible = false;
|
||||
uint16_t h_blank_start = 0;
|
||||
uint16_t h_blank_end = 0;
|
||||
|
||||
if (timing) {
|
||||
h_blank_start = timing->h_total - timing->h_front_porch;
|
||||
h_blank_end = h_blank_start - timing->h_addressable;
|
||||
|
||||
/* HTOTAL, Hblank start/end, and Hsync start/end all must be
|
||||
* divisible by 2 in order for the horizontal timing params
|
||||
* to be considered divisible by 2. Hsync start is always 0.
|
||||
*/
|
||||
divisible = (timing->h_total % 2 == 0) &&
|
||||
(h_blank_start % 2 == 0) &&
|
||||
(h_blank_end % 2 == 0) &&
|
||||
(timing->h_sync_width % 2 == 0);
|
||||
}
|
||||
return divisible;
|
||||
}
|
||||
|
||||
static bool is_dp_dig_pixel_rate_div_policy(struct dc *dc, const struct dc_crtc_timing *timing)
|
||||
{
|
||||
/* should be functionally the same as dcn32_is_dp_dig_pixel_rate_div_policy for DP encoders*/
|
||||
return is_h_timing_divisible_by_2(timing) &&
|
||||
dc->debug.enable_dp_dig_pixel_rate_div_policy;
|
||||
}
|
||||
|
||||
static void enc32_stream_encoder_dp_unblank(
|
||||
struct dc_link *link,
|
||||
struct stream_encoder *enc,
|
||||
|
@ -259,7 +292,7 @@ static void enc32_stream_encoder_dp_unblank(
|
|||
|
||||
/* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */
|
||||
if (is_two_pixels_per_containter(¶m->timing) || param->opp_cnt > 1
|
||||
|| dc->debug.enable_dp_dig_pixel_rate_div_policy) {
|
||||
|| is_dp_dig_pixel_rate_div_policy(dc, ¶m->timing)) {
|
||||
/*this logic should be the same in get_pixel_clock_parameters() */
|
||||
n_multiply = 1;
|
||||
}
|
||||
|
@ -355,7 +388,7 @@ static void enc32_dp_set_dsc_config(struct stream_encoder *enc,
|
|||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
REG_UPDATE(DP_DSC_CNTL, DP_DSC_MODE, dsc_mode);
|
||||
REG_UPDATE(DP_DSC_CNTL, DP_DSC_MODE, dsc_mode == OPTC_DSC_DISABLED ? 0 : 1);
|
||||
}
|
||||
|
||||
/* this function read dsc related register fields to be logged later in dcn10_log_hw_state
|
||||
|
@ -378,24 +411,6 @@ static void enc32_read_state(struct stream_encoder *enc, struct enc_state *s)
|
|||
}
|
||||
}
|
||||
|
||||
static void enc32_stream_encoder_reset_fifo(struct stream_encoder *enc)
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
uint32_t fifo_enabled;
|
||||
|
||||
REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &fifo_enabled);
|
||||
|
||||
if (fifo_enabled == 0) {
|
||||
/* reset DIG resync FIFO */
|
||||
REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
|
||||
/* TODO: fix timeout when wait for DIG_FIFO_RESET_DONE */
|
||||
//REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 1, 100);
|
||||
udelay(1);
|
||||
REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
|
||||
REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 1, 100);
|
||||
}
|
||||
}
|
||||
|
||||
static void enc32_set_dig_input_mode(struct stream_encoder *enc, unsigned int pix_per_container)
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
@ -425,8 +440,6 @@ static const struct stream_encoder_funcs dcn32_str_enc_funcs = {
|
|||
enc3_stream_encoder_update_dp_info_packets,
|
||||
.stop_dp_info_packets =
|
||||
enc1_stream_encoder_stop_dp_info_packets,
|
||||
.reset_fifo =
|
||||
enc32_stream_encoder_reset_fifo,
|
||||
.dp_blank =
|
||||
enc1_stream_encoder_dp_blank,
|
||||
.dp_unblank =
|
||||
|
|
|
@ -71,7 +71,9 @@
|
|||
SRI(DP_MSE_RATE_UPDATE, DP, id), \
|
||||
SRI(DP_PIXEL_FORMAT, DP, id), \
|
||||
SRI(DP_SEC_CNTL, DP, id), \
|
||||
SRI(DP_SEC_CNTL1, DP, id), \
|
||||
SRI(DP_SEC_CNTL2, DP, id), \
|
||||
SRI(DP_SEC_CNTL5, DP, id), \
|
||||
SRI(DP_SEC_CNTL6, DP, id), \
|
||||
SRI(DP_STEER_FIFO, DP, id), \
|
||||
SRI(DP_VID_M, DP, id), \
|
||||
|
@ -93,7 +95,7 @@
|
|||
SRI(DIG_FIFO_CTRL0, DIG, id)
|
||||
|
||||
|
||||
#define SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh)\
|
||||
#define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
|
||||
SE_SF(DP0_DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, mask_sh),\
|
||||
SE_SF(DP0_DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, mask_sh),\
|
||||
SE_SF(DP0_DP_PIXEL_FORMAT, DP_PIXEL_PER_CYCLE_PROCESSING_MODE, mask_sh),\
|
||||
|
@ -106,6 +108,7 @@
|
|||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE, mask_sh),\
|
||||
SE_SF(DIG0_HDMI_GC, HDMI_GC_AVMUTE, mask_sh),\
|
||||
|
@ -244,15 +247,6 @@
|
|||
SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, mask_sh),\
|
||||
SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_OUTPUT_PIXEL_MODE, mask_sh)
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||
#define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
|
||||
SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh),\
|
||||
SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, mask_sh)
|
||||
#else
|
||||
#define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
|
||||
SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh)
|
||||
#endif
|
||||
|
||||
void dcn32_dio_stream_encoder_construct(
|
||||
struct dcn10_stream_encoder *enc1,
|
||||
struct dc_context *ctx,
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_PRBS_SEL1, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_PRBS_SEL2, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG, TP_PRBS_SEL3, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_TP_SQ_PULSE, TP_SQ_PULSE_WIDTH, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC0, SAT_STREAM_SOURCE, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC0, SAT_SLOT_COUNT, mask_sh),\
|
||||
SE_SF(DP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL0, STREAM_VC_RATE_X, mask_sh),\
|
||||
|
|
|
@ -936,6 +936,7 @@ static const struct hubbub_funcs hubbub32_funcs = {
|
|||
.program_watermarks = hubbub32_program_watermarks,
|
||||
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
|
||||
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
|
||||
.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
|
||||
.force_wm_propagate_to_pipes = hubbub32_force_wm_propagate_to_pipes,
|
||||
.force_pstate_change_control = hubbub3_force_pstate_change_control,
|
||||
.init_watermarks = hubbub32_init_watermarks,
|
||||
|
|
|
@ -79,6 +79,8 @@ void hubp32_phantom_hubp_post_enable(struct hubp *hubp)
|
|||
uint32_t reg_val;
|
||||
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
|
||||
|
||||
/* For phantom pipe enable, disable GSL */
|
||||
REG_UPDATE(DCSURF_FLIP_CONTROL2, SURFACE_GSL_ENABLE, 0);
|
||||
REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, 1);
|
||||
reg_val = REG_READ(DCHUBP_CNTL);
|
||||
if (reg_val) {
|
||||
|
@ -179,12 +181,12 @@ static struct hubp_funcs dcn32_hubp_funcs = {
|
|||
.hubp_init = hubp3_init,
|
||||
.set_unbounded_requesting = hubp31_set_unbounded_requesting,
|
||||
.hubp_soft_reset = hubp31_soft_reset,
|
||||
.hubp_set_flip_int = hubp1_set_flip_int,
|
||||
.hubp_in_blank = hubp1_in_blank,
|
||||
.hubp_update_force_pstate_disallow = hubp32_update_force_pstate_disallow,
|
||||
.phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable,
|
||||
.hubp_update_mall_sel = hubp32_update_mall_sel,
|
||||
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
|
||||
.hubp_set_flip_int = hubp1_set_flip_int
|
||||
.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering
|
||||
};
|
||||
|
||||
bool hubp32_construct(
|
||||
|
|
|
@ -206,8 +206,7 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
|
|||
*/
|
||||
static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
|
||||
{
|
||||
uint8_t i;
|
||||
int j;
|
||||
int i, j;
|
||||
struct dc_stream_state *stream = NULL;
|
||||
struct dc_plane_state *plane = NULL;
|
||||
uint32_t cursor_size = 0;
|
||||
|
@ -630,10 +629,9 @@ bool dcn32_set_input_transfer_func(struct dc *dc,
|
|||
params = &dpp_base->degamma_params;
|
||||
}
|
||||
|
||||
result = dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
|
||||
dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
|
||||
|
||||
if (result &&
|
||||
pipe_ctx->stream_res.opp &&
|
||||
if (pipe_ctx->stream_res.opp &&
|
||||
pipe_ctx->stream_res.opp->ctx &&
|
||||
hws->funcs.set_mcm_luts)
|
||||
result = hws->funcs.set_mcm_luts(pipe_ctx, plane_state);
|
||||
|
@ -991,6 +989,10 @@ void dcn32_init_hw(struct dc *dc)
|
|||
dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
|
||||
dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
|
||||
}
|
||||
|
||||
/* Enable support for ODM and windowed MPO if policy flag is set */
|
||||
if (dc->debug.enable_single_display_2to1_odm_policy)
|
||||
dc->config.enable_windowed_mpo_odm = true;
|
||||
}
|
||||
|
||||
static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
|
||||
|
@ -1145,23 +1147,25 @@ void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *
|
|||
true);
|
||||
}
|
||||
|
||||
// Don't program pixel clock after link is already enabled
|
||||
/* if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
|
||||
pipe_ctx->clock_source,
|
||||
&pipe_ctx->stream_res.pix_clk_params,
|
||||
&pipe_ctx->pll_settings)) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
}*/
|
||||
if (pipe_ctx->stream_res.dsc) {
|
||||
struct pipe_ctx *current_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
|
||||
|
||||
if (pipe_ctx->stream_res.dsc)
|
||||
update_dsc_on_stream(pipe_ctx, pipe_ctx->stream->timing.flags.DSC);
|
||||
|
||||
/* Check if no longer using pipe for ODM, then need to disconnect DSC for that pipe */
|
||||
if (!pipe_ctx->next_odm_pipe && current_pipe_ctx->next_odm_pipe &&
|
||||
current_pipe_ctx->next_odm_pipe->stream_res.dsc) {
|
||||
struct display_stream_compressor *dsc = current_pipe_ctx->next_odm_pipe->stream_res.dsc;
|
||||
/* disconnect DSC block from stream */
|
||||
dsc->funcs->dsc_disconnect(dsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div)
|
||||
{
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
unsigned int odm_combine_factor = 0;
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
bool two_pix_per_container = false;
|
||||
|
||||
// For phantom pipes, use the same programming as the main pipes
|
||||
|
@ -1189,7 +1193,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
|
|||
} else {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
*k2_div = PIXEL_RATE_DIV_BY_4;
|
||||
if ((odm_combine_factor == 2) || dc->debug.enable_dp_dig_pixel_rate_div_policy)
|
||||
if ((odm_combine_factor == 2) || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx))
|
||||
*k2_div = PIXEL_RATE_DIV_BY_2;
|
||||
}
|
||||
}
|
||||
|
@ -1226,7 +1230,6 @@ void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
|
|||
struct dc_link *link = stream->link;
|
||||
struct dce_hwseq *hws = link->dc->hwseq;
|
||||
struct pipe_ctx *odm_pipe;
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
uint32_t pix_per_cycle = 1;
|
||||
|
||||
params.opp_cnt = 1;
|
||||
|
@ -1245,7 +1248,7 @@ void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
|
|||
pipe_ctx->stream_res.tg->inst);
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
|
||||
if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1
|
||||
|| dc->debug.enable_dp_dig_pixel_rate_div_policy) {
|
||||
|| dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx)) {
|
||||
params.timing.pix_clk_100hz /= 2;
|
||||
pix_per_cycle = 2;
|
||||
}
|
||||
|
@ -1262,6 +1265,9 @@ bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx)
|
|||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
|
||||
if (!is_h_timing_divisible_by_2(pipe_ctx->stream))
|
||||
return false;
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal) && !is_dp_128b_132b_signal(pipe_ctx) &&
|
||||
dc->debug.enable_dp_dig_pixel_rate_div_policy)
|
||||
return true;
|
||||
|
@ -1394,7 +1400,7 @@ bool dcn32_dsc_pg_status(
|
|||
break;
|
||||
}
|
||||
|
||||
return pwr_status == 0 ? true : false;
|
||||
return pwr_status == 0;
|
||||
}
|
||||
|
||||
void dcn32_update_dsc_pg(struct dc *dc,
|
||||
|
|
|
@ -151,7 +151,7 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
|
|||
/* CRTC disabled, so disable clock. */
|
||||
REG_WAIT(OTG_CLOCK_CONTROL,
|
||||
OTG_BUSY, 0,
|
||||
1, 100000);
|
||||
1, 150000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1680,6 +1680,8 @@ static void dcn32_enable_phantom_plane(struct dc *dc,
|
|||
phantom_plane->clip_rect.y = 0;
|
||||
phantom_plane->clip_rect.height = phantom_stream->timing.v_addressable;
|
||||
|
||||
phantom_plane->is_phantom = true;
|
||||
|
||||
dc_add_plane_to_context(dc, phantom_stream, phantom_plane, context);
|
||||
|
||||
curr_pipe = curr_pipe->bottom_pipe;
|
||||
|
@ -1749,6 +1751,10 @@ bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
|
|||
pipe->stream->mall_stream_config.type = SUBVP_NONE;
|
||||
pipe->stream->mall_stream_config.paired_stream = NULL;
|
||||
}
|
||||
|
||||
if (pipe->plane_state) {
|
||||
pipe->plane_state->is_phantom = false;
|
||||
}
|
||||
}
|
||||
return removed_pipe;
|
||||
}
|
||||
|
@ -1798,14 +1804,39 @@ bool dcn32_validate_bandwidth(struct dc *dc,
|
|||
int vlevel = 0;
|
||||
int pipe_cnt = 0;
|
||||
display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
|
||||
struct mall_temp_config mall_temp_config;
|
||||
|
||||
/* To handle Freesync properly, setting FreeSync DML parameters
|
||||
* to its default state for the first stage of validation
|
||||
*/
|
||||
context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false;
|
||||
context->bw_ctx.dml.soc.dram_clock_change_requirement_final = true;
|
||||
|
||||
DC_LOGGER_INIT(dc->ctx->logger);
|
||||
|
||||
/* For fast validation, there are situations where a shallow copy of
|
||||
* of the dc->current_state is created for the validation. In this case
|
||||
* we want to save and restore the mall config because we always
|
||||
* teardown subvp at the beginning of validation (and don't attempt
|
||||
* to add it back if it's fast validation). If we don't restore the
|
||||
* subvp config in cases of fast validation + shallow copy of the
|
||||
* dc->current_state, the dc->current_state will have a partially
|
||||
* removed subvp state when we did not intend to remove it.
|
||||
*/
|
||||
if (fast_validate) {
|
||||
memset(&mall_temp_config, 0, sizeof(mall_temp_config));
|
||||
dcn32_save_mall_state(dc, context, &mall_temp_config);
|
||||
}
|
||||
|
||||
BW_VAL_TRACE_COUNT();
|
||||
|
||||
DC_FP_START();
|
||||
out = dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
|
||||
DC_FP_END();
|
||||
|
||||
if (fast_validate)
|
||||
dcn32_restore_mall_state(dc, context, &mall_temp_config);
|
||||
|
||||
if (pipe_cnt == 0)
|
||||
goto validate_out;
|
||||
|
||||
|
|
|
@ -45,6 +45,17 @@
|
|||
extern struct _vcs_dpi_ip_params_st dcn3_2_ip;
|
||||
extern struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc;
|
||||
|
||||
/* Temp struct used to save and restore MALL config
|
||||
* during validation.
|
||||
*
|
||||
* TODO: Move MALL config into dc_state instead of stream struct
|
||||
* to avoid needing to save/restore.
|
||||
*/
|
||||
struct mall_temp_config {
|
||||
struct mall_stream_config mall_stream_config[MAX_PIPES];
|
||||
bool is_phantom_plane[MAX_PIPES];
|
||||
};
|
||||
|
||||
struct dcn32_resource_pool {
|
||||
struct resource_pool base;
|
||||
};
|
||||
|
@ -108,6 +119,8 @@ bool dcn32_subvp_in_use(struct dc *dc,
|
|||
|
||||
bool dcn32_mpo_in_use(struct dc_state *context);
|
||||
|
||||
bool dcn32_any_surfaces_rotated(struct dc *dc, struct dc_state *context);
|
||||
|
||||
struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer(
|
||||
struct dc_state *state,
|
||||
const struct resource_pool *pool,
|
||||
|
@ -120,6 +133,15 @@ void dcn32_determine_det_override(struct dc *dc,
|
|||
|
||||
void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes);
|
||||
|
||||
void dcn32_save_mall_state(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct mall_temp_config *temp_config);
|
||||
|
||||
void dcn32_restore_mall_state(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct mall_temp_config *temp_config);
|
||||
|
||||
/* definitions for run time init of reg offsets */
|
||||
|
||||
/* CLK SRC */
|
||||
|
|
|
@ -233,6 +233,23 @@ bool dcn32_mpo_in_use(struct dc_state *context)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool dcn32_any_surfaces_rotated(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (!pipe->stream)
|
||||
continue;
|
||||
|
||||
if (pipe->plane_state && pipe->plane_state->rotation != ROTATION_ANGLE_0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* *******************************************************************************************
|
||||
* dcn32_determine_det_override: Determine DET allocation for each pipe
|
||||
|
@ -363,3 +380,74 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context,
|
|||
} else
|
||||
dcn32_determine_det_override(dc, context, pipes);
|
||||
}
|
||||
|
||||
/**
|
||||
* *******************************************************************************************
|
||||
* dcn32_save_mall_state: Save MALL (SubVP) state for fast validation cases
|
||||
*
|
||||
* This function saves the MALL (SubVP) case for fast validation cases. For fast validation,
|
||||
* there are situations where a shallow copy of the dc->current_state is created for the
|
||||
* validation. In this case we want to save and restore the mall config because we always
|
||||
* teardown subvp at the beginning of validation (and don't attempt to add it back if it's
|
||||
* fast validation). If we don't restore the subvp config in cases of fast validation +
|
||||
* shallow copy of the dc->current_state, the dc->current_state will have a partially
|
||||
* removed subvp state when we did not intend to remove it.
|
||||
*
|
||||
* NOTE: This function ONLY works if the streams are not moved to a different pipe in the
|
||||
* validation. We don't expect this to happen in fast_validation=1 cases.
|
||||
*
|
||||
* @param [in]: dc: Current DC state
|
||||
* @param [in]: context: New DC state to be programmed
|
||||
* @param [out]: temp_config: struct used to cache the existing MALL state
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* *******************************************************************************************
|
||||
*/
|
||||
void dcn32_save_mall_state(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct mall_temp_config *temp_config)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->stream)
|
||||
temp_config->mall_stream_config[i] = pipe->stream->mall_stream_config;
|
||||
|
||||
if (pipe->plane_state)
|
||||
temp_config->is_phantom_plane[i] = pipe->plane_state->is_phantom;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* *******************************************************************************************
|
||||
* dcn32_restore_mall_state: Restore MALL (SubVP) state for fast validation cases
|
||||
*
|
||||
* Restore the MALL state based on the previously saved state from dcn32_save_mall_state
|
||||
*
|
||||
* @param [in]: dc: Current DC state
|
||||
* @param [in/out]: context: New DC state to be programmed, restore MALL state into here
|
||||
* @param [in]: temp_config: struct that has the cached MALL state
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* *******************************************************************************************
|
||||
*/
|
||||
void dcn32_restore_mall_state(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct mall_temp_config *temp_config)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->stream)
|
||||
pipe->stream->mall_stream_config = temp_config->mall_stream_config[i];
|
||||
|
||||
if (pipe->plane_state)
|
||||
pipe->plane_state->is_phantom = temp_config->is_phantom_plane[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,6 @@ static const struct link_encoder_funcs dcn321_link_enc_funcs = {
|
|||
.is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
|
||||
.get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
|
||||
.set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
|
||||
.set_dig_output_mode = enc32_set_dig_output_mode,
|
||||
};
|
||||
|
||||
void dcn321_link_encoder_construct(
|
||||
|
|
|
@ -94,8 +94,6 @@
|
|||
#include "dcn20/dcn20_vmid.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
#define fixed16_to_double(x) (((double)x) / ((double) (1 << 16)))
|
||||
#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
|
||||
|
||||
enum dcn321_clk_src_array_id {
|
||||
DCN321_CLK_SRC_PLL0,
|
||||
|
@ -1606,7 +1604,7 @@ static struct resource_funcs dcn321_res_pool_funcs = {
|
|||
.validate_bandwidth = dcn32_validate_bandwidth,
|
||||
.calculate_wm_and_dlg = dcn32_calculate_wm_and_dlg,
|
||||
.populate_dml_pipes = dcn32_populate_dml_pipes_from_context,
|
||||
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
|
||||
.acquire_idle_pipe_for_head_pipe_in_layer = dcn32_acquire_idle_pipe_for_head_pipe_in_layer,
|
||||
.add_stream_to_ctx = dcn30_add_stream_to_ctx,
|
||||
.add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
|
||||
.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
|
||||
|
@ -1656,7 +1654,7 @@ static bool dcn321_resource_construct(
|
|||
|
||||
#undef REG_STRUCT
|
||||
#define REG_STRUCT dccg_regs
|
||||
dccg_regs_init();
|
||||
dccg_regs_init();
|
||||
|
||||
|
||||
ctx->dc_bios->regs = &bios_regs;
|
||||
|
|
|
@ -1444,81 +1444,67 @@ unsigned int dcn_find_dcfclk_suits_all(
|
|||
return dcf_clk;
|
||||
}
|
||||
|
||||
static bool verify_clock_values(struct dm_pp_clock_levels_with_voltage *clks)
|
||||
void dcn_bw_update_from_pplib_fclks(
|
||||
struct dc *dc,
|
||||
struct dm_pp_clock_levels_with_voltage *fclks)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (clks->num_levels == 0)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < clks->num_levels; i++)
|
||||
/* Ensure that the result is sane */
|
||||
if (clks->data[i].clocks_in_khz == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcn_bw_update_from_pplib(struct dc *dc)
|
||||
{
|
||||
struct dc_context *ctx = dc->ctx;
|
||||
struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};
|
||||
bool res;
|
||||
unsigned vmin0p65_idx, vmid0p72_idx, vnom0p8_idx, vmax0p9_idx;
|
||||
|
||||
/* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
|
||||
res = dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks);
|
||||
ASSERT(fclks->num_levels);
|
||||
|
||||
if (res)
|
||||
res = verify_clock_values(&fclks);
|
||||
vmin0p65_idx = 0;
|
||||
vmid0p72_idx = fclks->num_levels -
|
||||
(fclks->num_levels > 2 ? 3 : (fclks->num_levels > 1 ? 2 : 1));
|
||||
vnom0p8_idx = fclks->num_levels - (fclks->num_levels > 1 ? 2 : 1);
|
||||
vmax0p9_idx = fclks->num_levels - 1;
|
||||
|
||||
if (res) {
|
||||
ASSERT(fclks.num_levels);
|
||||
|
||||
vmin0p65_idx = 0;
|
||||
vmid0p72_idx = fclks.num_levels -
|
||||
(fclks.num_levels > 2 ? 3 : (fclks.num_levels > 1 ? 2 : 1));
|
||||
vnom0p8_idx = fclks.num_levels - (fclks.num_levels > 1 ? 2 : 1);
|
||||
vmax0p9_idx = fclks.num_levels - 1;
|
||||
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 =
|
||||
32 * (fclks.data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 =
|
||||
dc->dcn_soc->number_of_channels *
|
||||
(fclks.data[vmid0p72_idx].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 =
|
||||
dc->dcn_soc->number_of_channels *
|
||||
(fclks.data[vnom0p8_idx].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 =
|
||||
dc->dcn_soc->number_of_channels *
|
||||
(fclks.data[vmax0p9_idx].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
} else
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
||||
res = dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks);
|
||||
|
||||
if (res)
|
||||
res = verify_clock_values(&dcfclks);
|
||||
|
||||
if (res && dcfclks.num_levels >= 3) {
|
||||
dc->dcn_soc->dcfclkv_min0p65 = dcfclks.data[0].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_mid0p72 = dcfclks.data[dcfclks.num_levels - 3].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_nom0p8 = dcfclks.data[dcfclks.num_levels - 2].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_max0p9 = dcfclks.data[dcfclks.num_levels - 1].clocks_in_khz / 1000.0;
|
||||
} else
|
||||
BREAK_TO_DEBUGGER();
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 =
|
||||
32 * (fclks->data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 =
|
||||
dc->dcn_soc->number_of_channels *
|
||||
(fclks->data[vmid0p72_idx].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 =
|
||||
dc->dcn_soc->number_of_channels *
|
||||
(fclks->data[vnom0p8_idx].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 =
|
||||
dc->dcn_soc->number_of_channels *
|
||||
(fclks->data[vmax0p9_idx].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
}
|
||||
|
||||
void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
|
||||
void dcn_bw_update_from_pplib_dcfclks(
|
||||
struct dc *dc,
|
||||
struct dm_pp_clock_levels_with_voltage *dcfclks)
|
||||
{
|
||||
if (dcfclks->num_levels >= 3) {
|
||||
dc->dcn_soc->dcfclkv_min0p65 = dcfclks->data[0].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_mid0p72 = dcfclks->data[dcfclks->num_levels - 3].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_nom0p8 = dcfclks->data[dcfclks->num_levels - 2].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_max0p9 = dcfclks->data[dcfclks->num_levels - 1].clocks_in_khz / 1000.0;
|
||||
}
|
||||
}
|
||||
|
||||
void dcn_get_soc_clks(
|
||||
struct dc *dc,
|
||||
int *min_fclk_khz,
|
||||
int *min_dcfclk_khz,
|
||||
int *socclk_khz)
|
||||
{
|
||||
*min_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 * 1000000 / 32;
|
||||
*min_dcfclk_khz = dc->dcn_soc->dcfclkv_min0p65 * 1000;
|
||||
*socclk_khz = dc->dcn_soc->socclk * 1000;
|
||||
}
|
||||
|
||||
void dcn_bw_notify_pplib_of_wm_ranges(
|
||||
struct dc *dc,
|
||||
int min_fclk_khz,
|
||||
int min_dcfclk_khz,
|
||||
int socclk_khz)
|
||||
{
|
||||
struct pp_smu_funcs_rv *pp = NULL;
|
||||
struct pp_smu_wm_range_sets ranges = {0};
|
||||
int min_fclk_khz, min_dcfclk_khz, socclk_khz;
|
||||
const int overdrive = 5000000; /* 5 GHz to cover Overdrive */
|
||||
|
||||
if (dc->res_pool->pp_smu)
|
||||
|
@ -1526,10 +1512,6 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
|
|||
if (!pp || !pp->set_wm_ranges)
|
||||
return;
|
||||
|
||||
min_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 * 1000000 / 32;
|
||||
min_dcfclk_khz = dc->dcn_soc->dcfclkv_min0p65 * 1000;
|
||||
socclk_khz = dc->dcn_soc->socclk * 1000;
|
||||
|
||||
/* Now notify PPLib/SMU about which Watermarks sets they should select
|
||||
* depending on DPM state they are in. And update BW MGR GFX Engine and
|
||||
* Memory clock member variables for Watermarks calculations for each
|
||||
|
|
|
@ -292,6 +292,7 @@ static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
|
|||
.urgent_latency_adjustment_fabric_clock_component_us = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
|
||||
.num_chans = 4,
|
||||
.dummy_pstate_latency_us = 10.0
|
||||
};
|
||||
|
||||
struct _vcs_dpi_ip_params_st dcn3_16_ip = {
|
||||
|
@ -459,13 +460,30 @@ void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
|
|||
}
|
||||
}
|
||||
|
||||
void dcn315_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
dc_assert_fp_enabled();
|
||||
|
||||
if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) {
|
||||
/* For 315 pstate change is only supported if possible in vactive */
|
||||
if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[context->bw_ctx.dml.vba.VoltageLevel][context->bw_ctx.dml.vba.maxMpcComb] != dm_dram_clock_change_vactive)
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
|
||||
else
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us;
|
||||
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us =
|
||||
dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_enter_plus_exit_time_us;
|
||||
context->bw_ctx.dml.soc.sr_exit_time_us =
|
||||
dc->clk_mgr->bw_params->wm_table.entries[WM_A].sr_exit_time_us;
|
||||
}
|
||||
}
|
||||
|
||||
void dcn31_calculate_wm_and_dlg_fp(
|
||||
struct dc *dc, struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int pipe_cnt,
|
||||
int vlevel)
|
||||
{
|
||||
int i, pipe_idx;
|
||||
int i, pipe_idx, active_dpp_count = 0;
|
||||
double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||
|
||||
dc_assert_fp_enabled();
|
||||
|
@ -486,72 +504,6 @@ void dcn31_calculate_wm_and_dlg_fp(
|
|||
pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
|
||||
pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
|
||||
|
||||
#if 0 // TODO
|
||||
/* Set B:
|
||||
* TODO
|
||||
*/
|
||||
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid) {
|
||||
if (vlevel == 0) {
|
||||
pipes[0].clks_cfg.voltage = 1;
|
||||
pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dcfclk_mhz;
|
||||
}
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us;
|
||||
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us;
|
||||
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us;
|
||||
}
|
||||
context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_z8_ns = get_wm_z8_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_z8_ns = get_wm_z8_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
|
||||
pipes[0].clks_cfg.voltage = vlevel;
|
||||
pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
|
||||
|
||||
/* Set C:
|
||||
* TODO
|
||||
*/
|
||||
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) {
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us;
|
||||
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;
|
||||
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;
|
||||
}
|
||||
context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_z8_ns = get_wm_z8_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_z8_ns = get_wm_z8_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
|
||||
/* Set D:
|
||||
* TODO
|
||||
*/
|
||||
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us;
|
||||
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us;
|
||||
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us;
|
||||
}
|
||||
context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_z8_ns = get_wm_z8_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_z8_ns = get_wm_z8_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
#endif
|
||||
|
||||
/* Set A:
|
||||
* All clocks min required
|
||||
*
|
||||
|
@ -568,16 +520,17 @@ void dcn31_calculate_wm_and_dlg_fp(
|
|||
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
/* TODO: remove: */
|
||||
context->bw_ctx.bw.dcn.watermarks.b = context->bw_ctx.bw.dcn.watermarks.a;
|
||||
context->bw_ctx.bw.dcn.watermarks.c = context->bw_ctx.bw.dcn.watermarks.a;
|
||||
context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a;
|
||||
/* end remove*/
|
||||
|
||||
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
|
||||
if (context->res_ctx.pipe_ctx[i].plane_state)
|
||||
active_dpp_count++;
|
||||
|
||||
pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
|
||||
pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
|
||||
|
||||
|
@ -594,6 +547,9 @@ void dcn31_calculate_wm_and_dlg_fp(
|
|||
}
|
||||
|
||||
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
|
||||
/* For 31x apu pstate change is only supported if possible in vactive or if there are no active dpps */
|
||||
context->bw_ctx.bw.dcn.clk.p_state_change_support =
|
||||
context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_vactive || !active_dpp_count;
|
||||
}
|
||||
|
||||
void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
|
||||
|
@ -739,7 +695,7 @@ void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
|||
}
|
||||
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
|
||||
dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN31);
|
||||
dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN315);
|
||||
else
|
||||
dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN31_FPGA);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ void dcn31_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes,
|
|||
int pipe_cnt);
|
||||
|
||||
void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context);
|
||||
void dcn315_update_soc_for_wm_a(struct dc *dc, struct dc_state *context);
|
||||
|
||||
void dcn31_calculate_wm_and_dlg_fp(
|
||||
struct dc *dc, struct dc_state *context,
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#define BPP_BLENDED_PIPE 0xffffffff
|
||||
#define DCN31_MAX_DSC_IMAGE_WIDTH 5184
|
||||
#define DCN31_MAX_FMT_420_BUFFER_WIDTH 4096
|
||||
#define DCN3_15_MIN_COMPBUF_SIZE_KB 128
|
||||
#define DCN3_15_MAX_DET_SIZE 384
|
||||
|
||||
// For DML-C changes that hasn't been propagated to VBA yet
|
||||
//#define __DML_VBA_ALLOW_DELTA__
|
||||
|
@ -3775,6 +3777,17 @@ static noinline void CalculatePrefetchSchedulePerPlane(
|
|||
&v->VReadyOffsetPix[k]);
|
||||
}
|
||||
|
||||
static void PatchDETBufferSizeInKByte(unsigned int NumberOfActivePlanes, int NoOfDPPThisState[], unsigned int config_return_buffer_size_in_kbytes, unsigned int *DETBufferSizeInKByte)
|
||||
{
|
||||
int i, total_pipes = 0;
|
||||
for (i = 0; i < NumberOfActivePlanes; i++)
|
||||
total_pipes += NoOfDPPThisState[i];
|
||||
*DETBufferSizeInKByte = ((config_return_buffer_size_in_kbytes - DCN3_15_MIN_COMPBUF_SIZE_KB) / 64 / total_pipes) * 64;
|
||||
if (*DETBufferSizeInKByte > DCN3_15_MAX_DET_SIZE)
|
||||
*DETBufferSizeInKByte = DCN3_15_MAX_DET_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
|
||||
{
|
||||
struct vba_vars_st *v = &mode_lib->vba;
|
||||
|
@ -4533,6 +4546,8 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
v->ODMCombineEnableThisState[k] = v->ODMCombineEnablePerState[i][k];
|
||||
}
|
||||
|
||||
if (v->NumberOfActivePlanes > 1 && mode_lib->project == DML_PROJECT_DCN315)
|
||||
PatchDETBufferSizeInKByte(v->NumberOfActivePlanes, v->NoOfDPPThisState, v->ip.config_return_buffer_size_in_kbytes, &v->DETBufferSizeInKByte[0]);
|
||||
CalculateSwathAndDETConfiguration(
|
||||
false,
|
||||
v->NumberOfActivePlanes,
|
||||
|
|
|
@ -243,7 +243,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
|
|||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Finds dummy_latency_index when MCLK switching using firmware based
|
||||
* vblank stretch is enabled. This function will iterate through the
|
||||
* table of dummy pstate latencies until the lowest value that allows
|
||||
|
@ -290,15 +290,14 @@ int dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
|
|||
/**
|
||||
* dcn32_helper_populate_phantom_dlg_params - Get DLG params for phantom pipes
|
||||
* and populate pipe_ctx with those params.
|
||||
*
|
||||
* This function must be called AFTER the phantom pipes are added to context
|
||||
* and run through DML (so that the DLG params for the phantom pipes can be
|
||||
* populated), and BEFORE we program the timing for the phantom pipes.
|
||||
*
|
||||
* @dc: [in] current dc state
|
||||
* @context: [in] new dc state
|
||||
* @pipes: [in] DML pipe params array
|
||||
* @pipe_cnt: [in] DML pipe count
|
||||
*
|
||||
* This function must be called AFTER the phantom pipes are added to context
|
||||
* and run through DML (so that the DLG params for the phantom pipes can be
|
||||
* populated), and BEFORE we program the timing for the phantom pipes.
|
||||
*/
|
||||
void dcn32_helper_populate_phantom_dlg_params(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -331,8 +330,9 @@ void dcn32_helper_populate_phantom_dlg_params(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* *******************************************************************************************
|
||||
* dcn32_predict_pipe_split: Predict if pipe split will occur for a given DML pipe
|
||||
* dcn32_predict_pipe_split - Predict if pipe split will occur for a given DML pipe
|
||||
* @context: [in] New DC state to be programmed
|
||||
* @pipe_e2e: [in] DML pipe end to end context
|
||||
*
|
||||
* This function takes in a DML pipe (pipe_e2e) and predicts if pipe split is required (both
|
||||
* ODM and MPC). For pipe split, ODM combine is determined by the ODM mode, and MPC combine is
|
||||
|
@ -343,12 +343,7 @@ void dcn32_helper_populate_phantom_dlg_params(struct dc *dc,
|
|||
* - MPC combine is only chosen if there is no ODM combine requirements / policy in place, and
|
||||
* MPC is required
|
||||
*
|
||||
* @param [in]: context: New DC state to be programmed
|
||||
* @param [in]: pipe_e2e: DML pipe end to end context
|
||||
*
|
||||
* @return: Number of splits expected (1 for 2:1 split, 3 for 4:1 split, 0 for no splits).
|
||||
*
|
||||
* *******************************************************************************************
|
||||
* Return: Number of splits expected (1 for 2:1 split, 3 for 4:1 split, 0 for no splits).
|
||||
*/
|
||||
uint8_t dcn32_predict_pipe_split(struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipe_e2e)
|
||||
|
@ -504,7 +499,14 @@ void insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table,
|
|||
}
|
||||
|
||||
/**
|
||||
* dcn32_set_phantom_stream_timing: Set timing params for the phantom stream
|
||||
* dcn32_set_phantom_stream_timing - Set timing params for the phantom stream
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
* @ref_pipe: Main pipe for the phantom stream
|
||||
* @phantom_stream: target phantom stream state
|
||||
* @pipes: DML pipe params
|
||||
* @pipe_cnt: number of DML pipes
|
||||
* @dc_pipe_idx: DC pipe index for the main pipe (i.e. ref_pipe)
|
||||
*
|
||||
* Set timing params of the phantom stream based on calculated output from DML.
|
||||
* This function first gets the DML pipe index using the DC pipe index, then
|
||||
|
@ -517,13 +519,6 @@ void insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table,
|
|||
* that separately.
|
||||
*
|
||||
* - Set phantom backporch = vstartup of main pipe
|
||||
*
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
* @ref_pipe: Main pipe for the phantom stream
|
||||
* @pipes: DML pipe params
|
||||
* @pipe_cnt: number of DML pipes
|
||||
* @dc_pipe_idx: DC pipe index for the main pipe (i.e. ref_pipe)
|
||||
*/
|
||||
void dcn32_set_phantom_stream_timing(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -592,16 +587,14 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* dcn32_get_num_free_pipes: Calculate number of free pipes
|
||||
* dcn32_get_num_free_pipes - Calculate number of free pipes
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* This function assumes that a "used" pipe is a pipe that has
|
||||
* both a stream and a plane assigned to it.
|
||||
*
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* Return:
|
||||
* Number of free pipes available in the context
|
||||
* Return: Number of free pipes available in the context
|
||||
*/
|
||||
static unsigned int dcn32_get_num_free_pipes(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
|
@ -625,7 +618,10 @@ static unsigned int dcn32_get_num_free_pipes(struct dc *dc, struct dc_state *con
|
|||
}
|
||||
|
||||
/**
|
||||
* dcn32_assign_subvp_pipe: Function to decide which pipe will use Sub-VP.
|
||||
* dcn32_assign_subvp_pipe - Function to decide which pipe will use Sub-VP.
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
* @index: [out] dc pipe index for the pipe chosen to have phantom pipes assigned
|
||||
*
|
||||
* We enter this function if we are Sub-VP capable (i.e. enough pipes available)
|
||||
* and regular P-State switching (i.e. VACTIVE/VBLANK) is not supported, or if
|
||||
|
@ -639,12 +635,7 @@ static unsigned int dcn32_get_num_free_pipes(struct dc *dc, struct dc_state *con
|
|||
* for determining which should be the SubVP pipe (need a way to determine if a pipe / plane doesn't
|
||||
* support MCLK switching naturally [i.e. ACTIVE or VBLANK]).
|
||||
*
|
||||
* @param dc: current dc state
|
||||
* @param context: new dc state
|
||||
* @param index: [out] dc pipe index for the pipe chosen to have phantom pipes assigned
|
||||
*
|
||||
* Return:
|
||||
* True if a valid pipe assignment was found for Sub-VP. Otherwise false.
|
||||
* Return: True if a valid pipe assignment was found for Sub-VP. Otherwise false.
|
||||
*/
|
||||
static bool dcn32_assign_subvp_pipe(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -711,7 +702,9 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* dcn32_enough_pipes_for_subvp: Function to check if there are "enough" pipes for SubVP.
|
||||
* dcn32_enough_pipes_for_subvp - Function to check if there are "enough" pipes for SubVP.
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* This function returns true if there are enough free pipes
|
||||
* to create the required phantom pipes for any given stream
|
||||
|
@ -723,9 +716,6 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc,
|
|||
* pipe which can be used as the phantom pipe for the non pipe
|
||||
* split pipe.
|
||||
*
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* Return:
|
||||
* True if there are enough free pipes to assign phantom pipes to at least one
|
||||
* stream that does not already have phantom pipes assigned. Otherwise false.
|
||||
|
@ -764,7 +754,9 @@ static bool dcn32_enough_pipes_for_subvp(struct dc *dc, struct dc_state *context
|
|||
}
|
||||
|
||||
/**
|
||||
* subvp_subvp_schedulable: Determine if SubVP + SubVP config is schedulable
|
||||
* subvp_subvp_schedulable - Determine if SubVP + SubVP config is schedulable
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* High level algorithm:
|
||||
* 1. Find longest microschedule length (in us) between the two SubVP pipes
|
||||
|
@ -772,11 +764,7 @@ static bool dcn32_enough_pipes_for_subvp(struct dc *dc, struct dc_state *context
|
|||
* pipes still allows for the maximum microschedule to fit in the active
|
||||
* region for both pipes.
|
||||
*
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* Return:
|
||||
* bool - True if the SubVP + SubVP config is schedulable, false otherwise
|
||||
* Return: True if the SubVP + SubVP config is schedulable, false otherwise
|
||||
*/
|
||||
static bool subvp_subvp_schedulable(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
|
@ -836,7 +824,10 @@ static bool subvp_subvp_schedulable(struct dc *dc, struct dc_state *context)
|
|||
}
|
||||
|
||||
/**
|
||||
* subvp_drr_schedulable: Determine if SubVP + DRR config is schedulable
|
||||
* subvp_drr_schedulable - Determine if SubVP + DRR config is schedulable
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
* @drr_pipe: DRR pipe_ctx for the SubVP + DRR config
|
||||
*
|
||||
* High level algorithm:
|
||||
* 1. Get timing for SubVP pipe, phantom pipe, and DRR pipe
|
||||
|
@ -845,12 +836,7 @@ static bool subvp_subvp_schedulable(struct dc *dc, struct dc_state *context)
|
|||
* 3.If (SubVP Active - Prefetch > Stretched DRR frame + max(MALL region, Stretched DRR frame))
|
||||
* then report the configuration as supported
|
||||
*
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
* @drr_pipe: DRR pipe_ctx for the SubVP + DRR config
|
||||
*
|
||||
* Return:
|
||||
* bool - True if the SubVP + DRR config is schedulable, false otherwise
|
||||
* Return: True if the SubVP + DRR config is schedulable, false otherwise
|
||||
*/
|
||||
static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context, struct pipe_ctx *drr_pipe)
|
||||
{
|
||||
|
@ -914,7 +900,9 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context, struc
|
|||
|
||||
|
||||
/**
|
||||
* subvp_vblank_schedulable: Determine if SubVP + VBLANK config is schedulable
|
||||
* subvp_vblank_schedulable - Determine if SubVP + VBLANK config is schedulable
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* High level algorithm:
|
||||
* 1. Get timing for SubVP pipe, phantom pipe, and VBLANK pipe
|
||||
|
@ -922,11 +910,7 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context, struc
|
|||
* then report the configuration as supported
|
||||
* 3. If the VBLANK display is DRR, then take the DRR static schedulability path
|
||||
*
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
*
|
||||
* Return:
|
||||
* bool - True if the SubVP + VBLANK/DRR config is schedulable, false otherwise
|
||||
* Return: True if the SubVP + VBLANK/DRR config is schedulable, false otherwise
|
||||
*/
|
||||
static bool subvp_vblank_schedulable(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
|
@ -1003,20 +987,18 @@ static bool subvp_vblank_schedulable(struct dc *dc, struct dc_state *context)
|
|||
}
|
||||
|
||||
/**
|
||||
* subvp_validate_static_schedulability: Check which SubVP case is calculated and handle
|
||||
* static analysis based on the case.
|
||||
* subvp_validate_static_schedulability - Check which SubVP case is calculated
|
||||
* and handle static analysis based on the case.
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
* @vlevel: Voltage level calculated by DML
|
||||
*
|
||||
* Three cases:
|
||||
* 1. SubVP + SubVP
|
||||
* 2. SubVP + VBLANK (DRR checked internally)
|
||||
* 3. SubVP + VACTIVE (currently unsupported)
|
||||
*
|
||||
* @dc: current dc state
|
||||
* @context: new dc state
|
||||
* @vlevel: Voltage level calculated by DML
|
||||
*
|
||||
* Return:
|
||||
* bool - True if statically schedulable, false otherwise
|
||||
* Return: True if statically schedulable, false otherwise
|
||||
*/
|
||||
static bool subvp_validate_static_schedulability(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -1115,7 +1097,8 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
|
|||
* 5. (Config doesn't support MCLK in VACTIVE/VBLANK || dc->debug.force_subvp_mclk_switch)
|
||||
*/
|
||||
if (!dc->debug.force_disable_subvp && dcn32_all_pipes_have_stream_and_plane(dc, context) &&
|
||||
!dcn32_mpo_in_use(context) && (*vlevel == context->bw_ctx.dml.soc.num_states ||
|
||||
!dcn32_mpo_in_use(context) && !dcn32_any_surfaces_rotated(dc, context) &&
|
||||
(*vlevel == context->bw_ctx.dml.soc.num_states ||
|
||||
vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported ||
|
||||
dc->debug.force_subvp_mclk_switch)) {
|
||||
|
||||
|
@ -1597,6 +1580,9 @@ bool dcn32_internal_validate_bw(struct dc *dc,
|
|||
/*MPC split rules will handle this case*/
|
||||
pipe->bottom_pipe->top_pipe = NULL;
|
||||
} else {
|
||||
/* when merging an ODM pipes, the bottom MPC pipe must now point to
|
||||
* the previous ODM pipe and its associated stream assets
|
||||
*/
|
||||
if (pipe->prev_odm_pipe->bottom_pipe) {
|
||||
/* 3 plane MPO*/
|
||||
pipe->bottom_pipe->top_pipe = pipe->prev_odm_pipe->bottom_pipe;
|
||||
|
@ -1606,6 +1592,8 @@ bool dcn32_internal_validate_bw(struct dc *dc,
|
|||
pipe->bottom_pipe->top_pipe = pipe->prev_odm_pipe;
|
||||
pipe->prev_odm_pipe->bottom_pipe = pipe->bottom_pipe;
|
||||
}
|
||||
|
||||
memcpy(&pipe->bottom_pipe->stream_res, &pipe->bottom_pipe->top_pipe->stream_res, sizeof(struct stream_resource));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1781,6 +1769,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
|||
int i, pipe_idx, vlevel_temp = 0;
|
||||
double dcfclk = dcn3_2_soc.clock_limits[0].dcfclk_mhz;
|
||||
double dcfclk_from_validation = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||
double dcfclk_from_fw_based_mclk_switching = dcfclk_from_validation;
|
||||
bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] !=
|
||||
dm_dram_clock_change_unsupported;
|
||||
unsigned int dummy_latency_index = 0;
|
||||
|
@ -1816,7 +1805,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
|||
dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
|
||||
dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
|
||||
maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
|
||||
dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||
dcfclk_from_fw_based_mclk_switching = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||
pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] !=
|
||||
dm_dram_clock_change_unsupported;
|
||||
}
|
||||
|
@ -1902,6 +1891,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
|||
pipes[0].clks_cfg.dcfclk_mhz = dcfclk_from_validation;
|
||||
pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
|
||||
|
||||
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
|
||||
pipes[0].clks_cfg.dcfclk_mhz = dcfclk_from_fw_based_mclk_switching;
|
||||
}
|
||||
|
||||
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) {
|
||||
min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed;
|
||||
min_dram_speed_mts_margin = 160;
|
||||
|
@ -2275,7 +2268,7 @@ static int build_synthetic_soc_states(struct clk_bw_params *bw_params,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* dcn32_update_bw_bounding_box
|
||||
*
|
||||
* This would override some dcn3_2 ip_or_soc initial parameters hardcoded from
|
||||
|
|
|
@ -733,6 +733,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
|||
mode_lib->vba.FCLKChangeLatency, v->UrgentLatency,
|
||||
mode_lib->vba.SREnterPlusExitTime);
|
||||
|
||||
memset(&v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe, 0, sizeof(DmlPipe));
|
||||
|
||||
v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.Dppclk = mode_lib->vba.DPPCLK[k];
|
||||
v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.Dispclk = mode_lib->vba.DISPCLK;
|
||||
v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.PixelClock = mode_lib->vba.PixelClock[k];
|
||||
|
@ -2252,9 +2254,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) {
|
||||
if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
|
||||
|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
|
||||
|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0
|
||||
|| mode_lib->vba.DSCInputBitPerComponent[k] >
|
||||
mode_lib->vba.MaximumDSCBitsPerComponent)) {
|
||||
|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)
|
||||
|| mode_lib->vba.DSCInputBitPerComponent[k] > mode_lib->vba.MaximumDSCBitsPerComponent) {
|
||||
mode_lib->vba.NonsupportedDSCInputBPC = true;
|
||||
}
|
||||
}
|
||||
|
@ -2330,16 +2331,15 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
if (mode_lib->vba.OutputMultistreamId[k] == k && mode_lib->vba.ForcedOutputLinkBPP[k] == 0)
|
||||
mode_lib->vba.BPPForMultistreamNotIndicated = true;
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActiveSurfaces; ++j) {
|
||||
if (mode_lib->vba.OutputMultistreamId[k] == j && mode_lib->vba.OutputMultistreamEn[k]
|
||||
if (mode_lib->vba.OutputMultistreamId[k] == j
|
||||
&& mode_lib->vba.ForcedOutputLinkBPP[k] == 0)
|
||||
mode_lib->vba.BPPForMultistreamNotIndicated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mode_lib->vba.Output[k] == dm_edp || mode_lib->vba.Output[k] == dm_hdmi)) {
|
||||
if (mode_lib->vba.OutputMultistreamId[k] == k && mode_lib->vba.OutputMultistreamEn[k])
|
||||
if (mode_lib->vba.OutputMultistreamEn[k] == true && mode_lib->vba.OutputMultistreamId[k] == k)
|
||||
mode_lib->vba.MultistreamWithHDMIOreDP = true;
|
||||
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActiveSurfaces; ++j) {
|
||||
if (mode_lib->vba.OutputMultistreamEn[k] == true && mode_lib->vba.OutputMultistreamId[k] == j)
|
||||
mode_lib->vba.MultistreamWithHDMIOreDP = true;
|
||||
|
@ -2478,8 +2478,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
mode_lib->vba.PixelClock[k], mode_lib->vba.PixelClockBackEnd[k]);
|
||||
}
|
||||
|
||||
m = 0;
|
||||
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) {
|
||||
for (m = 0; m <= mode_lib->vba.NumberOfActiveSurfaces - 1; m++) {
|
||||
for (j = 0; j <= mode_lib->vba.NumberOfActiveSurfaces - 1; j++) {
|
||||
|
@ -2856,8 +2854,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
}
|
||||
}
|
||||
|
||||
m = 0;
|
||||
|
||||
//Calculate Return BW
|
||||
for (i = 0; i < (int) v->soc.num_states; ++i) {
|
||||
for (j = 0; j <= 1; ++j) {
|
||||
|
@ -3618,11 +3614,10 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
|||
mode_lib->vba.ModeIsSupported = mode_lib->vba.ModeSupport[i][0] == true
|
||||
|| mode_lib->vba.ModeSupport[i][1] == true;
|
||||
|
||||
if (mode_lib->vba.ModeSupport[i][0] == true) {
|
||||
if (mode_lib->vba.ModeSupport[i][0] == true)
|
||||
MaximumMPCCombine = 0;
|
||||
} else {
|
||||
else
|
||||
MaximumMPCCombine = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ void dml_init_instance(struct display_mode_lib *lib,
|
|||
break;
|
||||
case DML_PROJECT_DCN31:
|
||||
case DML_PROJECT_DCN31_FPGA:
|
||||
case DML_PROJECT_DCN315:
|
||||
lib->funcs = dml31_funcs;
|
||||
break;
|
||||
case DML_PROJECT_DCN314:
|
||||
|
|
|
@ -40,6 +40,7 @@ enum dml_project {
|
|||
DML_PROJECT_DCN21,
|
||||
DML_PROJECT_DCN30,
|
||||
DML_PROJECT_DCN31,
|
||||
DML_PROJECT_DCN315,
|
||||
DML_PROJECT_DCN31_FPGA,
|
||||
DML_PROJECT_DCN314,
|
||||
DML_PROJECT_DCN32,
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include "panel_cntl.h"
|
||||
|
||||
#define MAX_CLOCK_SOURCES 7
|
||||
#define MAX_SVP_PHANTOM_STREAMS 2
|
||||
#define MAX_SVP_PHANTOM_PLANES 2
|
||||
|
||||
void enable_surface_flip_reporting(struct dc_plane_state *plane_state,
|
||||
uint32_t controller_id);
|
||||
|
@ -232,6 +234,7 @@ struct resource_funcs {
|
|||
unsigned int index);
|
||||
|
||||
bool (*remove_phantom_pipes)(struct dc *dc, struct dc_state *context);
|
||||
void (*get_panel_config_defaults)(struct dc_panel_config *panel_config);
|
||||
};
|
||||
|
||||
struct audio_support{
|
||||
|
@ -438,7 +441,6 @@ struct pipe_ctx {
|
|||
union pipe_update_flags update_flags;
|
||||
struct dwbc *dwbc;
|
||||
struct mcif_wb *mcif_wb;
|
||||
bool vtp_locked;
|
||||
};
|
||||
|
||||
/* Data used for dynamic link encoder assignment.
|
||||
|
@ -492,6 +494,8 @@ struct dcn_bw_output {
|
|||
struct dcn_watermark_set watermarks;
|
||||
struct dcn_bw_writeback bw_writeback;
|
||||
int compbuf_size_kb;
|
||||
unsigned int legacy_svp_drr_stream_index;
|
||||
bool legacy_svp_drr_stream_index_valid;
|
||||
};
|
||||
|
||||
union bw_output {
|
||||
|
|
|
@ -628,8 +628,23 @@ unsigned int dcn_find_dcfclk_suits_all(
|
|||
const struct dc *dc,
|
||||
struct dc_clocks *clocks);
|
||||
|
||||
void dcn_bw_update_from_pplib(struct dc *dc);
|
||||
void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc);
|
||||
void dcn_get_soc_clks(
|
||||
struct dc *dc,
|
||||
int *min_fclk_khz,
|
||||
int *min_dcfclk_khz,
|
||||
int *socclk_khz);
|
||||
|
||||
void dcn_bw_update_from_pplib_fclks(
|
||||
struct dc *dc,
|
||||
struct dm_pp_clock_levels_with_voltage *fclks);
|
||||
void dcn_bw_update_from_pplib_dcfclks(
|
||||
struct dc *dc,
|
||||
struct dm_pp_clock_levels_with_voltage *dcfclks);
|
||||
void dcn_bw_notify_pplib_of_wm_ranges(
|
||||
struct dc *dc,
|
||||
int min_fclk_khz,
|
||||
int min_dcfclk_khz,
|
||||
int socclk_khz);
|
||||
void dcn_bw_sync_calcs_and_dml(struct dc *dc);
|
||||
|
||||
enum source_macro_tile_size swizzle_mode_to_macro_tile_size(enum swizzle_mode_values sw_mode);
|
||||
|
|
|
@ -95,10 +95,23 @@ struct clk_limit_table_entry {
|
|||
unsigned int wck_ratio;
|
||||
};
|
||||
|
||||
struct clk_limit_num_entries {
|
||||
unsigned int num_dcfclk_levels;
|
||||
unsigned int num_fclk_levels;
|
||||
unsigned int num_memclk_levels;
|
||||
unsigned int num_socclk_levels;
|
||||
unsigned int num_dtbclk_levels;
|
||||
unsigned int num_dispclk_levels;
|
||||
unsigned int num_dppclk_levels;
|
||||
unsigned int num_phyclk_levels;
|
||||
unsigned int num_phyclk_d18_levels;
|
||||
};
|
||||
|
||||
/* This table is contiguous */
|
||||
struct clk_limit_table {
|
||||
struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL];
|
||||
unsigned int num_entries;
|
||||
struct clk_limit_num_entries num_entries_per_clk;
|
||||
unsigned int num_entries; /* highest populated dpm level for back compatibility */
|
||||
};
|
||||
|
||||
struct wm_range_table_entry {
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright © 2022 Advanced Micro Devices, Inc. All rights reserved. */
|
||||
|
||||
#ifndef __DAL_CURSOR_CACHE_H__
|
||||
#define __DAL_CURSOR_CACHE_H__
|
||||
|
||||
union reg_cursor_control_cfg {
|
||||
struct {
|
||||
uint32_t cur_enable: 1;
|
||||
uint32_t reser0: 3;
|
||||
uint32_t cur_2x_magnify: 1;
|
||||
uint32_t reser1: 3;
|
||||
uint32_t mode: 3;
|
||||
uint32_t reser2: 5;
|
||||
uint32_t pitch: 2;
|
||||
uint32_t reser3: 6;
|
||||
uint32_t line_per_chunk: 5;
|
||||
uint32_t reser4: 3;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
};
|
||||
struct cursor_position_cache_hubp {
|
||||
union reg_cursor_control_cfg cur_ctl;
|
||||
union reg_position_cfg {
|
||||
struct {
|
||||
uint32_t x_pos: 16;
|
||||
uint32_t y_pos: 16;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} position;
|
||||
union reg_hot_spot_cfg {
|
||||
struct {
|
||||
uint32_t x_hot: 16;
|
||||
uint32_t y_hot: 16;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} hot_spot;
|
||||
union reg_dst_offset_cfg {
|
||||
struct {
|
||||
uint32_t dst_x_offset: 13;
|
||||
uint32_t reserved: 19;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} dst_offset;
|
||||
};
|
||||
|
||||
struct cursor_attribute_cache_hubp {
|
||||
uint32_t SURFACE_ADDR_HIGH;
|
||||
uint32_t SURFACE_ADDR;
|
||||
union reg_cursor_control_cfg cur_ctl;
|
||||
union reg_cursor_size_cfg {
|
||||
struct {
|
||||
uint32_t width: 16;
|
||||
uint32_t height: 16;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} size;
|
||||
union reg_cursor_settings_cfg {
|
||||
struct {
|
||||
uint32_t dst_y_offset: 8;
|
||||
uint32_t chunk_hdl_adjust: 2;
|
||||
uint32_t reserved: 22;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} settings;
|
||||
};
|
||||
|
||||
struct cursor_rect {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
};
|
||||
|
||||
union reg_cur0_control_cfg {
|
||||
struct {
|
||||
uint32_t cur0_enable: 1;
|
||||
uint32_t expansion_mode: 1;
|
||||
uint32_t reser0: 1;
|
||||
uint32_t cur0_rom_en: 1;
|
||||
uint32_t mode: 3;
|
||||
uint32_t reserved: 25;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
};
|
||||
struct cursor_position_cache_dpp {
|
||||
union reg_cur0_control_cfg cur0_ctl;
|
||||
};
|
||||
|
||||
struct cursor_attribute_cache_dpp {
|
||||
union reg_cur0_control_cfg cur0_ctl;
|
||||
};
|
||||
|
||||
struct cursor_attributes_cfg {
|
||||
struct cursor_attribute_cache_hubp aHubp;
|
||||
struct cursor_attribute_cache_dpp aDpp;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -28,6 +28,7 @@
|
|||
#define __DAL_DPP_H__
|
||||
|
||||
#include "transform.h"
|
||||
#include "cursor_reg_cache.h"
|
||||
|
||||
union defer_reg_writes {
|
||||
struct {
|
||||
|
@ -58,6 +59,9 @@ struct dpp {
|
|||
|
||||
struct pwl_params shaper_params;
|
||||
bool cm_bypass_mode;
|
||||
|
||||
struct cursor_position_cache_dpp pos;
|
||||
struct cursor_attribute_cache_dpp att;
|
||||
};
|
||||
|
||||
struct dpp_input_csc_matrix {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define __DAL_HUBP_H__
|
||||
|
||||
#include "mem_input.h"
|
||||
#include "cursor_reg_cache.h"
|
||||
|
||||
#define OPP_ID_INVALID 0xf
|
||||
#define MAX_TTU 0xffffff
|
||||
|
@ -65,6 +66,10 @@ struct hubp {
|
|||
struct dc_cursor_attributes curs_attr;
|
||||
struct dc_cursor_position curs_pos;
|
||||
bool power_gated;
|
||||
|
||||
struct cursor_position_cache_hubp pos;
|
||||
struct cursor_attribute_cache_hubp att;
|
||||
struct cursor_rect cur_rect;
|
||||
};
|
||||
|
||||
struct surface_flip_registers {
|
||||
|
|
|
@ -209,7 +209,6 @@ struct timing_generator_funcs {
|
|||
void (*set_blank)(struct timing_generator *tg,
|
||||
bool enable_blanking);
|
||||
bool (*is_blanked)(struct timing_generator *tg);
|
||||
bool (*is_locked)(struct timing_generator *tg);
|
||||
void (*set_overscan_blank_color) (struct timing_generator *tg, const struct tg_color *color);
|
||||
void (*set_blank_color)(struct timing_generator *tg, const struct tg_color *color);
|
||||
void (*set_colors)(struct timing_generator *tg,
|
||||
|
|
|
@ -230,4 +230,10 @@ const struct link_hwss *get_link_hwss(const struct dc_link *link,
|
|||
|
||||
bool is_h_timing_divisible_by_2(struct dc_stream_state *stream);
|
||||
|
||||
bool dc_resource_acquire_secondary_pipe_for_mpc_odm(
|
||||
const struct dc *dc,
|
||||
struct dc_state *state,
|
||||
struct pipe_ctx *pri_pipe,
|
||||
struct pipe_ctx *sec_pipe,
|
||||
bool odm);
|
||||
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
|
||||
|
|
|
@ -111,7 +111,7 @@ static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
|
|||
enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link);
|
||||
|
||||
dto_params.otg_inst = tg->inst;
|
||||
dto_params.pixclk_khz = pipe_ctx->stream->phy_pix_clk;
|
||||
dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
|
||||
dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
|
||||
dto_params.timing = &pipe_ctx->stream->timing;
|
||||
dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
|
||||
|
|
|
@ -37,7 +37,7 @@ void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx)
|
|||
{
|
||||
}
|
||||
|
||||
void virtual_disable_link_output(struct dc_link *link,
|
||||
static void virtual_disable_link_output(struct dc_link *link,
|
||||
const struct link_resource *link_res,
|
||||
enum signal_type signal)
|
||||
{
|
||||
|
|
|
@ -248,6 +248,7 @@ struct dmub_srv_hw_params {
|
|||
bool disable_dpia;
|
||||
bool usb4_cm_version;
|
||||
bool fw_in_system_memory;
|
||||
bool dpia_hpd_int_enable_supported;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -400,8 +400,9 @@ union dmub_fw_boot_options {
|
|||
uint32_t diag_env: 1; /* 1 if diagnostic environment */
|
||||
uint32_t gpint_scratch8: 1; /* 1 if GPINT is in scratch8*/
|
||||
uint32_t usb4_cm_version: 1; /**< 1 CM support */
|
||||
uint32_t dpia_hpd_int_enable_supported: 1; /* 1 if dpia hpd int enable supported */
|
||||
|
||||
uint32_t reserved : 17; /**< reserved */
|
||||
uint32_t reserved : 16; /**< reserved */
|
||||
} bits; /**< boot bits */
|
||||
uint32_t all; /**< 32-bit access to bits */
|
||||
};
|
||||
|
@ -728,6 +729,12 @@ enum dmub_cmd_type {
|
|||
/**
|
||||
* Command type used for all VBIOS interface commands.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Command type used to set DPIA HPD interrupt state
|
||||
*/
|
||||
DMUB_CMD__DPIA_HPD_INT_ENABLE = 86,
|
||||
|
||||
DMUB_CMD__VBIOS = 128,
|
||||
};
|
||||
|
||||
|
@ -760,11 +767,6 @@ enum dmub_cmd_dpia_type {
|
|||
DMUB_CMD__DPIA_MST_ALLOC_SLOTS = 2,
|
||||
};
|
||||
|
||||
enum dmub_cmd_header_sub_type {
|
||||
DMUB_CMD__SUB_TYPE_GENERAL = 0,
|
||||
DMUB_CMD__SUB_TYPE_CURSOR_POSITION = 1
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/**
|
||||
|
@ -1260,6 +1262,14 @@ struct dmub_rb_cmd_set_mst_alloc_slots {
|
|||
struct dmub_cmd_mst_alloc_slots_control_data mst_slots_control; /* mst slots control */
|
||||
};
|
||||
|
||||
/**
|
||||
* DMUB command structure for DPIA HPD int enable control.
|
||||
*/
|
||||
struct dmub_rb_cmd_dpia_hpd_int_enable {
|
||||
struct dmub_cmd_header header; /* header */
|
||||
uint32_t enable; /* dpia hpd interrupt enable */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dmub_rb_cmd_dpphy_init - DPPHY init.
|
||||
*/
|
||||
|
@ -2089,7 +2099,99 @@ struct dmub_rb_cmd_update_dirty_rect {
|
|||
/**
|
||||
* Data passed from driver to FW in a DMUB_CMD__UPDATE_CURSOR_INFO command.
|
||||
*/
|
||||
struct dmub_cmd_update_cursor_info_data {
|
||||
union dmub_reg_cursor_control_cfg {
|
||||
struct {
|
||||
uint32_t cur_enable: 1;
|
||||
uint32_t reser0: 3;
|
||||
uint32_t cur_2x_magnify: 1;
|
||||
uint32_t reser1: 3;
|
||||
uint32_t mode: 3;
|
||||
uint32_t reser2: 5;
|
||||
uint32_t pitch: 2;
|
||||
uint32_t reser3: 6;
|
||||
uint32_t line_per_chunk: 5;
|
||||
uint32_t reser4: 3;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
};
|
||||
struct dmub_cursor_position_cache_hubp {
|
||||
union dmub_reg_cursor_control_cfg cur_ctl;
|
||||
union dmub_reg_position_cfg {
|
||||
struct {
|
||||
uint32_t cur_x_pos: 16;
|
||||
uint32_t cur_y_pos: 16;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} position;
|
||||
union dmub_reg_hot_spot_cfg {
|
||||
struct {
|
||||
uint32_t hot_x: 16;
|
||||
uint32_t hot_y: 16;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} hot_spot;
|
||||
union dmub_reg_dst_offset_cfg {
|
||||
struct {
|
||||
uint32_t dst_x_offset: 13;
|
||||
uint32_t reserved: 19;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} dst_offset;
|
||||
};
|
||||
|
||||
union dmub_reg_cur0_control_cfg {
|
||||
struct {
|
||||
uint32_t cur0_enable: 1;
|
||||
uint32_t expansion_mode: 1;
|
||||
uint32_t reser0: 1;
|
||||
uint32_t cur0_rom_en: 1;
|
||||
uint32_t mode: 3;
|
||||
uint32_t reserved: 25;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
};
|
||||
struct dmub_cursor_position_cache_dpp {
|
||||
union dmub_reg_cur0_control_cfg cur0_ctl;
|
||||
};
|
||||
struct dmub_cursor_position_cfg {
|
||||
struct dmub_cursor_position_cache_hubp pHubp;
|
||||
struct dmub_cursor_position_cache_dpp pDpp;
|
||||
uint8_t pipe_idx;
|
||||
/*
|
||||
* Padding is required. To be 4 Bytes Aligned.
|
||||
*/
|
||||
uint8_t padding[3];
|
||||
};
|
||||
|
||||
struct dmub_cursor_attribute_cache_hubp {
|
||||
uint32_t SURFACE_ADDR_HIGH;
|
||||
uint32_t SURFACE_ADDR;
|
||||
union dmub_reg_cursor_control_cfg cur_ctl;
|
||||
union dmub_reg_cursor_size_cfg {
|
||||
struct {
|
||||
uint32_t width: 16;
|
||||
uint32_t height: 16;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} size;
|
||||
union dmub_reg_cursor_settings_cfg {
|
||||
struct {
|
||||
uint32_t dst_y_offset: 8;
|
||||
uint32_t chunk_hdl_adjust: 2;
|
||||
uint32_t reserved: 22;
|
||||
} bits;
|
||||
uint32_t raw;
|
||||
} settings;
|
||||
};
|
||||
struct dmub_cursor_attribute_cache_dpp {
|
||||
union dmub_reg_cur0_control_cfg cur0_ctl;
|
||||
};
|
||||
struct dmub_cursor_attributes_cfg {
|
||||
struct dmub_cursor_attribute_cache_hubp aHubp;
|
||||
struct dmub_cursor_attribute_cache_dpp aDpp;
|
||||
};
|
||||
|
||||
struct dmub_cmd_update_cursor_payload0 {
|
||||
/**
|
||||
* Cursor dirty rects.
|
||||
*/
|
||||
|
@ -2116,6 +2218,20 @@ struct dmub_cmd_update_cursor_info_data {
|
|||
* Currently the support is only for 0 or 1
|
||||
*/
|
||||
uint8_t panel_inst;
|
||||
/**
|
||||
* Cursor Position Register.
|
||||
* Registers contains Hubp & Dpp modules
|
||||
*/
|
||||
struct dmub_cursor_position_cfg position_cfg;
|
||||
};
|
||||
|
||||
struct dmub_cmd_update_cursor_payload1 {
|
||||
struct dmub_cursor_attributes_cfg attribute_cfg;
|
||||
};
|
||||
|
||||
union dmub_cmd_update_cursor_info_data {
|
||||
struct dmub_cmd_update_cursor_payload0 payload0;
|
||||
struct dmub_cmd_update_cursor_payload1 payload1;
|
||||
};
|
||||
/**
|
||||
* Definition of a DMUB_CMD__UPDATE_CURSOR_INFO command.
|
||||
|
@ -2128,7 +2244,7 @@ struct dmub_rb_cmd_update_cursor_info {
|
|||
/**
|
||||
* Data passed from driver to FW in a DMUB_CMD__UPDATE_CURSOR_INFO command.
|
||||
*/
|
||||
struct dmub_cmd_update_cursor_info_data update_cursor_info_data;
|
||||
union dmub_cmd_update_cursor_info_data update_cursor_info_data;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2825,11 +2941,7 @@ struct dmub_rb_cmd_get_visual_confirm_color {
|
|||
struct dmub_optc_state {
|
||||
uint32_t v_total_max;
|
||||
uint32_t v_total_min;
|
||||
uint32_t v_total_mid;
|
||||
uint32_t v_total_mid_frame_num;
|
||||
uint32_t tg_inst;
|
||||
uint32_t enable_manual_trigger;
|
||||
uint32_t clear_force_vsync;
|
||||
};
|
||||
|
||||
struct dmub_rb_cmd_drr_update {
|
||||
|
@ -3235,6 +3347,10 @@ union dmub_rb_cmd {
|
|||
* Definition of a DMUB_CMD__QUERY_HPD_STATE command.
|
||||
*/
|
||||
struct dmub_rb_cmd_query_hpd_state query_hpd;
|
||||
/**
|
||||
* Definition of a DMUB_CMD__DPIA_HPD_INT_ENABLE command.
|
||||
*/
|
||||
struct dmub_rb_cmd_dpia_hpd_int_enable dpia_hpd_int_enable;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -350,6 +350,7 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu
|
|||
boot_options.bits.dpia_supported = params->dpia_supported;
|
||||
boot_options.bits.enable_dpia = params->disable_dpia ? 0 : 1;
|
||||
boot_options.bits.usb4_cm_version = params->usb4_cm_version;
|
||||
boot_options.bits.dpia_hpd_int_enable_supported = params->dpia_hpd_int_enable_supported;
|
||||
boot_options.bits.power_optimization = params->power_optimization;
|
||||
|
||||
boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0;
|
||||
|
|
|
@ -1692,7 +1692,7 @@ static void apply_degamma_for_user_regamma(struct pwl_float_data_ex *rgb_regamma
|
|||
struct pwl_float_data_ex *rgb = rgb_regamma;
|
||||
const struct hw_x_point *coord_x = coordinates_x;
|
||||
|
||||
build_coefficients(&coeff, true);
|
||||
build_coefficients(&coeff, TRANSFER_FUNCTION_SRGB);
|
||||
|
||||
i = 0;
|
||||
while (i != hw_points_num + 1) {
|
||||
|
|
|
@ -29,5 +29,7 @@
|
|||
#define regMCA_UMC_UMC0_MCUMC_STATUST0_BASE_IDX 2
|
||||
#define regMCA_UMC_UMC0_MCUMC_ADDRT0 0x03c4
|
||||
#define regMCA_UMC_UMC0_MCUMC_ADDRT0_BASE_IDX 2
|
||||
#define regUMCCH0_0_GeccCtrl 0x0053
|
||||
#define regUMCCH0_0_GeccCtrl_BASE_IDX 2
|
||||
|
||||
#endif
|
||||
|
|
|
@ -90,5 +90,8 @@
|
|||
#define MCA_UMC_UMC0_MCUMC_ADDRT0__ErrorAddr__SHIFT 0x0
|
||||
#define MCA_UMC_UMC0_MCUMC_ADDRT0__Reserved__SHIFT 0x38
|
||||
#define MCA_UMC_UMC0_MCUMC_ADDRT0__ErrorAddr_MASK 0x00FFFFFFFFFFFFFFL
|
||||
//UMCCH0_0_GeccCtrl
|
||||
#define UMCCH0_0_GeccCtrl__UCFatalEn__SHIFT 0xd
|
||||
#define UMCCH0_0_GeccCtrl__UCFatalEn_MASK 0x00002000L
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1384,13 +1384,16 @@ static int kv_dpm_enable(struct amdgpu_device *adev)
|
|||
static void kv_dpm_disable(struct amdgpu_device *adev)
|
||||
{
|
||||
struct kv_power_info *pi = kv_get_pi(adev);
|
||||
int err;
|
||||
|
||||
amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,
|
||||
AMDGPU_THERMAL_IRQ_LOW_TO_HIGH);
|
||||
amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,
|
||||
AMDGPU_THERMAL_IRQ_HIGH_TO_LOW);
|
||||
|
||||
amdgpu_kv_smc_bapm_enable(adev, false);
|
||||
err = amdgpu_kv_smc_bapm_enable(adev, false);
|
||||
if (err)
|
||||
DRM_ERROR("amdgpu_kv_smc_bapm_enable failed\n");
|
||||
|
||||
if (adev->asic_type == CHIP_MULLINS)
|
||||
kv_enable_nb_dpm(adev, false);
|
||||
|
|
|
@ -3603,7 +3603,7 @@ static int smu7_get_pp_table_entry_callback_func_v1(struct pp_hwmgr *hwmgr,
|
|||
return -EINVAL);
|
||||
|
||||
PP_ASSERT_WITH_CODE(
|
||||
(smu7_power_state->performance_level_count <=
|
||||
(smu7_power_state->performance_level_count <
|
||||
hwmgr->platform_descriptor.hardwareActivityPerformanceLevels),
|
||||
"Performance levels exceeds Driver limit!",
|
||||
return -EINVAL);
|
||||
|
|
|
@ -3155,7 +3155,7 @@ static int vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
|
|||
return -1);
|
||||
|
||||
PP_ASSERT_WITH_CODE(
|
||||
(vega10_ps->performance_level_count <=
|
||||
(vega10_ps->performance_level_count <
|
||||
hwmgr->platform_descriptor.
|
||||
hardwareActivityPerformanceLevels),
|
||||
"Performance levels exceeds Driver limit!",
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче