mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-18 08:35:08 +08:00
Merge tag 'amd-drm-next-6.3-2023-02-17' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.3-2023-02-17: amdgpu: - GC 11 fixes - Display fixes - Backlight cleanup - SMU13 fixes - SMU7 regression fix - GFX9 sw queues fix - AGP fix for GMC 11 - W1 warning fixes - S/G display fixes - Misc spelling fixes - Driver unload fix - DCN 3.1.4 fixes - Display code reorg fixes - Rotation fixes Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230217230930.64821-1-alexander.deucher@amd.com
This commit is contained in:
commit
fec67d1896
@ -34,6 +34,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
|
||||
-I$(FULL_AMD_PATH)/acp/include \
|
||||
-I$(FULL_AMD_DISPLAY_PATH) \
|
||||
-I$(FULL_AMD_DISPLAY_PATH)/include \
|
||||
-I$(FULL_AMD_DISPLAY_PATH)/modules/inc \
|
||||
-I$(FULL_AMD_DISPLAY_PATH)/dc \
|
||||
-I$(FULL_AMD_DISPLAY_PATH)/amdgpu_dm \
|
||||
-I$(FULL_AMD_PATH)/amdkfd
|
||||
@ -76,7 +77,7 @@ amdgpu-y += \
|
||||
vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
|
||||
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
|
||||
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
|
||||
sienna_cichlid.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
|
||||
sienna_cichlid.o smu_v13_0_10.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
|
||||
|
||||
# add DF block
|
||||
amdgpu-y += \
|
||||
|
@ -242,6 +242,7 @@ extern int amdgpu_num_kcq;
|
||||
|
||||
#define AMDGPU_VCNFW_LOG_SIZE (32 * 1024)
|
||||
extern int amdgpu_vcnfw_log;
|
||||
extern int amdgpu_sg_display;
|
||||
|
||||
#define AMDGPU_VM_MAX_NUM_CTX 4096
|
||||
#define AMDGPU_SG_THRESHOLD (256*1024*1024)
|
||||
|
@ -164,7 +164,7 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
|
||||
*
|
||||
* The amdgpu driver provides a sysfs API for reporting the product name
|
||||
* for the device
|
||||
* The file serial_number is used for this and returns the product name
|
||||
* The file product_name is used for this and returns the product name
|
||||
* as returned from the FRU.
|
||||
* NOTE: This is only available for certain server cards
|
||||
*/
|
||||
@ -186,7 +186,7 @@ static DEVICE_ATTR(product_name, S_IRUGO,
|
||||
*
|
||||
* The amdgpu driver provides a sysfs API for reporting the part number
|
||||
* for the device
|
||||
* The file serial_number is used for this and returns the part number
|
||||
* The file product_number is used for this and returns the part number
|
||||
* as returned from the FRU.
|
||||
* NOTE: This is only available for certain server cards
|
||||
*/
|
||||
@ -4270,6 +4270,9 @@ exit:
|
||||
}
|
||||
adev->in_suspend = false;
|
||||
|
||||
if (adev->enable_mes)
|
||||
amdgpu_mes_self_test(adev);
|
||||
|
||||
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0))
|
||||
DRM_WARN("smart shift update failed\n");
|
||||
|
||||
|
@ -188,6 +188,7 @@ int amdgpu_num_kcq = -1;
|
||||
int amdgpu_smartshift_bias;
|
||||
int amdgpu_use_xgmi_p2p = 1;
|
||||
int amdgpu_vcnfw_log;
|
||||
int amdgpu_sg_display = -1; /* auto */
|
||||
|
||||
static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
|
||||
|
||||
@ -933,6 +934,16 @@ module_param_named(num_kcq, amdgpu_num_kcq, int, 0444);
|
||||
MODULE_PARM_DESC(vcnfw_log, "Enable vcnfw log(0 = disable (default value), 1 = enable)");
|
||||
module_param_named(vcnfw_log, amdgpu_vcnfw_log, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: sg_display (int)
|
||||
* Disable S/G (scatter/gather) display (i.e., display from system memory).
|
||||
* This option is only relevant on APUs. Set this option to 0 to disable
|
||||
* S/G display if you experience flickering or other issues under memory
|
||||
* pressure and report the issue.
|
||||
*/
|
||||
MODULE_PARM_DESC(sg_display, "S/G Display (-1 = auto (default), 0 = disable)");
|
||||
module_param_named(sg_display, amdgpu_sg_display, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: smu_pptable_id (int)
|
||||
* Used to override pptable id. id = 0 use VBIOS pptable.
|
||||
|
@ -618,7 +618,13 @@ void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev)
|
||||
if (!ring || !ring->fence_drv.initialized)
|
||||
continue;
|
||||
|
||||
if (!ring->no_scheduler)
|
||||
/*
|
||||
* Notice we check for sched.ops since there's some
|
||||
* override on the meaning of sched.ready by amdgpu.
|
||||
* The natural check would be sched.ready, which is
|
||||
* set as drm_sched_init() finishes...
|
||||
*/
|
||||
if (ring->sched.ops)
|
||||
drm_sched_fini(&ring->sched);
|
||||
|
||||
for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
|
||||
|
@ -620,7 +620,8 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
||||
*/
|
||||
if (!dev_entered)
|
||||
WARN_ON(psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_LOAD_ASD &&
|
||||
psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_UNLOAD_TA);
|
||||
psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_UNLOAD_TA &&
|
||||
psp->cmd_buf_mem->cmd_id != GFX_CMD_ID_INVOKE_CMD);
|
||||
|
||||
memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "amdgpu_reset.h"
|
||||
#include "aldebaran.h"
|
||||
#include "sienna_cichlid.h"
|
||||
#include "smu_v13_0_10.h"
|
||||
|
||||
int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_handler *handler)
|
||||
@ -44,6 +45,9 @@ int amdgpu_reset_init(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 7):
|
||||
ret = sienna_cichlid_reset_init(adev);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
ret = smu_v13_0_10_reset_init(adev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -62,6 +66,9 @@ int amdgpu_reset_fini(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 7):
|
||||
ret = sienna_cichlid_reset_fini(adev);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
ret = smu_v13_0_10_reset_fini(adev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ struct amdgpu_ring {
|
||||
#define amdgpu_ring_parse_cs(r, p, job, ib) ((r)->funcs->parse_cs((p), (job), (ib)))
|
||||
#define amdgpu_ring_patch_cs_in_place(r, p, job, ib) ((r)->funcs->patch_cs_in_place((p), (job), (ib)))
|
||||
#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
|
||||
#define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t))
|
||||
#define amdgpu_ring_test_ib(r, t) ((r)->funcs->test_ib ? (r)->funcs->test_ib((r), (t)) : 0)
|
||||
#define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r))
|
||||
#define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r))
|
||||
#define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r))
|
||||
|
@ -538,6 +538,7 @@ struct amdgpu_firmware {
|
||||
|
||||
void amdgpu_ucode_print_mc_hdr(const struct common_firmware_header *hdr);
|
||||
void amdgpu_ucode_print_smc_hdr(const struct common_firmware_header *hdr);
|
||||
void amdgpu_ucode_print_imu_hdr(const struct common_firmware_header *hdr);
|
||||
void amdgpu_ucode_print_gfx_hdr(const struct common_firmware_header *hdr);
|
||||
void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr);
|
||||
void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr);
|
||||
|
@ -983,9 +983,13 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
|
||||
if (offset == reg_access_ctrl->grbm_cntl) {
|
||||
/* if the target reg offset is grbm_cntl, write to scratch_reg2 */
|
||||
writel(v, scratch_reg2);
|
||||
if (flag == AMDGPU_RLCG_GC_WRITE_LEGACY)
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
|
||||
} else if (offset == reg_access_ctrl->grbm_idx) {
|
||||
/* if the target reg offset is grbm_idx, write to scratch_reg3 */
|
||||
writel(v, scratch_reg3);
|
||||
if (flag == AMDGPU_RLCG_GC_WRITE_LEGACY)
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
|
||||
} else {
|
||||
/*
|
||||
* SCRATCH_REG0 = read/write value
|
||||
|
@ -974,7 +974,7 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
|
||||
trace_amdgpu_vm_update_ptes(params, frag_start, upd_end,
|
||||
min(nptes, 32u), dst, incr,
|
||||
upd_flags,
|
||||
vm->task_info.pid,
|
||||
vm->task_info.tgid,
|
||||
vm->immediate.fence_context);
|
||||
amdgpu_vm_pte_update_flags(params, to_amdgpu_bo_vm(pt),
|
||||
cursor.level, pe_start, dst,
|
||||
|
@ -6783,7 +6783,6 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
|
||||
.emit_gds_switch = gfx_v9_0_ring_emit_gds_switch,
|
||||
.emit_hdp_flush = gfx_v9_0_ring_emit_hdp_flush,
|
||||
.test_ring = gfx_v9_0_ring_test_ring,
|
||||
.test_ib = gfx_v9_0_ring_test_ib,
|
||||
.insert_nop = amdgpu_ring_insert_nop,
|
||||
.pad_ib = amdgpu_ring_generic_pad_ib,
|
||||
.emit_switch_buffer = gfx_v9_ring_emit_sb,
|
||||
|
@ -159,9 +159,9 @@ static void gfxhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 18);
|
||||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start
|
||||
|
@ -159,14 +159,14 @@ static void gfxhub_v3_0_3_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
|
||||
/* Disable AGP. */
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BASE, 0);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, 0);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BOT, 0x00FFFFFF);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BOT, adev->gmc.agp_start >> 24);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, adev->gmc.agp_end >> 24);
|
||||
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 18);
|
||||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start
|
||||
|
@ -1284,7 +1284,7 @@ static int mes_v11_0_late_init(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* it's only intended for use in mes_self_test case, not for s0ix and reset */
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_s0ix &&
|
||||
if (!amdgpu_in_reset(adev) && !adev->in_s0ix && !adev->in_suspend &&
|
||||
(adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3)))
|
||||
amdgpu_mes_self_test(adev);
|
||||
|
||||
|
@ -184,9 +184,9 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 18);
|
||||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
|
@ -183,9 +183,9 @@ static void mmhub_v3_0_1_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
*/
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 18);
|
||||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
|
@ -175,9 +175,9 @@ static void mmhub_v3_0_2_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
*/
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 18);
|
||||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
}
|
||||
|
||||
/* Set default page address. */
|
||||
|
@ -273,8 +273,6 @@ static void sdma_v6_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
* sdma_v6_0_ring_emit_mem_sync - flush the IB by graphics cache rinse
|
||||
*
|
||||
* @ring: amdgpu ring pointer
|
||||
* @job: job to retrieve vmid from
|
||||
* @ib: IB object to schedule
|
||||
*
|
||||
* flush the IB by graphics cache rinse.
|
||||
*/
|
||||
@ -326,7 +324,9 @@ static void sdma_v6_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
|
||||
* sdma_v6_0_ring_emit_fence - emit a fence on the DMA ring
|
||||
*
|
||||
* @ring: amdgpu ring pointer
|
||||
* @fence: amdgpu fence object
|
||||
* @addr: address
|
||||
* @seq: fence seq number
|
||||
* @flags: fence flags
|
||||
*
|
||||
* Add a DMA fence packet to the ring to write
|
||||
* the fence seq number and DMA trap packet to generate
|
||||
@ -1060,10 +1060,9 @@ static void sdma_v6_0_vm_copy_pte(struct amdgpu_ib *ib,
|
||||
*
|
||||
* @ib: indirect buffer to fill with commands
|
||||
* @pe: addr of the page entry
|
||||
* @addr: dst addr to write into pe
|
||||
* @value: dst addr to write into pe
|
||||
* @count: number of page entries to update
|
||||
* @incr: increase next addr by incr bytes
|
||||
* @flags: access flags
|
||||
*
|
||||
* Update PTEs by writing them manually using sDMA.
|
||||
*/
|
||||
@ -1167,7 +1166,6 @@ static void sdma_v6_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
||||
* sdma_v6_0_ring_emit_vm_flush - vm flush using sDMA
|
||||
*
|
||||
* @ring: amdgpu_ring pointer
|
||||
* @vm: amdgpu_vm pointer
|
||||
*
|
||||
* Update the page table base and flush the VM TLB
|
||||
* using sDMA.
|
||||
@ -1591,10 +1589,11 @@ static void sdma_v6_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
/**
|
||||
* sdma_v6_0_emit_copy_buffer - copy buffer using the sDMA engine
|
||||
*
|
||||
* @ring: amdgpu_ring structure holding ring information
|
||||
* @ib: indirect buffer to fill with commands
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: if a secure copy should be used
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine.
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1620,7 +1619,7 @@ static void sdma_v6_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
/**
|
||||
* sdma_v6_0_emit_fill_buffer - fill buffer using the sDMA engine
|
||||
*
|
||||
* @ring: amdgpu_ring structure holding ring information
|
||||
* @ib: indirect buffer to fill
|
||||
* @src_data: value to write to buffer
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
|
303
drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c
Normal file
303
drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright 2023 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "smu_v13_0_10.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_dpm.h"
|
||||
#include "amdgpu_job.h"
|
||||
#include "amdgpu_ring.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_psp.h"
|
||||
|
||||
static bool smu_v13_0_10_is_mode2_default(struct amdgpu_reset_control *reset_ctl)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
if (adev->pm.fw_version >= 0x00502005 && !amdgpu_sriov_vf(adev))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct amdgpu_reset_handler *
|
||||
smu_v13_0_10_get_reset_handler(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
struct amdgpu_reset_handler *handler;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
if (reset_context->method != AMD_RESET_METHOD_NONE) {
|
||||
list_for_each_entry(handler, &reset_ctl->reset_handlers,
|
||||
handler_list) {
|
||||
if (handler->reset_method == reset_context->method)
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
if (smu_v13_0_10_is_mode2_default(reset_ctl) &&
|
||||
amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_MODE2) {
|
||||
list_for_each_entry (handler, &reset_ctl->reset_handlers,
|
||||
handler_list) {
|
||||
if (handler->reset_method == AMD_RESET_METHOD_MODE2)
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int smu_v13_0_10_mode2_suspend_ip(struct amdgpu_device *adev)
|
||||
{
|
||||
int r, i;
|
||||
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||
|
||||
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
||||
if (!(adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_SDMA ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_MES))
|
||||
continue;
|
||||
|
||||
r = adev->ip_blocks[i].version->funcs->suspend(adev);
|
||||
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"suspend of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = false;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
smu_v13_0_10_mode2_prepare_hwcontext(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
int r = 0;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
r = smu_v13_0_10_mode2_suspend_ip(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int smu_v13_0_10_mode2_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
return amdgpu_dpm_mode2_reset(adev);
|
||||
}
|
||||
|
||||
static void smu_v13_0_10_async_reset(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_reset_handler *handler;
|
||||
struct amdgpu_reset_control *reset_ctl =
|
||||
container_of(work, struct amdgpu_reset_control, reset_work);
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
list_for_each_entry(handler, &reset_ctl->reset_handlers,
|
||||
handler_list) {
|
||||
if (handler->reset_method == reset_ctl->active_reset) {
|
||||
dev_dbg(adev->dev, "Resetting device\n");
|
||||
handler->do_reset(adev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
static int
|
||||
smu_v13_0_10_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
int r;
|
||||
|
||||
r = smu_v13_0_10_mode2_reset(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"ASIC reset failed with error, %d ", r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int smu_v13_0_10_mode2_restore_ip(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, r;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct amdgpu_firmware_info *ucode;
|
||||
struct amdgpu_firmware_info *ucode_list[2];
|
||||
int ucode_count = 0;
|
||||
|
||||
for (i = 0; i < adev->firmware.max_ucodes; i++) {
|
||||
ucode = &adev->firmware.ucode[i];
|
||||
|
||||
switch (ucode->ucode_id) {
|
||||
case AMDGPU_UCODE_ID_IMU_I:
|
||||
case AMDGPU_UCODE_ID_IMU_D:
|
||||
ucode_list[ucode_count++] = ucode;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = psp_load_fw_list(psp, ucode_list, ucode_count);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "IMU ucode load failed after mode2 reset\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = psp_rlc_autoload_start(psp);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to start rlc autoload after mode2 reset\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
amdgpu_dpm_enable_gfx_features(adev);
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!(adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_MES ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
r = adev->ip_blocks[i].version->funcs->resume(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"resume of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!(adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_MES ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
|
||||
if (adev->ip_blocks[i].version->funcs->late_init) {
|
||||
r = adev->ip_blocks[i].version->funcs->late_init(
|
||||
(void *)adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"late_init of IP block <%s> failed %d after reset\n",
|
||||
adev->ip_blocks[i].version->funcs->name,
|
||||
r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
adev->ip_blocks[i].status.late_initialized = true;
|
||||
}
|
||||
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
smu_v13_0_10_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *tmp_adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
dev_info(tmp_adev->dev,
|
||||
"GPU reset succeeded, trying to resume\n");
|
||||
r = smu_v13_0_10_mode2_restore_ip(tmp_adev);
|
||||
if (r)
|
||||
goto end;
|
||||
|
||||
amdgpu_register_gpu_instance(tmp_adev);
|
||||
|
||||
/* Resume RAS */
|
||||
amdgpu_ras_resume(tmp_adev);
|
||||
|
||||
amdgpu_irq_gpu_reset_resume_helper(tmp_adev);
|
||||
|
||||
r = amdgpu_ib_ring_tests(tmp_adev);
|
||||
if (r) {
|
||||
dev_err(tmp_adev->dev,
|
||||
"ib ring test failed (%d).\n", r);
|
||||
r = -EAGAIN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
if (r)
|
||||
return -EAGAIN;
|
||||
else
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct amdgpu_reset_handler smu_v13_0_10_mode2_handler = {
|
||||
.reset_method = AMD_RESET_METHOD_MODE2,
|
||||
.prepare_env = NULL,
|
||||
.prepare_hwcontext = smu_v13_0_10_mode2_prepare_hwcontext,
|
||||
.perform_reset = smu_v13_0_10_mode2_perform_reset,
|
||||
.restore_hwcontext = smu_v13_0_10_mode2_restore_hwcontext,
|
||||
.restore_env = NULL,
|
||||
.do_reset = smu_v13_0_10_mode2_reset,
|
||||
};
|
||||
|
||||
int smu_v13_0_10_reset_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_reset_control *reset_ctl;
|
||||
|
||||
reset_ctl = kzalloc(sizeof(*reset_ctl), GFP_KERNEL);
|
||||
if (!reset_ctl)
|
||||
return -ENOMEM;
|
||||
|
||||
reset_ctl->handle = adev;
|
||||
reset_ctl->async_reset = smu_v13_0_10_async_reset;
|
||||
reset_ctl->active_reset = AMD_RESET_METHOD_NONE;
|
||||
reset_ctl->get_reset_handler = smu_v13_0_10_get_reset_handler;
|
||||
|
||||
INIT_LIST_HEAD(&reset_ctl->reset_handlers);
|
||||
INIT_WORK(&reset_ctl->reset_work, reset_ctl->async_reset);
|
||||
/* Only mode2 is handled through reset control now */
|
||||
amdgpu_reset_add_handler(reset_ctl, &smu_v13_0_10_mode2_handler);
|
||||
|
||||
adev->reset_cntl = reset_ctl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int smu_v13_0_10_reset_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
kfree(adev->reset_cntl);
|
||||
adev->reset_cntl = NULL;
|
||||
return 0;
|
||||
}
|
32
drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.h
Normal file
32
drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2023 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SMU_V13_0_10_H__
|
||||
#define __SMU_V13_0_10_H__
|
||||
|
||||
#include "amdgpu.h"
|
||||
|
||||
int smu_v13_0_10_reset_init(struct amdgpu_device *adev);
|
||||
int smu_v13_0_10_reset_fini(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
@ -677,7 +677,9 @@ static int soc21_common_early_init(void *handle)
|
||||
AMD_CG_SUPPORT_GFX_CGLS |
|
||||
AMD_CG_SUPPORT_REPEATER_FGCG |
|
||||
AMD_CG_SUPPORT_GFX_MGCG |
|
||||
AMD_CG_SUPPORT_HDP_SD;
|
||||
AMD_CG_SUPPORT_HDP_SD |
|
||||
AMD_CG_SUPPORT_ATHUB_MGCG |
|
||||
AMD_CG_SUPPORT_ATHUB_LS;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
|
@ -1065,6 +1065,20 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
|
||||
mutex_unlock(&p->svms.lock);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
|
||||
/* When register user buffer check if it has been registered by svm by
|
||||
* buffer cpu virtual address.
|
||||
*/
|
||||
if ((flags & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) &&
|
||||
interval_tree_iter_first(&p->svms.objects,
|
||||
args->mmap_offset >> PAGE_SHIFT,
|
||||
(args->mmap_offset + args->size - 1) >> PAGE_SHIFT)) {
|
||||
pr_err("User Buffer Address: 0x%llx already allocated by SVM\n",
|
||||
args->mmap_offset);
|
||||
mutex_unlock(&p->svms.lock);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
|
||||
mutex_unlock(&p->svms.lock);
|
||||
#endif
|
||||
mutex_lock(&p->mutex);
|
||||
|
@ -1191,7 +1191,7 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
|
||||
|
||||
/* AGP aperture is disabled */
|
||||
if (agp_bot == agp_top) {
|
||||
logical_addr_low = adev->gmc.vram_start >> 18;
|
||||
logical_addr_low = adev->gmc.fb_start >> 18;
|
||||
if (adev->apu_flags & AMD_APU_IS_RAVEN2)
|
||||
/*
|
||||
* Raven2 has a HW issue that it is unable to use the vram which
|
||||
@ -1201,9 +1201,9 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
|
||||
*/
|
||||
logical_addr_high = (adev->gmc.fb_end >> 18) + 0x1;
|
||||
else
|
||||
logical_addr_high = adev->gmc.vram_end >> 18;
|
||||
logical_addr_high = adev->gmc.fb_end >> 18;
|
||||
} else {
|
||||
logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18;
|
||||
logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18;
|
||||
if (adev->apu_flags & AMD_APU_IS_RAVEN2)
|
||||
/*
|
||||
* Raven2 has a HW issue that it is unable to use the vram which
|
||||
@ -1283,7 +1283,7 @@ static void dm_handle_hpd_rx_offload_work(struct work_struct *work)
|
||||
dc_link = aconnector->dc_link;
|
||||
|
||||
mutex_lock(&aconnector->hpd_lock);
|
||||
if (!dc_link_detect_sink(dc_link, &new_connection_type))
|
||||
if (!dc_link_detect_connection_type(dc_link, &new_connection_type))
|
||||
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||
mutex_unlock(&aconnector->hpd_lock);
|
||||
|
||||
@ -1334,7 +1334,7 @@ static void dm_handle_hpd_rx_offload_work(struct work_struct *work)
|
||||
offload_work->offload_wq->is_handling_link_loss = false;
|
||||
spin_unlock_irqrestore(&offload_work->offload_wq->offload_lock, flags);
|
||||
|
||||
if ((dp_read_hpd_rx_irq_data(dc_link, &irq_data) == DC_OK) &&
|
||||
if ((dc_link_dp_read_hpd_rx_irq_data(dc_link, &irq_data) == DC_OK) &&
|
||||
dc_link_check_link_loss_status(dc_link, &irq_data))
|
||||
dc_link_dp_handle_link_loss(dc_link);
|
||||
}
|
||||
@ -1566,8 +1566,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
(adev->apu_flags & AMD_APU_IS_PICASSO))
|
||||
init_data.flags.gpu_vm_support = true;
|
||||
break;
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(3, 0, 1):
|
||||
case IP_VERSION(3, 1, 2):
|
||||
case IP_VERSION(3, 1, 3):
|
||||
case IP_VERSION(3, 1, 4):
|
||||
case IP_VERSION(3, 1, 5):
|
||||
case IP_VERSION(3, 1, 6):
|
||||
init_data.flags.gpu_vm_support = true;
|
||||
break;
|
||||
@ -1576,6 +1580,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (init_data.flags.gpu_vm_support &&
|
||||
(amdgpu_sg_display == 0))
|
||||
init_data.flags.gpu_vm_support = false;
|
||||
|
||||
if (init_data.flags.gpu_vm_support)
|
||||
adev->mode_info.gpu_vm_support = true;
|
||||
@ -1597,6 +1604,11 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP2_0)
|
||||
init_data.flags.allow_lttpr_non_transparent_mode.bits.DP2_0 = true;
|
||||
|
||||
/* Disable SubVP + DRR config by default */
|
||||
init_data.flags.disable_subvp_drr = true;
|
||||
if (amdgpu_dc_feature_mask & DC_ENABLE_SUBVP_DRR)
|
||||
init_data.flags.disable_subvp_drr = false;
|
||||
|
||||
init_data.flags.seamless_boot_edp_requested = false;
|
||||
|
||||
if (check_seamless_boot_capability(adev)) {
|
||||
@ -1652,6 +1664,23 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
/* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */
|
||||
adev->dm.dc->debug.ignore_cable_id = true;
|
||||
|
||||
/* TODO: There is a new drm mst change where the freedom of
|
||||
* vc_next_start_slot update is revoked/moved into drm, instead of in
|
||||
* driver. This forces us to make sure to get vc_next_start_slot updated
|
||||
* in drm function each time without considering if mst_state is active
|
||||
* or not. Otherwise, next time hotplug will give wrong start_slot
|
||||
* number. We are implementing a temporary solution to even notify drm
|
||||
* mst deallocation when link is no longer of MST type when uncommitting
|
||||
* the stream so we will have more time to work on a proper solution.
|
||||
* Ideally when dm_helpers_dp_mst_stop_top_mgr message is triggered, we
|
||||
* should notify drm to do a complete "reset" of its states and stop
|
||||
* calling further drm mst functions when link is no longer of an MST
|
||||
* type. This could happen when we unplug an MST hubs/displays. When
|
||||
* uncommit stream comes later after unplug, we should just reset
|
||||
* hardware states only.
|
||||
*/
|
||||
adev->dm.dc->debug.temp_mst_deallocation_sequence = true;
|
||||
|
||||
if (adev->dm.dc->caps.dp_hdmi21_pcon_support)
|
||||
DRM_INFO("DP-HDMI FRL PCON supported\n");
|
||||
|
||||
@ -2777,7 +2806,7 @@ static int dm_resume(void *handle)
|
||||
continue;
|
||||
|
||||
mutex_lock(&aconnector->hpd_lock);
|
||||
if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
|
||||
if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type))
|
||||
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||
|
||||
if (aconnector->base.force && new_connection_type == dc_connection_none) {
|
||||
@ -3118,7 +3147,7 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
|
||||
|
||||
aconnector->timing_changed = false;
|
||||
|
||||
if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
|
||||
if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type))
|
||||
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||
|
||||
if (aconnector->base.force && new_connection_type == dc_connection_none) {
|
||||
@ -3321,7 +3350,7 @@ static void handle_hpd_rx_irq(void *param)
|
||||
out:
|
||||
if (result && !is_mst_root_connector) {
|
||||
/* Downstream Port status changed. */
|
||||
if (!dc_link_detect_sink(dc_link, &new_connection_type))
|
||||
if (!dc_link_detect_connection_type(dc_link, &new_connection_type))
|
||||
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||
|
||||
if (aconnector->base.force && new_connection_type == dc_connection_none) {
|
||||
@ -4230,6 +4259,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||
const struct dc_plane_cap *plane;
|
||||
bool psr_feature_enabled = false;
|
||||
int max_overlay = dm->dc->caps.max_slave_planes;
|
||||
|
||||
dm->display_indexes_num = dm->dc->caps.max_streams;
|
||||
/* Update the actual used number of crtc */
|
||||
@ -4284,14 +4314,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
if (!plane->pixel_format_support.argb8888)
|
||||
continue;
|
||||
|
||||
if (max_overlay-- == 0)
|
||||
break;
|
||||
|
||||
if (initialize_plane(dm, NULL, primary_planes + i,
|
||||
DRM_PLANE_TYPE_OVERLAY, plane)) {
|
||||
DRM_ERROR("KMS: Failed to initialize overlay plane\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Only create one overlay plane. */
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < dm->dc->caps.max_streams; i++)
|
||||
@ -4370,7 +4400,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
|
||||
link = dc_get_link_at_index(dm->dc, i);
|
||||
|
||||
if (!dc_link_detect_sink(link, &new_connection_type))
|
||||
if (!dc_link_detect_connection_type(link, &new_connection_type))
|
||||
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||
|
||||
if (aconnector->base.force && new_connection_type == dc_connection_none) {
|
||||
@ -5020,6 +5050,7 @@ out:
|
||||
* @new_plane_state: New state of @plane
|
||||
* @crtc_state: New state of CRTC connected to the @plane
|
||||
* @flip_addrs: DC flip tracking struct, which also tracts dirty rects
|
||||
* @dirty_regions_changed: dirty regions changed
|
||||
*
|
||||
* For PSR SU, DC informs the DMUB uController of dirty rectangle regions
|
||||
* (referred to as "damage clips" in DRM nomenclature) that require updating on
|
||||
@ -5036,7 +5067,8 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_plane_state,
|
||||
struct drm_plane_state *new_plane_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct dc_flip_addrs *flip_addrs)
|
||||
struct dc_flip_addrs *flip_addrs,
|
||||
bool *dirty_regions_changed)
|
||||
{
|
||||
struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
|
||||
struct rect *dirty_rects = flip_addrs->dirty_rects;
|
||||
@ -5045,6 +5077,7 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
|
||||
bool bb_changed;
|
||||
bool fb_changed;
|
||||
u32 i = 0;
|
||||
*dirty_regions_changed = false;
|
||||
|
||||
/*
|
||||
* Cursor plane has it's own dirty rect update interface. See
|
||||
@ -5089,6 +5122,8 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
|
||||
new_plane_state->plane->base.id,
|
||||
bb_changed, fb_changed, num_clips);
|
||||
|
||||
*dirty_regions_changed = bb_changed;
|
||||
|
||||
if (bb_changed) {
|
||||
fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i],
|
||||
new_plane_state->crtc_x,
|
||||
@ -6175,15 +6210,12 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
|
||||
if (aconnector->mst_mgr.dev)
|
||||
drm_dp_mst_topology_mgr_destroy(&aconnector->mst_mgr);
|
||||
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
|
||||
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
for (i = 0; i < dm->num_of_edps; i++) {
|
||||
if ((link == dm->backlight_link[i]) && dm->backlight_dev[i]) {
|
||||
backlight_device_unregister(dm->backlight_dev[i]);
|
||||
dm->backlight_dev[i] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aconnector->dc_em_sink)
|
||||
dc_sink_release(aconnector->dc_em_sink);
|
||||
@ -7842,7 +7874,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
bool wait_for_vblank)
|
||||
{
|
||||
u32 i;
|
||||
u64 timestamp_ns;
|
||||
u64 timestamp_ns = ktime_get_ns();
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *old_plane_state, *new_plane_state;
|
||||
struct amdgpu_crtc *acrtc_attach = to_amdgpu_crtc(pcrtc);
|
||||
@ -7857,6 +7889,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
|
||||
bool cursor_update = false;
|
||||
bool pflip_present = false;
|
||||
bool dirty_rects_changed = false;
|
||||
struct {
|
||||
struct dc_surface_update surface_updates[MAX_SURFACES];
|
||||
struct dc_plane_info plane_infos[MAX_SURFACES];
|
||||
@ -7944,10 +7977,32 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
bundle->surface_updates[planes_count].plane_info =
|
||||
&bundle->plane_infos[planes_count];
|
||||
|
||||
if (acrtc_state->stream->link->psr_settings.psr_feature_enabled)
|
||||
if (acrtc_state->stream->link->psr_settings.psr_feature_enabled) {
|
||||
fill_dc_dirty_rects(plane, old_plane_state,
|
||||
new_plane_state, new_crtc_state,
|
||||
&bundle->flip_addrs[planes_count]);
|
||||
&bundle->flip_addrs[planes_count],
|
||||
&dirty_rects_changed);
|
||||
|
||||
/*
|
||||
* If the dirty regions changed, PSR-SU need to be disabled temporarily
|
||||
* and enabled it again after dirty regions are stable to avoid video glitch.
|
||||
* PSR-SU will be enabled in vblank_control_worker() if user pause the video
|
||||
* during the PSR-SU was disabled.
|
||||
*/
|
||||
if (acrtc_state->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 &&
|
||||
acrtc_attach->dm_irq_params.allow_psr_entry &&
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
!amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
|
||||
#endif
|
||||
dirty_rects_changed) {
|
||||
mutex_lock(&dm->dc_lock);
|
||||
acrtc_state->stream->link->psr_settings.psr_dirty_rects_change_timestamp_ns =
|
||||
timestamp_ns;
|
||||
if (acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream);
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only allow immediate flips for fast updates that don't
|
||||
@ -8166,7 +8221,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
!amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
|
||||
#endif
|
||||
!acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
!acrtc_state->stream->link->psr_settings.psr_allow_active &&
|
||||
(timestamp_ns -
|
||||
acrtc_state->stream->link->psr_settings.psr_dirty_rects_change_timestamp_ns) >
|
||||
500000000)
|
||||
amdgpu_dm_psr_enable(acrtc_state->stream);
|
||||
} else {
|
||||
acrtc_attach->dm_irq_params.allow_psr_entry = false;
|
||||
@ -9458,7 +9516,8 @@ static int dm_update_plane_state(struct dc *dc,
|
||||
struct drm_plane_state *old_plane_state,
|
||||
struct drm_plane_state *new_plane_state,
|
||||
bool enable,
|
||||
bool *lock_and_validation_needed)
|
||||
bool *lock_and_validation_needed,
|
||||
bool *is_top_most_overlay)
|
||||
{
|
||||
|
||||
struct dm_atomic_state *dm_state = NULL;
|
||||
@ -9566,6 +9625,14 @@ static int dm_update_plane_state(struct dc *dc,
|
||||
if (!dc_new_plane_state)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Block top most plane from being a video plane */
|
||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
|
||||
if (is_video_format(new_plane_state->fb->format->format) && *is_top_most_overlay)
|
||||
return -EINVAL;
|
||||
else
|
||||
*is_top_most_overlay = false;
|
||||
}
|
||||
|
||||
DRM_DEBUG_ATOMIC("Enabling DRM plane: %d on DRM crtc %d\n",
|
||||
plane->base.id, new_plane_crtc->base.id);
|
||||
|
||||
@ -9762,6 +9829,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
enum dc_status status;
|
||||
int ret, i;
|
||||
bool lock_and_validation_needed = false;
|
||||
bool is_top_most_overlay = true;
|
||||
struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct drm_dp_mst_topology_mgr *mgr;
|
||||
@ -9888,7 +9956,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
* `dcn10_can_pipe_disable_cursor`). By now, all modified planes are in
|
||||
* atomic state, so call drm helper to normalize zpos.
|
||||
*/
|
||||
drm_atomic_normalize_zpos(dev, state);
|
||||
ret = drm_atomic_normalize_zpos(dev, state);
|
||||
if (ret) {
|
||||
drm_dbg(dev, "drm_atomic_normalize_zpos() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Remove exiting planes if they are modified */
|
||||
for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
|
||||
@ -9896,7 +9968,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
old_plane_state,
|
||||
new_plane_state,
|
||||
false,
|
||||
&lock_and_validation_needed);
|
||||
&lock_and_validation_needed,
|
||||
&is_top_most_overlay);
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
|
||||
goto fail;
|
||||
@ -9935,7 +10008,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
old_plane_state,
|
||||
new_plane_state,
|
||||
true,
|
||||
&lock_and_validation_needed);
|
||||
&lock_and_validation_needed,
|
||||
&is_top_most_overlay);
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
|
||||
goto fail;
|
||||
|
@ -77,6 +77,9 @@ int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable)
|
||||
struct amdgpu_device *adev = drm_to_adev(crtc->dev);
|
||||
int rc;
|
||||
|
||||
if (acrtc->otg_inst == -1)
|
||||
return 0;
|
||||
|
||||
irq_source = IRQ_TYPE_VUPDATE + acrtc->otg_inst;
|
||||
|
||||
rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY;
|
||||
@ -151,6 +154,9 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
|
||||
struct vblank_control_work *work;
|
||||
int rc = 0;
|
||||
|
||||
if (acrtc->otg_inst == -1)
|
||||
goto skip;
|
||||
|
||||
if (enable) {
|
||||
/* vblank irq on -> Only need vupdate irq in vrr mode */
|
||||
if (amdgpu_dm_vrr_active(acrtc_state))
|
||||
@ -168,6 +174,7 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
|
||||
if (!dc_interrupt_set(adev->dm.dc, irq_source, enable))
|
||||
return -EBUSY;
|
||||
|
||||
skip:
|
||||
if (amdgpu_in_reset(adev))
|
||||
return 0;
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "dsc.h"
|
||||
#include "link_hwss.h"
|
||||
#include "dc/dc_dmub_srv.h"
|
||||
#include "link/protocols/link_dp_capability.h"
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
#include "amdgpu_dm_psr.h"
|
||||
@ -418,67 +419,38 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int dp_lttpr_status_show(struct seq_file *m, void *d)
|
||||
static int dp_lttpr_status_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
char *data;
|
||||
struct amdgpu_dm_connector *connector = file_inode(m->file)->i_private;
|
||||
struct dc_link *link = connector->dc_link;
|
||||
uint32_t read_size = 1;
|
||||
uint8_t repeater_count = 0;
|
||||
struct drm_connector *connector = m->private;
|
||||
struct amdgpu_dm_connector *aconnector =
|
||||
to_amdgpu_dm_connector(connector);
|
||||
struct dc_lttpr_caps caps = aconnector->dc_link->dpcd_caps.lttpr_caps;
|
||||
|
||||
data = kzalloc(read_size, GFP_KERNEL);
|
||||
if (!data)
|
||||
return 0;
|
||||
if (connector->status != connector_status_connected)
|
||||
return -ENODEV;
|
||||
|
||||
dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0002, data, read_size);
|
||||
seq_printf(m, "phy repeater count: %u (raw: 0x%x)\n",
|
||||
dp_parse_lttpr_repeater_count(caps.phy_repeater_cnt),
|
||||
caps.phy_repeater_cnt);
|
||||
|
||||
switch ((uint8_t)*data) {
|
||||
case 0x80:
|
||||
repeater_count = 1;
|
||||
seq_puts(m, "phy repeater mode: ");
|
||||
|
||||
switch (caps.mode) {
|
||||
case DP_PHY_REPEATER_MODE_TRANSPARENT:
|
||||
seq_puts(m, "transparent");
|
||||
break;
|
||||
case 0x40:
|
||||
repeater_count = 2;
|
||||
case DP_PHY_REPEATER_MODE_NON_TRANSPARENT:
|
||||
seq_puts(m, "non-transparent");
|
||||
break;
|
||||
case 0x20:
|
||||
repeater_count = 3;
|
||||
break;
|
||||
case 0x10:
|
||||
repeater_count = 4;
|
||||
break;
|
||||
case 0x8:
|
||||
repeater_count = 5;
|
||||
break;
|
||||
case 0x4:
|
||||
repeater_count = 6;
|
||||
break;
|
||||
case 0x2:
|
||||
repeater_count = 7;
|
||||
break;
|
||||
case 0x1:
|
||||
repeater_count = 8;
|
||||
break;
|
||||
case 0x0:
|
||||
repeater_count = 0;
|
||||
case 0x00:
|
||||
seq_puts(m, "non lttpr");
|
||||
break;
|
||||
default:
|
||||
repeater_count = (uint8_t)*data;
|
||||
seq_printf(m, "read error (raw: 0x%x)", caps.mode);
|
||||
break;
|
||||
}
|
||||
|
||||
seq_printf(m, "phy repeater count: %d\n", repeater_count);
|
||||
|
||||
dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0003, data, read_size);
|
||||
|
||||
if ((uint8_t)*data == 0x55)
|
||||
seq_printf(m, "phy repeater mode: transparent\n");
|
||||
else if ((uint8_t)*data == 0xAA)
|
||||
seq_printf(m, "phy repeater mode: non-transparent\n");
|
||||
else if ((uint8_t)*data == 0x00)
|
||||
seq_printf(m, "phy repeater mode: non lttpr\n");
|
||||
else
|
||||
seq_printf(m, "phy repeater mode: read error\n");
|
||||
|
||||
kfree(data);
|
||||
seq_puts(m, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1285,7 +1257,7 @@ static ssize_t trigger_hotplug(struct file *f, const char __user *buf,
|
||||
|
||||
if (param[0] == 1) {
|
||||
|
||||
if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type) &&
|
||||
if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type) &&
|
||||
new_connection_type != dc_connection_none)
|
||||
goto unlock;
|
||||
|
||||
@ -1322,7 +1294,7 @@ static ssize_t trigger_hotplug(struct file *f, const char __user *buf,
|
||||
|
||||
/* If the aconnector is the root node in mst topology */
|
||||
if (aconnector->mst_mgr.mst_state == true)
|
||||
reset_cur_dp_mst_topology(link);
|
||||
dc_link_reset_cur_dp_mst_topology(link);
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
dm_restore_drm_connector_state(dev, connector);
|
||||
|
@ -1104,7 +1104,7 @@ bool dm_helpers_dp_handle_test_pattern_request(
|
||||
pipe_ctx->stream->timing.display_color_depth = requestColorDepth;
|
||||
pipe_ctx->stream->timing.pixel_encoding = requestPixelEncoding;
|
||||
|
||||
dp_update_dsc_config(pipe_ctx);
|
||||
dc_link_update_dsc_config(pipe_ctx);
|
||||
|
||||
aconnector->timing_changed = true;
|
||||
/* store current timing */
|
||||
|
@ -50,7 +50,7 @@
|
||||
#include "dc/dcn20/dcn20_resource.h"
|
||||
bool is_timing_changed(struct dc_stream_state *cur_stream,
|
||||
struct dc_stream_state *new_stream);
|
||||
|
||||
#define PEAK_FACTOR_X1000 1006
|
||||
|
||||
static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
struct drm_dp_aux_msg *msg)
|
||||
|
@ -67,7 +67,16 @@ static const uint32_t overlay_formats[] = {
|
||||
DRM_FORMAT_RGBA8888,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_RGB565
|
||||
DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_NV21,
|
||||
DRM_FORMAT_NV12,
|
||||
DRM_FORMAT_P010
|
||||
};
|
||||
|
||||
static const uint32_t video_formats[] = {
|
||||
DRM_FORMAT_NV21,
|
||||
DRM_FORMAT_NV12,
|
||||
DRM_FORMAT_P010
|
||||
};
|
||||
|
||||
static const u32 cursor_formats[] = {
|
||||
@ -1616,3 +1625,14 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_video_format(uint32_t format)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(video_formats); i++)
|
||||
if (format == video_formats[i])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -62,4 +62,5 @@ void fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
|
||||
bool *per_pixel_alpha, bool *pre_multiplied_alpha,
|
||||
bool *global_alpha, int *global_alpha_value);
|
||||
|
||||
bool is_video_format(uint32_t format);
|
||||
#endif
|
||||
|
@ -64,8 +64,8 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI
|
||||
|
||||
include $(AMD_DC)
|
||||
|
||||
DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
|
||||
dc_surface.o dc_debug.o dc_stream.o dc_link_enc_cfg.o
|
||||
DISPLAY_CORE = dc.o dc_stat.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
|
||||
dc_surface.o dc_debug.o dc_stream.o dc_link_enc_cfg.o dc_link_exports.o
|
||||
|
||||
DISPLAY_CORE += dc_vm_helper.o
|
||||
|
||||
|
@ -572,11 +572,10 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl
|
||||
{
|
||||
struct clk_bw_params *bw_params = clk_mgr->base.bw_params;
|
||||
struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1];
|
||||
uint32_t max_pstate = 0, max_fclk = 0, max_dispclk = 0, max_dppclk = 0;
|
||||
uint32_t min_pstate = 0, min_fclk = clock_table->DfPstateTable[0].FClk;
|
||||
uint32_t max_pstate = 0, max_fclk = 0, min_pstate = 0, max_dispclk = 0, max_dppclk = 0;
|
||||
int i;
|
||||
|
||||
/* Find highest and lowest valid fclk pstate */
|
||||
/* Find highest valid fclk pstate */
|
||||
for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) {
|
||||
if (is_valid_clock_value(clock_table->DfPstateTable[i].FClk) &&
|
||||
clock_table->DfPstateTable[i].FClk > max_fclk) {
|
||||
@ -585,14 +584,6 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) {
|
||||
if (is_valid_clock_value(clock_table->DfPstateTable[i].FClk) &&
|
||||
clock_table->DfPstateTable[i].FClk < min_fclk) {
|
||||
min_fclk = clock_table->DfPstateTable[i].FClk;
|
||||
min_pstate = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* We expect the table to contain at least one valid fclk entry. */
|
||||
ASSERT(is_valid_clock_value(max_fclk));
|
||||
|
||||
@ -608,17 +599,15 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl
|
||||
|
||||
/* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */
|
||||
for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) {
|
||||
uint32_t max_level_fclk = clock_table->DfPstateTable[0].FClk;
|
||||
uint32_t max_level_pstate = 0;
|
||||
uint32_t min_fclk = clock_table->DfPstateTable[0].FClk;
|
||||
int j;
|
||||
|
||||
/* Look for the maximum supported FCLK for the current voltage. */
|
||||
for (j = 1; j < clock_table->NumDfPstatesEnabled; j++) {
|
||||
if (is_valid_clock_value(clock_table->DfPstateTable[j].FClk) &&
|
||||
clock_table->DfPstateTable[j].FClk > max_level_fclk &&
|
||||
clock_table->DfPstateTable[j].FClk < min_fclk &&
|
||||
clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i]) {
|
||||
max_level_fclk = clock_table->DfPstateTable[j].FClk;
|
||||
max_level_pstate = j;
|
||||
min_fclk = clock_table->DfPstateTable[j].FClk;
|
||||
min_pstate = j;
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,15 +621,15 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl
|
||||
bw_params->clk_table.entries[i].dtbclk_mhz = bw_params->clk_table.entries[j].dtbclk_mhz;
|
||||
|
||||
/* Now update clocks we do read */
|
||||
bw_params->clk_table.entries[i].fclk_mhz = max_level_fclk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_level_pstate].MemClk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_level_pstate].Voltage;
|
||||
bw_params->clk_table.entries[i].fclk_mhz = min_fclk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_pstate].Voltage;
|
||||
bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i];
|
||||
bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i];
|
||||
bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk;
|
||||
bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
|
||||
bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio(
|
||||
clock_table->DfPstateTable[max_level_pstate].WckRatio);
|
||||
clock_table->DfPstateTable[min_pstate].WckRatio);
|
||||
}
|
||||
|
||||
/* Make sure to include at least one entry at highest pstate */
|
||||
|
@ -87,6 +87,16 @@ static int dcn315_get_active_display_cnt_wa(
|
||||
return display_count;
|
||||
}
|
||||
|
||||
static bool should_disable_otg(struct pipe_ctx *pipe)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if (pipe->stream->link->link_enc && pipe->stream->link->link_enc->funcs->is_dig_enabled &&
|
||||
pipe->stream->link->link_enc->funcs->is_dig_enabled(pipe->stream->link->link_enc))
|
||||
ret = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
|
||||
{
|
||||
struct dc *dc = clk_mgr_base->ctx->dc;
|
||||
@ -98,12 +108,16 @@ static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state
|
||||
if (pipe->top_pipe || pipe->prev_odm_pipe)
|
||||
continue;
|
||||
if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL ||
|
||||
dc_is_virtual_signal(pipe->stream->signal))) {
|
||||
if (disable) {
|
||||
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
|
||||
reset_sync_context_for_pipe(dc, context, i);
|
||||
} else
|
||||
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
|
||||
dc_is_virtual_signal(pipe->stream->signal))) {
|
||||
|
||||
/* This w/a should not trigger when we have a dig active */
|
||||
if (should_disable_otg(pipe)) {
|
||||
if (disable) {
|
||||
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
|
||||
reset_sync_context_for_pipe(dc, context, i);
|
||||
} else
|
||||
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1199,7 +1199,7 @@ static void disable_vbios_mode_if_required(
|
||||
pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;
|
||||
|
||||
if (pix_clk_100hz != requested_pix_clk_100hz) {
|
||||
core_link_disable_stream(pipe);
|
||||
link_set_dpms_off(pipe);
|
||||
pipe->stream->dpms_off = false;
|
||||
}
|
||||
}
|
||||
@ -1307,7 +1307,7 @@ static void detect_edp_presence(struct dc *dc)
|
||||
if (dc->config.edp_not_connected) {
|
||||
edp_link->edp_sink_present = false;
|
||||
} else {
|
||||
dc_link_detect_sink(edp_link, &type);
|
||||
dc_link_detect_connection_type(edp_link, &type);
|
||||
edp_link->edp_sink_present = (type != dc_connection_none);
|
||||
}
|
||||
}
|
||||
@ -3173,7 +3173,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
||||
dc->hwss.update_info_frame(pipe_ctx);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
|
||||
link_dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
|
||||
}
|
||||
|
||||
if (stream_update->hdr_static_metadata &&
|
||||
@ -3209,14 +3209,14 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
||||
continue;
|
||||
|
||||
if (stream_update->dsc_config)
|
||||
dp_update_dsc_config(pipe_ctx);
|
||||
link_update_dsc_config(pipe_ctx);
|
||||
|
||||
if (stream_update->mst_bw_update) {
|
||||
if (stream_update->mst_bw_update->is_increase)
|
||||
dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
|
||||
else
|
||||
dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
|
||||
}
|
||||
link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
|
||||
else
|
||||
link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
|
||||
}
|
||||
|
||||
if (stream_update->pending_test_pattern) {
|
||||
dc_link_dp_set_test_pattern(stream->link,
|
||||
@ -3229,7 +3229,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
||||
|
||||
if (stream_update->dpms_off) {
|
||||
if (*stream_update->dpms_off) {
|
||||
core_link_disable_stream(pipe_ctx);
|
||||
link_set_dpms_off(pipe_ctx);
|
||||
/* for dpms, keep acquired resources*/
|
||||
if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
|
||||
pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
|
||||
@ -3239,7 +3239,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
||||
} else {
|
||||
if (get_seamless_boot_stream_count(context) == 0)
|
||||
dc->hwss.prepare_bandwidth(dc, dc->current_state);
|
||||
core_link_enable_stream(dc->current_state, pipe_ctx);
|
||||
link_set_dpms_on(dc->current_state, pipe_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3350,6 +3350,21 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||
|
||||
dc_z10_restore(dc);
|
||||
|
||||
if (update_type == UPDATE_TYPE_FULL) {
|
||||
/* wait for all double-buffer activity to clear on all pipes */
|
||||
int pipe_idx;
|
||||
|
||||
for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
|
||||
|
||||
if (!pipe_ctx->stream)
|
||||
continue;
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear)
|
||||
pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg);
|
||||
}
|
||||
}
|
||||
|
||||
if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) {
|
||||
/* Optimize seamless boot flag keeps clocks and watermarks high until
|
||||
* first flip. After first flip, optimization is required to lower
|
||||
@ -4290,7 +4305,7 @@ void dc_resume(struct dc *dc)
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++)
|
||||
core_link_resume(dc->links[i]);
|
||||
link_resume(dc->links[i]);
|
||||
}
|
||||
|
||||
bool dc_is_dmcu_initialized(struct dc *dc)
|
||||
|
File diff suppressed because it is too large
Load Diff
103
drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
Normal file
103
drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2023 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
/* FILE POLICY AND INTENDED USAGE:
|
||||
* This file provides single entrance to link functionality declared in dc
|
||||
* public headers. The file is intended to be used as a thin translation layer
|
||||
* that directly calls link internal functions without adding new functional
|
||||
* behavior.
|
||||
*
|
||||
* When exporting a new link related dc function, add function declaration in
|
||||
* dc.h with detail interface documentation, then add function implementation
|
||||
* in this file which calls link functions.
|
||||
*/
|
||||
#include "link.h"
|
||||
|
||||
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
|
||||
{
|
||||
return link_detect(link, reason);
|
||||
}
|
||||
|
||||
bool dc_link_detect_connection_type(struct dc_link *link,
|
||||
enum dc_connection_type *type)
|
||||
{
|
||||
return link_detect_connection_type(link, type);
|
||||
}
|
||||
|
||||
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
|
||||
{
|
||||
return link_get_status(link);
|
||||
}
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
|
||||
/* return true if the connected receiver supports the hdcp version */
|
||||
bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal)
|
||||
{
|
||||
return link_is_hdcp14(link, signal);
|
||||
}
|
||||
|
||||
bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
|
||||
{
|
||||
return link_is_hdcp22(link, signal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void dc_link_clear_dprx_states(struct dc_link *link)
|
||||
{
|
||||
link_clear_dprx_states(link);
|
||||
}
|
||||
|
||||
bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link)
|
||||
{
|
||||
return link_reset_cur_dp_mst_topology(link);
|
||||
}
|
||||
|
||||
uint32_t dc_link_bandwidth_kbps(
|
||||
const struct dc_link *link,
|
||||
const struct dc_link_settings *link_settings)
|
||||
{
|
||||
return dp_link_bandwidth_kbps(link, link_settings);
|
||||
}
|
||||
|
||||
uint32_t dc_bandwidth_in_kbps_from_timing(
|
||||
const struct dc_crtc_timing *timing)
|
||||
{
|
||||
return link_timing_bandwidth_kbps(timing);
|
||||
}
|
||||
|
||||
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
|
||||
{
|
||||
link_get_cur_res_map(dc, map);
|
||||
}
|
||||
|
||||
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
|
||||
{
|
||||
link_restore_res_map(dc, map);
|
||||
}
|
||||
|
||||
bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
return link_update_dsc_config(pipe_ctx);
|
||||
}
|
@ -3685,7 +3685,7 @@ enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
|
||||
/* TODO: validate audio ASIC caps, encoder */
|
||||
|
||||
if (res == DC_OK)
|
||||
res = dc_link_validate_mode_timing(stream,
|
||||
res = link_validate_mode_timing(stream,
|
||||
link,
|
||||
&stream->timing);
|
||||
|
||||
|
@ -47,12 +47,11 @@ struct aux_payload;
|
||||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.221"
|
||||
#define DC_VER "3.2.223"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
#define MAX_STREAMS 6
|
||||
#define MAX_SINKS_PER_LINK 4
|
||||
#define MIN_VIEWPORT_SIZE 12
|
||||
#define MAX_NUM_EDP 2
|
||||
|
||||
@ -410,7 +409,7 @@ struct dc_config {
|
||||
bool force_bios_enable_lttpr;
|
||||
uint8_t force_bios_fixed_vs;
|
||||
int sdpif_request_limit_words_per_umc;
|
||||
|
||||
bool disable_subvp_drr;
|
||||
};
|
||||
|
||||
enum visual_confirm {
|
||||
@ -874,6 +873,7 @@ struct dc_debug_options {
|
||||
unsigned int min_prefetch_in_strobe_ns;
|
||||
bool disable_unbounded_requesting;
|
||||
bool dig_fifo_off_in_blank;
|
||||
bool temp_mst_deallocation_sequence;
|
||||
};
|
||||
|
||||
struct gpu_info_soc_bounding_box_v1_0;
|
||||
@ -1371,109 +1371,128 @@ struct dc_state *dc_copy_state(struct dc_state *src_ctx);
|
||||
void dc_retain_state(struct dc_state *context);
|
||||
void dc_release_state(struct dc_state *context);
|
||||
|
||||
/* Link Interfaces */
|
||||
struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
int mpcc_inst);
|
||||
|
||||
struct dpcd_caps {
|
||||
union dpcd_rev dpcd_rev;
|
||||
union max_lane_count max_ln_count;
|
||||
union max_down_spread max_down_spread;
|
||||
union dprx_feature dprx_feature;
|
||||
|
||||
/* valid only for eDP v1.4 or higher*/
|
||||
uint8_t edp_supported_link_rates_count;
|
||||
enum dc_link_rate edp_supported_link_rates[8];
|
||||
|
||||
/* dongle type (DP converter, CV smart dongle) */
|
||||
enum display_dongle_type dongle_type;
|
||||
bool is_dongle_type_one;
|
||||
/* branch device or sink device */
|
||||
bool is_branch_dev;
|
||||
/* Dongle's downstream count. */
|
||||
union sink_count sink_count;
|
||||
bool is_mst_capable;
|
||||
/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
|
||||
indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
|
||||
struct dc_dongle_caps dongle_caps;
|
||||
|
||||
uint32_t sink_dev_id;
|
||||
int8_t sink_dev_id_str[6];
|
||||
int8_t sink_hw_revision;
|
||||
int8_t sink_fw_revision[2];
|
||||
|
||||
uint32_t branch_dev_id;
|
||||
int8_t branch_dev_name[6];
|
||||
int8_t branch_hw_revision;
|
||||
int8_t branch_fw_revision[2];
|
||||
|
||||
bool allow_invalid_MSA_timing_param;
|
||||
bool panel_mode_edp;
|
||||
bool dpcd_display_control_capable;
|
||||
bool ext_receiver_cap_field_present;
|
||||
bool set_power_state_capable_edp;
|
||||
bool dynamic_backlight_capable_edp;
|
||||
union dpcd_fec_capability fec_cap;
|
||||
struct dpcd_dsc_capabilities dsc_caps;
|
||||
struct dc_lttpr_caps lttpr_caps;
|
||||
struct adaptive_sync_caps adaptive_sync_caps;
|
||||
struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;
|
||||
|
||||
union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
|
||||
union dp_main_line_channel_coding_cap channel_coding_cap;
|
||||
union dp_sink_video_fallback_formats fallback_formats;
|
||||
union dp_fec_capability1 fec_cap1;
|
||||
union dp_cable_id cable_id;
|
||||
uint8_t edp_rev;
|
||||
union edp_alpm_caps alpm_caps;
|
||||
struct edp_psr_info psr_info;
|
||||
};
|
||||
|
||||
union dpcd_sink_ext_caps {
|
||||
struct {
|
||||
/* 0 - Sink supports backlight adjust via PWM during SDR/HDR mode
|
||||
* 1 - Sink supports backlight adjust via AUX during SDR/HDR mode.
|
||||
*/
|
||||
uint8_t sdr_aux_backlight_control : 1;
|
||||
uint8_t hdr_aux_backlight_control : 1;
|
||||
uint8_t reserved_1 : 2;
|
||||
uint8_t oled : 1;
|
||||
uint8_t reserved : 3;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||
union hdcp_rx_caps {
|
||||
struct {
|
||||
uint8_t version;
|
||||
uint8_t reserved;
|
||||
struct {
|
||||
uint8_t repeater : 1;
|
||||
uint8_t hdcp_capable : 1;
|
||||
uint8_t reserved : 6;
|
||||
} byte0;
|
||||
} fields;
|
||||
uint8_t raw[3];
|
||||
};
|
||||
|
||||
union hdcp_bcaps {
|
||||
struct {
|
||||
uint8_t HDCP_CAPABLE:1;
|
||||
uint8_t REPEATER:1;
|
||||
uint8_t RESERVED:6;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
struct hdcp_caps {
|
||||
union hdcp_rx_caps rx_caps;
|
||||
union hdcp_bcaps bcaps;
|
||||
};
|
||||
#endif
|
||||
|
||||
#include "dc_link.h"
|
||||
|
||||
uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
|
||||
|
||||
/* Link Interfaces */
|
||||
/* TODO: remove this after resolving external dependencies */
|
||||
#include "dc_link.h"
|
||||
|
||||
/* The function initiates detection handshake over the given link. It first
|
||||
* determines if there are display connections over the link. If so it initiates
|
||||
* detection protocols supported by the connected receiver device. The function
|
||||
* contains protocol specific handshake sequences which are sometimes mandatory
|
||||
* to establish a proper connection between TX and RX. So it is always
|
||||
* recommended to call this function as the first link operation upon HPD event
|
||||
* or power up event. Upon completion, the function will update link structure
|
||||
* in place based on latest RX capabilities. The function may also cause dpms
|
||||
* to be reset to off for all currently enabled streams to the link. It is DM's
|
||||
* responsibility to serialize detection and DPMS updates.
|
||||
*
|
||||
* @reason - Indicate which event triggers this detection. dc may customize
|
||||
* detection flow depending on the triggering events.
|
||||
* return false - if detection is not fully completed. This could happen when
|
||||
* there is an unrecoverable error during detection or detection is partially
|
||||
* completed (detection has been delegated to dm mst manager ie.
|
||||
* link->connection_type == dc_connection_mst_branch when returning false).
|
||||
* return true - detection is completed, link has been fully updated with latest
|
||||
* detection result.
|
||||
*/
|
||||
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason);
|
||||
|
||||
/* determine if there is a sink connected to the link
|
||||
*
|
||||
* @type - dc_connection_single if connected, dc_connection_none otherwise.
|
||||
* return - false if an unexpected error occurs, true otherwise.
|
||||
*
|
||||
* NOTE: This function doesn't detect downstream sink connections i.e
|
||||
* dc_connection_mst_branch, dc_connection_sst_branch. In this case, it will
|
||||
* return dc_connection_single if the branch device is connected despite of
|
||||
* downstream sink's connection status.
|
||||
*/
|
||||
bool dc_link_detect_connection_type(struct dc_link *link,
|
||||
enum dc_connection_type *type);
|
||||
|
||||
/* Getter for cached link status from given link */
|
||||
const struct dc_link_status *dc_link_get_status(const struct dc_link *link);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
/* return true if the connected receiver supports the hdcp version */
|
||||
bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal);
|
||||
bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal);
|
||||
#endif
|
||||
|
||||
/* The function clears recorded DP RX states in the link. DM should call this
|
||||
* function when it is resuming from S3 power state to previously connected links.
|
||||
*
|
||||
* TODO - in the future we should consider to expand link resume interface to
|
||||
* support clearing previous rx states. So we don't have to rely on dm to call
|
||||
* this interface explicitly.
|
||||
*/
|
||||
void dc_link_clear_dprx_states(struct dc_link *link);
|
||||
|
||||
/* Destruct the mst topology of the link and reset the allocated payload table
|
||||
*
|
||||
* NOTE: this should only be called if DM chooses not to call dc_link_detect but
|
||||
* still wants to reset MST topology on an unplug event */
|
||||
bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link);
|
||||
|
||||
/* The function calculates effective DP link bandwidth when a given link is
|
||||
* using the given link settings.
|
||||
*
|
||||
* return - total effective link bandwidth in kbps.
|
||||
*/
|
||||
uint32_t dc_link_bandwidth_kbps(
|
||||
const struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting);
|
||||
|
||||
/* The function returns minimum bandwidth required to drive a given timing
|
||||
* return - minimum required timing bandwidth in kbps.
|
||||
*/
|
||||
uint32_t dc_bandwidth_in_kbps_from_timing(
|
||||
const struct dc_crtc_timing *timing);
|
||||
|
||||
/* The function takes a snapshot of current link resource allocation state
|
||||
* @dc: pointer to dc of the dm calling this
|
||||
* @map: a dc link resource snapshot defined internally to dc.
|
||||
*
|
||||
* DM needs to capture a snapshot of current link resource allocation mapping
|
||||
* and store it in its persistent storage.
|
||||
*
|
||||
* Some of the link resource is using first come first serve policy.
|
||||
* The allocation mapping depends on original hotplug order. This information
|
||||
* is lost after driver is loaded next time. The snapshot is used in order to
|
||||
* restore link resource to its previous state so user will get consistent
|
||||
* link capability allocation across reboot.
|
||||
*
|
||||
*/
|
||||
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map);
|
||||
|
||||
/* This function restores link resource allocation state from a snapshot
|
||||
* @dc: pointer to dc of the dm calling this
|
||||
* @map: a dc link resource snapshot defined internally to dc.
|
||||
*
|
||||
* DM needs to call this function after initial link detection on boot and
|
||||
* before first commit streams to restore link resource allocation state
|
||||
* from previous boot session.
|
||||
*
|
||||
* Some of the link resource is using first come first serve policy.
|
||||
* The allocation mapping depends on original hotplug order. This information
|
||||
* is lost after driver is loaded next time. The snapshot is used in order to
|
||||
* restore link resource to its previous state so user will get consistent
|
||||
* link capability allocation across reboot.
|
||||
*
|
||||
*/
|
||||
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
|
||||
|
||||
/* TODO: this is not meant to be exposed to DM. Should switch to stream update
|
||||
* interface i.e stream_update->dsc_config
|
||||
*/
|
||||
bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
/* Sink Interfaces - A sink corresponds to a display output device */
|
||||
|
||||
struct dc_container_id {
|
||||
@ -1505,6 +1524,11 @@ struct dc_sink_fec_caps {
|
||||
bool is_topology_fec_supported;
|
||||
};
|
||||
|
||||
struct scdc_caps {
|
||||
union hdmi_scdc_manufacturer_OUI_data manufacturer_OUI;
|
||||
union hdmi_scdc_device_id_data device_id;
|
||||
};
|
||||
|
||||
/*
|
||||
* The sink structure contains EDID and other display device properties
|
||||
*/
|
||||
@ -1518,6 +1542,7 @@ struct dc_sink {
|
||||
struct stereo_3d_features features_3d[TIMING_3D_FORMAT_MAX];
|
||||
bool converter_disable_audio;
|
||||
|
||||
struct scdc_caps scdc_caps;
|
||||
struct dc_sink_dsc_caps dsc_caps;
|
||||
struct dc_sink_fec_caps fec_caps;
|
||||
|
||||
|
@ -178,6 +178,9 @@ enum display_dongle_type {
|
||||
DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE,
|
||||
};
|
||||
|
||||
#define DC_MAX_EDID_BUFFER_SIZE 2048
|
||||
#define DC_EDID_BLOCK_SIZE 128
|
||||
|
||||
struct ddc_service {
|
||||
struct ddc *ddc_pin;
|
||||
struct ddc_flags flags;
|
||||
|
@ -698,7 +698,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
|
||||
*
|
||||
* @dc: [in] current dc state
|
||||
* @context: [in] new dc state
|
||||
* @cmd: [in] DMUB cmd to be populated with SubVP info
|
||||
* @enable: [in] if true enables the pipes population
|
||||
*
|
||||
* This function loops through each pipe and populates the DMUB SubVP CMD info
|
||||
* based on the pipe (e.g. SubVP, VBLANK).
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define DC_DP_TYPES_H
|
||||
|
||||
#include "os_types.h"
|
||||
#include "dc_ddc_types.h"
|
||||
|
||||
enum dc_lane_count {
|
||||
LANE_COUNT_UNKNOWN = 0,
|
||||
@ -1125,4 +1126,139 @@ struct edp_psr_info {
|
||||
uint8_t force_psrsu_cap;
|
||||
};
|
||||
|
||||
struct dprx_states {
|
||||
bool cable_id_written;
|
||||
};
|
||||
|
||||
enum dpcd_downstream_port_max_bpc {
|
||||
DOWN_STREAM_MAX_8BPC = 0,
|
||||
DOWN_STREAM_MAX_10BPC,
|
||||
DOWN_STREAM_MAX_12BPC,
|
||||
DOWN_STREAM_MAX_16BPC
|
||||
};
|
||||
|
||||
enum link_training_offset {
|
||||
DPRX = 0,
|
||||
LTTPR_PHY_REPEATER1 = 1,
|
||||
LTTPR_PHY_REPEATER2 = 2,
|
||||
LTTPR_PHY_REPEATER3 = 3,
|
||||
LTTPR_PHY_REPEATER4 = 4,
|
||||
LTTPR_PHY_REPEATER5 = 5,
|
||||
LTTPR_PHY_REPEATER6 = 6,
|
||||
LTTPR_PHY_REPEATER7 = 7,
|
||||
LTTPR_PHY_REPEATER8 = 8
|
||||
};
|
||||
|
||||
#define MAX_REPEATER_CNT 8
|
||||
|
||||
struct dc_lttpr_caps {
|
||||
union dpcd_rev revision;
|
||||
uint8_t mode;
|
||||
uint8_t max_lane_count;
|
||||
uint8_t max_link_rate;
|
||||
uint8_t phy_repeater_cnt;
|
||||
uint8_t max_ext_timeout;
|
||||
union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
|
||||
union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
|
||||
uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
|
||||
};
|
||||
|
||||
struct dc_dongle_dfp_cap_ext {
|
||||
bool supported;
|
||||
uint16_t max_pixel_rate_in_mps;
|
||||
uint16_t max_video_h_active_width;
|
||||
uint16_t max_video_v_active_height;
|
||||
struct dp_encoding_format_caps encoding_format_caps;
|
||||
struct dp_color_depth_caps rgb_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr444_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr422_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr420_color_depth_caps;
|
||||
};
|
||||
|
||||
struct dc_dongle_caps {
|
||||
/* dongle type (DP converter, CV smart dongle) */
|
||||
enum display_dongle_type dongle_type;
|
||||
bool extendedCapValid;
|
||||
/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
|
||||
indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
|
||||
bool is_dp_hdmi_s3d_converter;
|
||||
bool is_dp_hdmi_ycbcr422_pass_through;
|
||||
bool is_dp_hdmi_ycbcr420_pass_through;
|
||||
bool is_dp_hdmi_ycbcr422_converter;
|
||||
bool is_dp_hdmi_ycbcr420_converter;
|
||||
uint32_t dp_hdmi_max_bpc;
|
||||
uint32_t dp_hdmi_max_pixel_clk_in_khz;
|
||||
uint32_t dp_hdmi_frl_max_link_bw_in_kbps;
|
||||
struct dc_dongle_dfp_cap_ext dfp_cap_ext;
|
||||
};
|
||||
|
||||
struct dpcd_caps {
|
||||
union dpcd_rev dpcd_rev;
|
||||
union max_lane_count max_ln_count;
|
||||
union max_down_spread max_down_spread;
|
||||
union dprx_feature dprx_feature;
|
||||
|
||||
/* valid only for eDP v1.4 or higher*/
|
||||
uint8_t edp_supported_link_rates_count;
|
||||
enum dc_link_rate edp_supported_link_rates[8];
|
||||
|
||||
/* dongle type (DP converter, CV smart dongle) */
|
||||
enum display_dongle_type dongle_type;
|
||||
bool is_dongle_type_one;
|
||||
/* branch device or sink device */
|
||||
bool is_branch_dev;
|
||||
/* Dongle's downstream count. */
|
||||
union sink_count sink_count;
|
||||
bool is_mst_capable;
|
||||
/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
|
||||
indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
|
||||
struct dc_dongle_caps dongle_caps;
|
||||
|
||||
uint32_t sink_dev_id;
|
||||
int8_t sink_dev_id_str[6];
|
||||
int8_t sink_hw_revision;
|
||||
int8_t sink_fw_revision[2];
|
||||
|
||||
uint32_t branch_dev_id;
|
||||
int8_t branch_dev_name[6];
|
||||
int8_t branch_hw_revision;
|
||||
int8_t branch_fw_revision[2];
|
||||
|
||||
bool allow_invalid_MSA_timing_param;
|
||||
bool panel_mode_edp;
|
||||
bool dpcd_display_control_capable;
|
||||
bool ext_receiver_cap_field_present;
|
||||
bool set_power_state_capable_edp;
|
||||
bool dynamic_backlight_capable_edp;
|
||||
union dpcd_fec_capability fec_cap;
|
||||
struct dpcd_dsc_capabilities dsc_caps;
|
||||
struct dc_lttpr_caps lttpr_caps;
|
||||
struct adaptive_sync_caps adaptive_sync_caps;
|
||||
struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;
|
||||
|
||||
union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
|
||||
union dp_main_line_channel_coding_cap channel_coding_cap;
|
||||
union dp_sink_video_fallback_formats fallback_formats;
|
||||
union dp_fec_capability1 fec_cap1;
|
||||
union dp_cable_id cable_id;
|
||||
uint8_t edp_rev;
|
||||
union edp_alpm_caps alpm_caps;
|
||||
struct edp_psr_info psr_info;
|
||||
};
|
||||
|
||||
union dpcd_sink_ext_caps {
|
||||
struct {
|
||||
/* 0 - Sink supports backlight adjust via PWM during SDR/HDR mode
|
||||
* 1 - Sink supports backlight adjust via AUX during SDR/HDR mode.
|
||||
*/
|
||||
uint8_t sdr_aux_backlight_control : 1;
|
||||
uint8_t hdr_aux_backlight_control : 1;
|
||||
uint8_t reserved_1 : 2;
|
||||
uint8_t oled : 1;
|
||||
uint8_t reserved_2 : 1;
|
||||
uint8_t miniled : 1;
|
||||
uint8_t reserved : 1;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
#endif /* DC_DP_TYPES_H */
|
||||
|
@ -69,6 +69,9 @@ static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR";
|
||||
#define HDMI_SCDC_ERR_DETECT 0x50
|
||||
#define HDMI_SCDC_TEST_CONFIG 0xC0
|
||||
|
||||
#define HDMI_SCDC_MANUFACTURER_OUI 0xD0
|
||||
#define HDMI_SCDC_DEVICE_ID 0xDB
|
||||
|
||||
union hdmi_scdc_update_read_data {
|
||||
uint8_t byte[2];
|
||||
struct {
|
||||
@ -111,4 +114,21 @@ union hdmi_scdc_ced_data {
|
||||
} fields;
|
||||
};
|
||||
|
||||
union hdmi_scdc_manufacturer_OUI_data {
|
||||
uint8_t byte[3];
|
||||
struct {
|
||||
uint8_t Manufacturer_OUI_1:8;
|
||||
uint8_t Manufacturer_OUI_2:8;
|
||||
uint8_t Manufacturer_OUI_3:8;
|
||||
} fields;
|
||||
};
|
||||
|
||||
union hdmi_scdc_device_id_data {
|
||||
uint8_t byte;
|
||||
struct {
|
||||
uint8_t Hardware_Minor_Rev:4;
|
||||
uint8_t Hardware_Major_Rev:4;
|
||||
} fields;
|
||||
};
|
||||
|
||||
#endif /* DC_HDMI_TYPES_H */
|
||||
|
@ -39,15 +39,6 @@ enum dc_link_fec_state {
|
||||
dc_link_fec_enabled
|
||||
};
|
||||
|
||||
struct dc_link_status {
|
||||
bool link_active;
|
||||
struct dpcd_caps *dpcd_caps;
|
||||
};
|
||||
|
||||
struct dprx_states {
|
||||
bool cable_id_written;
|
||||
};
|
||||
|
||||
/* DP MST stream allocation (payload bandwidth number) */
|
||||
struct link_mst_stream_allocation {
|
||||
/* DIG front */
|
||||
@ -102,6 +93,7 @@ struct psr_settings {
|
||||
bool psr_allow_active; // PSR is currently active
|
||||
enum dc_psr_version psr_version; // Internal PSR version, determined based on DPCD
|
||||
bool psr_vtotal_control_support; // Vtotal control is supported by sink
|
||||
unsigned long long psr_dirty_rects_change_timestamp_ns; // for delay of enabling PSR-SU
|
||||
|
||||
/* These parameters are calculated in Driver,
|
||||
* based on display timing and Sink capabilities.
|
||||
@ -166,6 +158,8 @@ struct dc_dpia_bw_alloc {
|
||||
bool response_ready; // Response ready from the CM side
|
||||
};
|
||||
|
||||
#define MAX_SINKS_PER_LINK 4
|
||||
|
||||
/*
|
||||
* A link contains one or more sinks and their connected status.
|
||||
* The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
|
||||
@ -301,7 +295,6 @@ struct dc_link {
|
||||
struct phy_state phy_state;
|
||||
};
|
||||
|
||||
const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link);
|
||||
|
||||
/**
|
||||
* dc_get_link_at_index() - Return an enumerated dc_link.
|
||||
@ -384,32 +377,7 @@ bool dc_link_setup_psr(struct dc_link *dc_link,
|
||||
const struct dc_stream_state *stream, struct psr_config *psr_config,
|
||||
struct psr_context *psr_context);
|
||||
|
||||
void dc_link_blank_all_dp_displays(struct dc *dc);
|
||||
void dc_link_blank_all_edp_displays(struct dc *dc);
|
||||
|
||||
void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init);
|
||||
|
||||
/* Request DC to detect if there is a Panel connected.
|
||||
* boot - If this call is during initial boot.
|
||||
* Return false for any type of detection failure or MST detection
|
||||
* true otherwise. True meaning further action is required (status update
|
||||
* and OS notification).
|
||||
*/
|
||||
enum dc_detect_reason {
|
||||
DETECT_REASON_BOOT,
|
||||
DETECT_REASON_RESUMEFROMS3S4,
|
||||
DETECT_REASON_HPD,
|
||||
DETECT_REASON_HPDRX,
|
||||
DETECT_REASON_FALLBACK,
|
||||
DETECT_REASON_RETRAIN,
|
||||
DETECT_REASON_TDR,
|
||||
};
|
||||
|
||||
bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
|
||||
bool dc_link_get_hpd_state(struct dc_link *dc_link);
|
||||
enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
|
||||
enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
|
||||
enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
|
||||
|
||||
/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
|
||||
* Return:
|
||||
@ -432,8 +400,8 @@ void dc_link_dp_handle_automated_test(struct dc_link *link);
|
||||
void dc_link_dp_handle_link_loss(struct dc_link *link);
|
||||
bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link);
|
||||
bool dc_link_check_link_loss_status(struct dc_link *link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data);
|
||||
enum dc_status dp_read_hpd_rx_irq_data(
|
||||
union hpd_irq_data *hpd_irq_dpcd_data);
|
||||
enum dc_status dc_link_dp_read_hpd_rx_irq_data(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *irq_data);
|
||||
struct dc_sink_init_data;
|
||||
@ -478,16 +446,10 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_
|
||||
void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
|
||||
|
||||
bool dc_link_is_dp_sink_present(struct dc_link *link);
|
||||
|
||||
bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type);
|
||||
/*
|
||||
* DPCD access interfaces
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal);
|
||||
bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal);
|
||||
#endif
|
||||
void dc_link_set_drive_settings(struct dc *dc,
|
||||
struct link_training_settings *lt_settings,
|
||||
const struct dc_link *link);
|
||||
@ -507,9 +469,6 @@ void dc_link_set_test_pattern(struct dc_link *link,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size);
|
||||
uint32_t dc_link_bandwidth_kbps(
|
||||
const struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting);
|
||||
|
||||
const struct dc_link_settings *dc_link_get_link_cap(
|
||||
const struct dc_link *link);
|
||||
@ -531,22 +490,16 @@ bool dc_submit_i2c_oem(
|
||||
struct dc *dc,
|
||||
struct i2c_command *cmd);
|
||||
|
||||
uint32_t dc_bandwidth_in_kbps_from_timing(
|
||||
const struct dc_crtc_timing *timing);
|
||||
|
||||
bool dc_link_is_fec_supported(const struct dc_link *link);
|
||||
bool dc_link_should_enable_fec(const struct dc_link *link);
|
||||
|
||||
uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw);
|
||||
enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
|
||||
|
||||
void dc_link_get_cur_link_res(const struct dc_link *link,
|
||||
struct link_resource *link_res);
|
||||
/* take a snapshot of current link resource allocation state */
|
||||
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map);
|
||||
/* restore link resource allocation state from a snapshot */
|
||||
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
|
||||
void dc_link_clear_dprx_states(struct dc_link *link);
|
||||
void dp_trace_reset(struct dc_link *link);
|
||||
bool dc_dp_trace_is_initialized(struct dc_link *link);
|
||||
unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link,
|
||||
@ -560,9 +513,6 @@ struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link,
|
||||
bool in_detection);
|
||||
unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link);
|
||||
|
||||
/* Destruct the mst topology of the link and reset the allocated payload table */
|
||||
bool reset_cur_dp_mst_topology(struct dc_link *link);
|
||||
|
||||
/* Attempt to transfer the given aux payload. This function does not perform
|
||||
* retries or handle error states. The reply is returned in the payload->reply
|
||||
* and the result through operation_result. Returns the number of bytes
|
||||
@ -581,55 +531,6 @@ bool dc_link_decide_edp_link_settings(struct dc_link *link,
|
||||
void dc_link_edp_panel_backlight_power_on(struct dc_link *link,
|
||||
bool wait_for_hpd);
|
||||
|
||||
#define LINK_TRAINING_ATTEMPTS 4
|
||||
#define LINK_TRAINING_RETRY_DELAY 50 /* ms */
|
||||
#define MAX_MTP_SLOT_COUNT 64
|
||||
#define TRAINING_AUX_RD_INTERVAL 100 //us
|
||||
#define LINK_AUX_WAKE_TIMEOUT_MS 1500 // Timeout when trying to wake unresponsive DPRX.
|
||||
|
||||
struct dc_link;
|
||||
struct dc_stream_state;
|
||||
struct dc_link_settings;
|
||||
|
||||
enum {
|
||||
/*
|
||||
* Some receivers fail to train on first try and are good
|
||||
* on subsequent tries. 2 retries should be plenty. If we
|
||||
* don't have a successful training then we don't expect to
|
||||
* ever get one.
|
||||
*/
|
||||
LINK_TRAINING_MAX_VERIFY_RETRY = 2,
|
||||
PEAK_FACTOR_X1000 = 1006,
|
||||
};
|
||||
|
||||
bool dp_validate_mode_timing(
|
||||
struct dc_link *link,
|
||||
const struct dc_crtc_timing *timing);
|
||||
|
||||
void dp_enable_mst_on_sink(struct dc_link *link, bool enable);
|
||||
|
||||
enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready);
|
||||
void dp_set_fec_enable(struct dc_link *link, bool enable);
|
||||
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update);
|
||||
void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
|
||||
bool dpcd_write_128b_132b_sst_payload_allocation_table(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
struct link_mst_stream_allocation_table *proposed_table,
|
||||
bool allocate);
|
||||
|
||||
bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link);
|
||||
|
||||
struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
|
||||
const struct dc_stream_state *stream,
|
||||
const struct dc_link *link);
|
||||
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
|
||||
|
||||
/*
|
||||
* USB4 DPIA BW ALLOCATION PUBLIC FUNCTIONS
|
||||
*/
|
||||
@ -657,4 +558,20 @@ void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw);
|
||||
*/
|
||||
void dc_link_get_usb4_req_bw_resp(struct dc_link *link, uint8_t bw, uint8_t result);
|
||||
|
||||
/*
|
||||
* Handle the USB4 BW Allocation related functionality here:
|
||||
* Plug => Try to allocate max bw from timing parameters supported by the sink
|
||||
* Unplug => de-allocate bw
|
||||
*
|
||||
* @link: pointer to the dc_link struct instance
|
||||
* @peak_bw: Peak bw used by the link/sink
|
||||
*
|
||||
* return: allocated bw else return 0
|
||||
*/
|
||||
int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int peak_bw);
|
||||
|
||||
/* TODO: this is not meant to be exposed to DM. Should switch to stream update
|
||||
* interface i.e stream_update->dsc_config
|
||||
*/
|
||||
bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
#endif /* DC_LINK_H_ */
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "os_types.h"
|
||||
#include "fixed31_32.h"
|
||||
#include "irq_types.h"
|
||||
#include "dc_ddc_types.h"
|
||||
#include "dc_dp_types.h"
|
||||
#include "dc_hdmi_types.h"
|
||||
#include "dc_hw_types.h"
|
||||
@ -83,13 +84,8 @@ struct dc_perf_trace {
|
||||
unsigned long last_entry_write;
|
||||
};
|
||||
|
||||
#define DC_MAX_EDID_BUFFER_SIZE 2048
|
||||
#define DC_EDID_BLOCK_SIZE 128
|
||||
#define MAX_SURFACE_NUM 4
|
||||
#define NUM_PIXEL_FORMATS 10
|
||||
#define MAX_REPEATER_CNT 8
|
||||
|
||||
#include "dc_ddc_types.h"
|
||||
|
||||
enum tiling_mode {
|
||||
TILING_MODE_INVALID,
|
||||
@ -375,66 +371,6 @@ struct dc_csc_adjustments {
|
||||
struct fixed31_32 hue;
|
||||
};
|
||||
|
||||
enum dpcd_downstream_port_max_bpc {
|
||||
DOWN_STREAM_MAX_8BPC = 0,
|
||||
DOWN_STREAM_MAX_10BPC,
|
||||
DOWN_STREAM_MAX_12BPC,
|
||||
DOWN_STREAM_MAX_16BPC
|
||||
};
|
||||
|
||||
|
||||
enum link_training_offset {
|
||||
DPRX = 0,
|
||||
LTTPR_PHY_REPEATER1 = 1,
|
||||
LTTPR_PHY_REPEATER2 = 2,
|
||||
LTTPR_PHY_REPEATER3 = 3,
|
||||
LTTPR_PHY_REPEATER4 = 4,
|
||||
LTTPR_PHY_REPEATER5 = 5,
|
||||
LTTPR_PHY_REPEATER6 = 6,
|
||||
LTTPR_PHY_REPEATER7 = 7,
|
||||
LTTPR_PHY_REPEATER8 = 8
|
||||
};
|
||||
|
||||
struct dc_lttpr_caps {
|
||||
union dpcd_rev revision;
|
||||
uint8_t mode;
|
||||
uint8_t max_lane_count;
|
||||
uint8_t max_link_rate;
|
||||
uint8_t phy_repeater_cnt;
|
||||
uint8_t max_ext_timeout;
|
||||
union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
|
||||
union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
|
||||
uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
|
||||
};
|
||||
|
||||
struct dc_dongle_dfp_cap_ext {
|
||||
bool supported;
|
||||
uint16_t max_pixel_rate_in_mps;
|
||||
uint16_t max_video_h_active_width;
|
||||
uint16_t max_video_v_active_height;
|
||||
struct dp_encoding_format_caps encoding_format_caps;
|
||||
struct dp_color_depth_caps rgb_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr444_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr422_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr420_color_depth_caps;
|
||||
};
|
||||
|
||||
struct dc_dongle_caps {
|
||||
/* dongle type (DP converter, CV smart dongle) */
|
||||
enum display_dongle_type dongle_type;
|
||||
bool extendedCapValid;
|
||||
/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
|
||||
indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
|
||||
bool is_dp_hdmi_s3d_converter;
|
||||
bool is_dp_hdmi_ycbcr422_pass_through;
|
||||
bool is_dp_hdmi_ycbcr420_pass_through;
|
||||
bool is_dp_hdmi_ycbcr422_converter;
|
||||
bool is_dp_hdmi_ycbcr420_converter;
|
||||
uint32_t dp_hdmi_max_bpc;
|
||||
uint32_t dp_hdmi_max_pixel_clk_in_khz;
|
||||
uint32_t dp_hdmi_frl_max_link_bw_in_kbps;
|
||||
struct dc_dongle_dfp_cap_ext dfp_cap_ext;
|
||||
};
|
||||
/* Scaling format */
|
||||
enum scaling_transformation {
|
||||
SCALING_TRANSFORMATION_UNINITIALIZED,
|
||||
@ -1003,4 +939,47 @@ struct otg_phy_mux {
|
||||
};
|
||||
#endif
|
||||
|
||||
enum dc_detect_reason {
|
||||
DETECT_REASON_BOOT,
|
||||
DETECT_REASON_RESUMEFROMS3S4,
|
||||
DETECT_REASON_HPD,
|
||||
DETECT_REASON_HPDRX,
|
||||
DETECT_REASON_FALLBACK,
|
||||
DETECT_REASON_RETRAIN,
|
||||
DETECT_REASON_TDR,
|
||||
};
|
||||
|
||||
struct dc_link_status {
|
||||
bool link_active;
|
||||
struct dpcd_caps *dpcd_caps;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||
union hdcp_rx_caps {
|
||||
struct {
|
||||
uint8_t version;
|
||||
uint8_t reserved;
|
||||
struct {
|
||||
uint8_t repeater : 1;
|
||||
uint8_t hdcp_capable : 1;
|
||||
uint8_t reserved : 6;
|
||||
} byte0;
|
||||
} fields;
|
||||
uint8_t raw[3];
|
||||
};
|
||||
|
||||
union hdcp_bcaps {
|
||||
struct {
|
||||
uint8_t HDCP_CAPABLE:1;
|
||||
uint8_t REPEATER:1;
|
||||
uint8_t RESERVED:6;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
struct hdcp_caps {
|
||||
union hdcp_rx_caps rx_caps;
|
||||
union hdcp_bcaps bcaps;
|
||||
};
|
||||
#endif
|
||||
#endif /* DC_TYPES_H_ */
|
||||
|
@ -1566,10 +1566,10 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
||||
pipe_ctx->stream_res.tg->inst);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
|
||||
|
||||
if (!stream->dpms_off)
|
||||
core_link_enable_stream(context, pipe_ctx);
|
||||
link_set_dpms_on(context, pipe_ctx);
|
||||
|
||||
/* DCN3.1 FPGA Workaround
|
||||
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
|
||||
@ -1602,7 +1602,7 @@ static void power_down_encoders(struct dc *dc)
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
enum signal_type signal = dc->links[i]->connector_signal;
|
||||
|
||||
dc_link_blank_dp_stream(dc->links[i], false);
|
||||
link_blank_dp_stream(dc->links[i], false);
|
||||
|
||||
if (signal != SIGNAL_TYPE_EDP)
|
||||
signal = SIGNAL_TYPE_NONE;
|
||||
@ -2085,7 +2085,7 @@ static void dce110_reset_hw_ctx_wrap(
|
||||
* disabled already, no need to disable again.
|
||||
*/
|
||||
if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) {
|
||||
core_link_disable_stream(pipe_ctx_old);
|
||||
link_set_dpms_off(pipe_ctx_old);
|
||||
|
||||
/* free acquired resources*/
|
||||
if (pipe_ctx_old->stream_res.audio) {
|
||||
@ -3079,7 +3079,7 @@ void dce110_enable_dp_link_output(
|
||||
if (dmcu != NULL && dmcu->funcs->unlock_phy)
|
||||
dmcu->funcs->unlock_phy(dmcu);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
|
||||
}
|
||||
|
||||
void dce110_disable_link_output(struct dc_link *link,
|
||||
@ -3104,7 +3104,7 @@ void dce110_disable_link_output(struct dc_link *link,
|
||||
link->dc->hwss.edp_power_control(link, false);
|
||||
else if (dmcu != NULL && dmcu->funcs->lock_phy)
|
||||
dmcu->funcs->unlock_phy(dmcu);
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
|
||||
}
|
||||
|
||||
static const struct hw_sequencer_funcs dce110_funcs = {
|
||||
|
@ -581,7 +581,7 @@ static void dpp1_dscl_set_manual_ratio_init(
|
||||
* dpp1_dscl_set_recout - Set the first pixel of RECOUT in the OTG active area
|
||||
*
|
||||
* @dpp: DPP data struct
|
||||
* @recount: Rectangle information
|
||||
* @recout: Rectangle information
|
||||
*
|
||||
* This function sets the MPC RECOUT_START and RECOUT_SIZE registers based on
|
||||
* the values specified in the recount parameter.
|
||||
|
@ -1017,7 +1017,7 @@ static void dcn10_reset_back_end_for_pipe(
|
||||
* VBIOS lit up eDP, so check link status too.
|
||||
*/
|
||||
if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
|
||||
core_link_disable_stream(pipe_ctx);
|
||||
link_set_dpms_off(pipe_ctx);
|
||||
else if (pipe_ctx->stream_res.audio)
|
||||
dc->hwss.disable_audio_stream(pipe_ctx);
|
||||
|
||||
@ -1564,7 +1564,7 @@ void dcn10_init_hw(struct dc *dc)
|
||||
}
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
dc_link_blank_all_dp_displays(dc);
|
||||
link_blank_all_dp_displays(dc);
|
||||
|
||||
if (hws->funcs.enable_power_gating_plane)
|
||||
hws->funcs.enable_power_gating_plane(dc->hwseq, true);
|
||||
@ -3223,12 +3223,16 @@ static void dcn10_config_stereo_parameters(
|
||||
timing_3d_format == TIMING_3D_FORMAT_INBAND_FA ||
|
||||
timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
|
||||
timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
|
||||
enum display_dongle_type dongle = \
|
||||
stream->link->ddc->dongle_type;
|
||||
if (dongle == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
|
||||
dongle == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
|
||||
dongle == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
|
||||
flags->DISABLE_STEREO_DP_SYNC = 1;
|
||||
|
||||
if (stream->link && stream->link->ddc) {
|
||||
enum display_dongle_type dongle = \
|
||||
stream->link->ddc->dongle_type;
|
||||
|
||||
if (dongle == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
|
||||
dongle == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
|
||||
dongle == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
|
||||
flags->DISABLE_STEREO_DP_SYNC = 1;
|
||||
}
|
||||
}
|
||||
flags->RIGHT_EYE_POLARITY =\
|
||||
stream->timing.flags.RIGHT_EYE_3D_POLARITY;
|
||||
@ -3624,7 +3628,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
||||
(int)hubp->curs_attr.width || pos_cpy.x
|
||||
<= (int)hubp->curs_attr.width +
|
||||
pipe_ctx->plane_state->src_rect.x) {
|
||||
pos_cpy.x = temp_x + viewport_width;
|
||||
pos_cpy.x = 2 * viewport_width - temp_x;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -519,7 +519,8 @@ struct dcn_optc_registers {
|
||||
type OTG_CRC_DATA_STREAM_COMBINE_MODE;\
|
||||
type OTG_CRC_DATA_STREAM_SPLIT_MODE;\
|
||||
type OTG_CRC_DATA_FORMAT;\
|
||||
type OTG_V_TOTAL_LAST_USED_BY_DRR;
|
||||
type OTG_V_TOTAL_LAST_USED_BY_DRR;\
|
||||
type OTG_DRR_TIMING_DBUF_UPDATE_PENDING;
|
||||
|
||||
#define TG_REG_FIELD_LIST_DCN3_2(type) \
|
||||
type OTG_H_TIMING_DIV_MODE_MANUAL;
|
||||
|
@ -933,7 +933,7 @@ void enc1_stream_encoder_dp_blank(
|
||||
/* disable DP stream */
|
||||
REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM);
|
||||
|
||||
/* the encoder stops sending the video stream
|
||||
* at the start of the vertical blanking.
|
||||
@ -952,7 +952,7 @@ void enc1_stream_encoder_dp_blank(
|
||||
|
||||
REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, true);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET);
|
||||
}
|
||||
|
||||
/* output video stream to link encoder */
|
||||
@ -1025,7 +1025,7 @@ void enc1_stream_encoder_dp_unblank(
|
||||
|
||||
REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
}
|
||||
|
||||
void enc1_stream_encoder_set_avmute(
|
||||
|
@ -1826,15 +1826,17 @@ void dcn20_program_front_end_for_ctx(
|
||||
/* When disabling phantom pipes, turn on phantom OTG first (so we can get double
|
||||
* buffer updates properly)
|
||||
*/
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
|
||||
&& dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct dc_stream_state *stream = dc->current_state->res_ctx.pipe_ctx[i].stream;
|
||||
|
||||
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable && stream &&
|
||||
dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
|
||||
|
||||
if (tg->funcs->enable_crtc)
|
||||
tg->funcs->enable_crtc(tg);
|
||||
}
|
||||
|
||||
}
|
||||
/* OTG blank before disabling all front ends */
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
|
||||
@ -2447,7 +2449,7 @@ static void dcn20_reset_back_end_for_pipe(
|
||||
* VBIOS lit up eDP, so check link status too.
|
||||
*/
|
||||
if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
|
||||
core_link_disable_stream(pipe_ctx);
|
||||
link_set_dpms_off(pipe_ctx);
|
||||
else if (pipe_ctx->stream_res.audio)
|
||||
dc->hwss.disable_audio_stream(pipe_ctx);
|
||||
|
||||
@ -2467,7 +2469,7 @@ static void dcn20_reset_back_end_for_pipe(
|
||||
}
|
||||
}
|
||||
else if (pipe_ctx->stream_res.dsc) {
|
||||
dp_set_dsc_enable(pipe_ctx, false);
|
||||
link_set_dsc_enable(pipe_ctx, false);
|
||||
}
|
||||
|
||||
/* by upper caller loop, parent pipe: pipe0, will be reset last.
|
||||
@ -2741,7 +2743,7 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
||||
dc->hwss.update_info_frame(pipe_ctx);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
|
||||
|
||||
/* enable early control to avoid corruption on DP monitor*/
|
||||
active_total_with_borders =
|
||||
|
@ -546,7 +546,7 @@ void enc2_stream_encoder_dp_unblank(
|
||||
|
||||
REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
}
|
||||
|
||||
static void enc2_dp_set_odm_combine(
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "hw/clk_mgr.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "abm.h"
|
||||
|
||||
#include "link.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
@ -132,8 +132,8 @@ void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx)
|
||||
return;
|
||||
|
||||
pipe_ctx->stream->dpms_off = false;
|
||||
core_link_enable_stream(context, pipe_ctx);
|
||||
core_link_disable_stream(pipe_ctx);
|
||||
link_set_dpms_on(context, pipe_ctx);
|
||||
link_set_dpms_off(pipe_ctx);
|
||||
pipe_ctx->stream->dpms_off = true;
|
||||
}
|
||||
|
||||
|
@ -90,8 +90,8 @@ bool dcn30_set_blend_lut(
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool dcn30_set_mpc_shaper_3dlut(
|
||||
struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
|
||||
static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
|
||||
const struct dc_stream_state *stream)
|
||||
{
|
||||
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
|
||||
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
|
||||
@ -103,19 +103,18 @@ static bool dcn30_set_mpc_shaper_3dlut(
|
||||
const struct pwl_params *shaper_lut = NULL;
|
||||
//get the shaper lut params
|
||||
if (stream->func_shaper) {
|
||||
if (stream->func_shaper->type == TF_TYPE_HWPWL)
|
||||
if (stream->func_shaper->type == TF_TYPE_HWPWL) {
|
||||
shaper_lut = &stream->func_shaper->pwl;
|
||||
else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
|
||||
cm_helper_translate_curve_to_hw_format(
|
||||
stream->func_shaper,
|
||||
&dpp_base->shaper_params, true);
|
||||
} else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
|
||||
cm_helper_translate_curve_to_hw_format(stream->func_shaper,
|
||||
&dpp_base->shaper_params, true);
|
||||
shaper_lut = &dpp_base->shaper_params;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->lut3d_func &&
|
||||
stream->lut3d_func->state.bits.initialized == 1 &&
|
||||
stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
|
||||
stream->lut3d_func->state.bits.initialized == 1 &&
|
||||
stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
|
||||
if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
|
||||
mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux;
|
||||
else if (stream->lut3d_func->state.bits.rmu_mux_num == 1)
|
||||
@ -124,20 +123,22 @@ static bool dcn30_set_mpc_shaper_3dlut(
|
||||
mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu2_mux;
|
||||
if (mpcc_id_projected != mpcc_id)
|
||||
BREAK_TO_DEBUGGER();
|
||||
/*find the reason why logical layer assigned a differant mpcc_id into acquire_post_bldn_3dlut*/
|
||||
/* find the reason why logical layer assigned a different
|
||||
* mpcc_id into acquire_post_bldn_3dlut
|
||||
*/
|
||||
acquired_rmu = mpc->funcs->acquire_rmu(mpc, mpcc_id,
|
||||
stream->lut3d_func->state.bits.rmu_mux_num);
|
||||
stream->lut3d_func->state.bits.rmu_mux_num);
|
||||
if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
|
||||
BREAK_TO_DEBUGGER();
|
||||
result = mpc->funcs->program_3dlut(mpc,
|
||||
&stream->lut3d_func->lut_3d,
|
||||
stream->lut3d_func->state.bits.rmu_mux_num);
|
||||
result = mpc->funcs->program_shaper(mpc, shaper_lut,
|
||||
stream->lut3d_func->state.bits.rmu_mux_num);
|
||||
} else
|
||||
/*loop through the available mux and release the requested mpcc_id*/
|
||||
mpc->funcs->release_rmu(mpc, mpcc_id);
|
||||
|
||||
result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
|
||||
stream->lut3d_func->state.bits.rmu_mux_num);
|
||||
result = mpc->funcs->program_shaper(mpc, shaper_lut,
|
||||
stream->lut3d_func->state.bits.rmu_mux_num);
|
||||
} else {
|
||||
// loop through the available mux and release the requested mpcc_id
|
||||
mpc->funcs->release_rmu(mpc, mpcc_id);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -539,7 +540,7 @@ void dcn30_init_hw(struct dc *dc)
|
||||
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
dc_link_blank_all_dp_displays(dc);
|
||||
link_blank_all_dp_displays(dc);
|
||||
|
||||
if (hws->funcs.enable_power_gating_plane)
|
||||
hws->funcs.enable_power_gating_plane(dc->hwseq, true);
|
||||
@ -997,8 +998,5 @@ void dcn30_prepare_bandwidth(struct dc *dc,
|
||||
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
|
||||
|
||||
dcn20_prepare_bandwidth(dc, context);
|
||||
|
||||
dc_dmub_srv_p_state_delegate(dc,
|
||||
context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching, context);
|
||||
}
|
||||
|
||||
|
@ -291,6 +291,14 @@ static void optc3_set_timing_double_buffer(struct timing_generator *optc, bool e
|
||||
OTG_DRR_TIMING_DBUF_UPDATE_MODE, mode);
|
||||
}
|
||||
|
||||
void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *optc)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
REG_WAIT(OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_PENDING, 0, 2, 100000); /* 1 vupdate at 5hz */
|
||||
|
||||
}
|
||||
|
||||
void optc3_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max)
|
||||
{
|
||||
optc1_set_vtotal_min_max(optc, vtotal_min, vtotal_max);
|
||||
@ -360,6 +368,7 @@ static struct timing_generator_funcs dcn30_tg_funcs = {
|
||||
.program_manual_trigger = optc2_program_manual_trigger,
|
||||
.setup_manual_trigger = optc2_setup_manual_trigger,
|
||||
.get_hw_timing = optc1_get_hw_timing,
|
||||
.wait_drr_doublebuffer_pending_clear = optc3_wait_drr_doublebuffer_pending_clear,
|
||||
};
|
||||
|
||||
void dcn30_timing_generator_init(struct optc *optc1)
|
||||
|
@ -279,6 +279,7 @@
|
||||
SF(OTG0_OTG_DRR_TRIGGER_WINDOW, OTG_DRR_TRIGGER_WINDOW_END_X, mask_sh),\
|
||||
SF(OTG0_OTG_DRR_V_TOTAL_CHANGE, OTG_DRR_V_TOTAL_CHANGE_LIMIT, mask_sh),\
|
||||
SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_BY2, mask_sh),\
|
||||
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_PENDING, mask_sh),\
|
||||
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_BLANK_DATA_DOUBLE_BUFFER_EN, mask_sh)
|
||||
|
||||
@ -317,6 +318,7 @@
|
||||
SF(OTG0_OTG_DRR_TRIGGER_WINDOW, OTG_DRR_TRIGGER_WINDOW_END_X, mask_sh),\
|
||||
SF(OTG0_OTG_DRR_V_TOTAL_CHANGE, OTG_DRR_V_TOTAL_CHANGE_LIMIT, mask_sh),\
|
||||
SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
|
||||
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_PENDING, mask_sh),\
|
||||
SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh)
|
||||
|
||||
void dcn30_timing_generator_init(struct optc *optc1);
|
||||
|
@ -1477,8 +1477,8 @@ bool dcn30_acquire_post_bldn_3dlut(
|
||||
state->bits.mpc_rmu2_mux = mpcc_id;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1648,7 +1648,8 @@ noinline bool dcn30_internal_validate_bw(
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int *pipe_cnt_out,
|
||||
int *vlevel_out,
|
||||
bool fast_validate)
|
||||
bool fast_validate,
|
||||
bool allow_self_refresh_only)
|
||||
{
|
||||
bool out = false;
|
||||
bool repopulate_pipes = false;
|
||||
@ -1675,7 +1676,7 @@ noinline bool dcn30_internal_validate_bw(
|
||||
|
||||
dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
|
||||
|
||||
if (!fast_validate) {
|
||||
if (!fast_validate || !allow_self_refresh_only) {
|
||||
/*
|
||||
* DML favors voltage over p-state, but we're more interested in
|
||||
* supporting p-state over voltage. We can't support p-state in
|
||||
@ -1688,11 +1689,12 @@ noinline bool dcn30_internal_validate_bw(
|
||||
if (vlevel < context->bw_ctx.dml.soc.num_states)
|
||||
vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
|
||||
}
|
||||
if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
|
||||
vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
|
||||
if (allow_self_refresh_only &&
|
||||
(fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
|
||||
vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported)) {
|
||||
/*
|
||||
* If mode is unsupported or there's still no p-state support then
|
||||
* fall back to favoring voltage.
|
||||
* If mode is unsupported or there's still no p-state support
|
||||
* then fall back to favoring voltage.
|
||||
*
|
||||
* We don't actually support prefetch mode 2, so require that we
|
||||
* at least support prefetch mode 1.
|
||||
@ -2063,7 +2065,7 @@ bool dcn30_validate_bandwidth(struct dc *dc,
|
||||
BW_VAL_TRACE_COUNT();
|
||||
|
||||
DC_FP_START();
|
||||
out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
|
||||
out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
|
||||
DC_FP_END();
|
||||
|
||||
if (pipe_cnt == 0)
|
||||
|
@ -64,7 +64,8 @@ bool dcn30_internal_validate_bw(
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int *pipe_cnt_out,
|
||||
int *vlevel_out,
|
||||
bool fast_validate);
|
||||
bool fast_validate,
|
||||
bool allow_self_refresh_only);
|
||||
void dcn30_calculate_wm_and_dlg(
|
||||
struct dc *dc, struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
|
@ -133,6 +133,8 @@
|
||||
int hubbub31_init_dchub_sys_ctx(struct hubbub *hubbub,
|
||||
struct dcn_hubbub_phys_addr_config *pa_config);
|
||||
|
||||
void hubbub31_init(struct hubbub *hubbub);
|
||||
|
||||
void hubbub31_construct(struct dcn20_hubbub *hubbub3,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn_hubbub_registers *hubbub_regs,
|
||||
|
@ -202,7 +202,7 @@ void dcn31_init_hw(struct dc *dc)
|
||||
dmub_enable_outbox_notification(dc->ctx->dmub_srv);
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
dc_link_blank_all_dp_displays(dc);
|
||||
link_blank_all_dp_displays(dc);
|
||||
|
||||
if (hws->funcs.enable_power_gating_plane)
|
||||
hws->funcs.enable_power_gating_plane(dc->hwseq, true);
|
||||
@ -230,7 +230,7 @@ void dcn31_init_hw(struct dc *dc)
|
||||
}
|
||||
|
||||
if (num_opps > 1) {
|
||||
dc_link_blank_all_edp_displays(dc);
|
||||
link_blank_all_edp_displays(dc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -565,7 +565,7 @@ static void dcn31_reset_back_end_for_pipe(
|
||||
* VBIOS lit up eDP, so check link status too.
|
||||
*/
|
||||
if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
|
||||
core_link_disable_stream(pipe_ctx);
|
||||
link_set_dpms_off(pipe_ctx);
|
||||
else if (pipe_ctx->stream_res.audio)
|
||||
dc->hwss.disable_audio_stream(pipe_ctx);
|
||||
|
||||
@ -584,7 +584,7 @@ static void dcn31_reset_back_end_for_pipe(
|
||||
}
|
||||
}
|
||||
} else if (pipe_ctx->stream_res.dsc) {
|
||||
dp_set_dsc_enable(pipe_ctx, false);
|
||||
link_set_dsc_enable(pipe_ctx, false);
|
||||
}
|
||||
|
||||
pipe_ctx->stream = NULL;
|
||||
|
@ -1795,7 +1795,7 @@ bool dcn31_validate_bandwidth(struct dc *dc,
|
||||
BW_VAL_TRACE_COUNT();
|
||||
|
||||
DC_FP_START();
|
||||
out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
|
||||
out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
|
||||
DC_FP_END();
|
||||
|
||||
// Disable fast_validate to set min dcfclk in alculate_wm_and_dlg
|
||||
|
@ -366,7 +366,7 @@ static void enc314_stream_encoder_dp_unblank(
|
||||
*/
|
||||
enc314_enable_fifo(enc);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
}
|
||||
|
||||
/* Set DSC-related configuration.
|
||||
|
@ -389,3 +389,27 @@ void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->stream_res.stream_enc->funcs->set_input_mode(pipe_ctx->stream_res.stream_enc,
|
||||
pix_per_cycle);
|
||||
}
|
||||
|
||||
void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
|
||||
{
|
||||
struct dc_context *ctx = hws->ctx;
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
if (hws->ctx->dc->debug.disable_hubp_power_gate)
|
||||
return;
|
||||
|
||||
PERF_TRACE();
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.domain_control.header.type = DMUB_CMD__VBIOS;
|
||||
cmd.domain_control.header.sub_type = DMUB_CMD__VBIOS_DOMAIN_CONTROL;
|
||||
cmd.domain_control.header.payload_bytes = sizeof(cmd.domain_control.data);
|
||||
cmd.domain_control.data.inst = hubp_inst;
|
||||
cmd.domain_control.data.power_gate = !power_on;
|
||||
|
||||
dc_dmub_srv_cmd_queue(ctx->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(ctx->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(ctx->dmub_srv);
|
||||
|
||||
PERF_TRACE();
|
||||
}
|
||||
|
@ -41,4 +41,6 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
|
||||
|
||||
void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
|
||||
|
||||
#endif /* __DC_HWSS_DCN314_H__ */
|
||||
|
@ -137,7 +137,7 @@ static const struct hwseq_private_funcs dcn314_private_funcs = {
|
||||
.plane_atomic_disable = dcn20_plane_atomic_disable,
|
||||
.plane_atomic_power_down = dcn10_plane_atomic_power_down,
|
||||
.enable_power_gating_plane = dcn314_enable_power_gating_plane,
|
||||
.hubp_pg_control = dcn31_hubp_pg_control,
|
||||
.hubp_pg_control = dcn314_hubp_pg_control,
|
||||
.program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree,
|
||||
.update_odm = dcn314_update_odm,
|
||||
.dsc_pg_control = dcn314_dsc_pg_control,
|
||||
|
@ -892,6 +892,8 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
.force_abm_enable = false,
|
||||
.timing_trace = false,
|
||||
.clock_trace = true,
|
||||
.disable_dpp_power_gate = true,
|
||||
.disable_hubp_power_gate = true,
|
||||
.disable_pplib_clock_request = false,
|
||||
.pipe_split_policy = MPC_SPLIT_DYNAMIC,
|
||||
.force_single_disp_pipe_split = false,
|
||||
@ -901,7 +903,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
.max_downscale_src_width = 4096,/*upto true 4k*/
|
||||
.disable_pplib_wm_range = false,
|
||||
.scl_reset_length10 = true,
|
||||
.sanity_checks = false,
|
||||
.sanity_checks = true,
|
||||
.underflow_assert_delay_us = 0xFFFFFFFF,
|
||||
.dwb_fi_phase = -1, // -1 = disable,
|
||||
.dmub_command_table = true,
|
||||
@ -1695,6 +1697,61 @@ static void dcn314_get_panel_config_defaults(struct dc_panel_config *panel_confi
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
bool dcn314_validate_bandwidth(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
bool fast_validate)
|
||||
{
|
||||
bool out = false;
|
||||
|
||||
BW_VAL_TRACE_SETUP();
|
||||
|
||||
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);
|
||||
DC_LOGGER_INIT(dc->ctx->logger);
|
||||
|
||||
BW_VAL_TRACE_COUNT();
|
||||
|
||||
DC_FP_START();
|
||||
// do not support self refresh only
|
||||
out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, false);
|
||||
DC_FP_END();
|
||||
|
||||
// Disable fast_validate to set min dcfclk in calculate_wm_and_dlg
|
||||
if (pipe_cnt == 0)
|
||||
fast_validate = false;
|
||||
|
||||
if (!out)
|
||||
goto validate_fail;
|
||||
|
||||
BW_VAL_TRACE_END_VOLTAGE_LEVEL();
|
||||
|
||||
if (fast_validate) {
|
||||
BW_VAL_TRACE_SKIP(fast);
|
||||
goto validate_out;
|
||||
}
|
||||
|
||||
dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
|
||||
|
||||
BW_VAL_TRACE_END_WATERMARKS();
|
||||
|
||||
goto validate_out;
|
||||
|
||||
validate_fail:
|
||||
DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
|
||||
dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
|
||||
|
||||
BW_VAL_TRACE_SKIP(fail);
|
||||
out = false;
|
||||
|
||||
validate_out:
|
||||
kfree(pipes);
|
||||
|
||||
BW_VAL_TRACE_FINISH();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static struct resource_funcs dcn314_res_pool_funcs = {
|
||||
.destroy = dcn314_destroy_resource_pool,
|
||||
.link_enc_create = dcn31_link_encoder_create,
|
||||
@ -1702,7 +1759,7 @@ static struct resource_funcs dcn314_res_pool_funcs = {
|
||||
.link_encs_assign = link_enc_cfg_link_encs_assign,
|
||||
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
|
||||
.panel_cntl_create = dcn31_panel_cntl_create,
|
||||
.validate_bandwidth = dcn31_validate_bandwidth,
|
||||
.validate_bandwidth = dcn314_validate_bandwidth,
|
||||
.calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
|
||||
.update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
|
||||
.populate_dml_pipes = dcn314_populate_dml_pipes_from_context,
|
||||
|
@ -39,6 +39,10 @@ struct dcn314_resource_pool {
|
||||
struct resource_pool base;
|
||||
};
|
||||
|
||||
bool dcn314_validate_bandwidth(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
bool fast_validate);
|
||||
|
||||
struct resource_pool *dcn314_create_resource_pool(
|
||||
const struct dc_init_data *init_data,
|
||||
struct dc *dc);
|
||||
|
@ -373,7 +373,7 @@ static void enc32_stream_encoder_dp_unblank(
|
||||
|
||||
REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
|
||||
}
|
||||
|
||||
/* Set DSC-related configuration.
|
||||
|
@ -204,6 +204,8 @@ void hubbub32_force_usr_retraining_allow(struct hubbub *hubbub, bool allow);
|
||||
|
||||
void hubbub32_force_wm_propagate_to_pipes(struct hubbub *hubbub);
|
||||
|
||||
void hubbub32_init(struct hubbub *hubbub);
|
||||
|
||||
void dcn32_program_det_size(struct hubbub *hubbub, int hubp_inst, unsigned int det_buffer_size_in_kbyte);
|
||||
|
||||
void hubbub32_construct(struct dcn20_hubbub *hubbub2,
|
||||
|
@ -61,6 +61,8 @@ void hubp32_phantom_hubp_post_enable(struct hubp *hubp);
|
||||
void hubp32_cursor_set_attributes(struct hubp *hubp,
|
||||
const struct dc_cursor_attributes *attr);
|
||||
|
||||
void hubp32_init(struct hubp *hubp);
|
||||
|
||||
bool hubp32_construct(
|
||||
struct dcn20_hubp *hubp2,
|
||||
struct dc_context *ctx,
|
||||
|
@ -792,7 +792,7 @@ void dcn32_init_hw(struct dc *dc)
|
||||
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
dc_link_blank_all_dp_displays(dc);
|
||||
link_blank_all_dp_displays(dc);
|
||||
|
||||
/* If taking control over from VBIOS, we may want to optimize our first
|
||||
* mode set, so we need to skip powering down pipes until we know which
|
||||
@ -1098,13 +1098,13 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
|
||||
if (link_is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
*k2_div = PIXEL_RATE_DIV_BY_1;
|
||||
} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
|
||||
} else if (dc_is_hdmi_tmds_signal(stream->signal) || dc_is_dvi_signal(stream->signal)) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||
*k2_div = PIXEL_RATE_DIV_BY_2;
|
||||
else
|
||||
*k2_div = PIXEL_RATE_DIV_BY_4;
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
|
||||
} else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) {
|
||||
if (two_pix_per_container) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
*k2_div = PIXEL_RATE_DIV_BY_2;
|
||||
@ -1252,7 +1252,7 @@ void dcn32_disable_link_output(struct dc_link *link,
|
||||
else if (dmcu != NULL && dmcu->funcs->lock_phy)
|
||||
dmcu->funcs->unlock_phy(dmcu);
|
||||
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
|
||||
|
||||
apply_symclk_on_tx_off_wa(link);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "dcn30/dcn30_hwseq.h"
|
||||
#include "dcn31/dcn31_hwseq.h"
|
||||
#include "dcn32_hwseq.h"
|
||||
#include "dcn32_init.h"
|
||||
|
||||
static const struct hw_sequencer_funcs dcn32_funcs = {
|
||||
.program_gamut_remap = dcn10_program_gamut_remap,
|
||||
|
@ -150,6 +150,8 @@ bool dcn32_allow_subvp_with_active_margin(struct pipe_ctx *pipe);
|
||||
|
||||
unsigned int dcn32_calc_num_avail_chans_for_mall(struct dc *dc, int num_chans);
|
||||
|
||||
double dcn32_determine_max_vratio_prefetch(struct dc *dc, struct dc_state *context);
|
||||
|
||||
/* definitions for run time init of reg offsets */
|
||||
|
||||
/* CLK SRC */
|
||||
|
@ -3897,14 +3897,14 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
|
||||
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
||||
|
||||
locals->ODMCombineEnablePerState[i][k] = false;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
|
||||
if (mode_lib->vba.ODMCapability) {
|
||||
if (locals->PlaneRequiredDISPCLKWithoutODMCombine > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
} else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
}
|
||||
}
|
||||
@ -3957,7 +3957,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->RequiredDISPCLK[i][j] = 0.0;
|
||||
locals->DISPCLK_DPPCLK_Support[i][j] = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
locals->ODMCombineEnablePerState[i][k] = false;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
|
||||
locals->NoOfDPP[i][j][k] = 1;
|
||||
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
|
||||
|
@ -4008,17 +4008,17 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
|
||||
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
||||
|
||||
locals->ODMCombineEnablePerState[i][k] = false;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
|
||||
if (mode_lib->vba.ODMCapability) {
|
||||
if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
} else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN20_MAX_DSC_IMAGE_WIDTH)) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
} else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
}
|
||||
}
|
||||
@ -4071,7 +4071,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
locals->RequiredDISPCLK[i][j] = 0.0;
|
||||
locals->DISPCLK_DPPCLK_Support[i][j] = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
locals->ODMCombineEnablePerState[i][k] = false;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
|
||||
locals->NoOfDPP[i][j][k] = 1;
|
||||
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
|
||||
|
@ -4102,17 +4102,17 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
|
||||
* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
||||
|
||||
locals->ODMCombineEnablePerState[i][k] = false;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
|
||||
if (mode_lib->vba.ODMCapability) {
|
||||
if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
} else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN21_MAX_DSC_IMAGE_WIDTH)) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
} else if (locals->HActive[k] > DCN21_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
|
||||
locals->ODMCombineEnablePerState[i][k] = true;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
|
||||
mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
|
||||
}
|
||||
}
|
||||
@ -4165,7 +4165,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->RequiredDISPCLK[i][j] = 0.0;
|
||||
locals->DISPCLK_DPPCLK_Support[i][j] = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
locals->ODMCombineEnablePerState[i][k] = false;
|
||||
locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
|
||||
if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
|
||||
locals->NoOfDPP[i][j][k] = 1;
|
||||
locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
|
||||
@ -5230,7 +5230,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.ODMCombineEnabled[k] =
|
||||
locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
|
||||
} else {
|
||||
mode_lib->vba.ODMCombineEnabled[k] = false;
|
||||
mode_lib->vba.ODMCombineEnabled[k] = dm_odm_combine_mode_disabled;
|
||||
}
|
||||
mode_lib->vba.DSCEnabled[k] =
|
||||
locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
|
||||
|
@ -634,7 +634,7 @@ int dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
|
||||
while (dummy_latency_index < max_latency_table_entries) {
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
|
||||
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
|
||||
dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
|
||||
dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false, true);
|
||||
|
||||
if (context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank ==
|
||||
dm_allow_self_refresh_and_mclk_switch)
|
||||
|
@ -878,7 +878,9 @@ static bool CalculatePrefetchSchedule(
|
||||
double DSTTotalPixelsAfterScaler;
|
||||
double LineTime;
|
||||
double dst_y_prefetch_equ;
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
double Tsw_oto;
|
||||
#endif
|
||||
double prefetch_bw_oto;
|
||||
double prefetch_bw_pr;
|
||||
double Tvm_oto;
|
||||
@ -1060,7 +1062,9 @@ static bool CalculatePrefetchSchedule(
|
||||
|
||||
min_Lsw = dml_max(1, dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / max_vratio_pre);
|
||||
Lsw_oto = dml_ceil(4 * dml_max(prefetch_sw_bytes / prefetch_bw_oto / LineTime, min_Lsw), 1) / 4;
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
Tsw_oto = Lsw_oto * LineTime;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
|
@ -149,8 +149,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = {
|
||||
.num_states = 5,
|
||||
.sr_exit_time_us = 16.5,
|
||||
.sr_enter_plus_exit_time_us = 18.5,
|
||||
.sr_exit_z8_time_us = 280.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 350.0,
|
||||
.sr_exit_z8_time_us = 210.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 310.0,
|
||||
.writeback_latency_us = 12.0,
|
||||
.dram_channel_width_bytes = 4,
|
||||
.round_trip_ping_latency_dcfclk_cycles = 106,
|
||||
@ -346,7 +346,8 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
|
||||
context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_14_DEFAULT_DET_SIZE;
|
||||
|
||||
dc->config.enable_4to1MPC = false;
|
||||
if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
|
||||
if (pipe_cnt == 1 && pipe->plane_state
|
||||
&& pipe->plane_state->rotation == ROTATION_ANGLE_0 && !dc->debug.disable_z9_mpc) {
|
||||
if (is_dual_plane(pipe->plane_state->format)
|
||||
&& pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
|
||||
dc->config.enable_4to1MPC = true;
|
||||
|
@ -900,7 +900,9 @@ static bool CalculatePrefetchSchedule(
|
||||
double DSTTotalPixelsAfterScaler;
|
||||
double LineTime;
|
||||
double dst_y_prefetch_equ;
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
double Tsw_oto;
|
||||
#endif
|
||||
double prefetch_bw_oto;
|
||||
double prefetch_bw_pr;
|
||||
double Tvm_oto;
|
||||
@ -1082,7 +1084,9 @@ static bool CalculatePrefetchSchedule(
|
||||
|
||||
min_Lsw = dml_max(1, dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / max_vratio_pre);
|
||||
Lsw_oto = dml_ceil(4 * dml_max(prefetch_sw_bytes / prefetch_bw_oto / LineTime, min_Lsw), 1) / 4;
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
Tsw_oto = Lsw_oto * LineTime;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
|
@ -51,7 +51,7 @@ static bool CalculateBytePerPixelAnd256BBlockSizes(
|
||||
*BytePerPixelDETC = 0;
|
||||
*BytePerPixelY = 4;
|
||||
*BytePerPixelC = 0;
|
||||
} else if (SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_16) {
|
||||
} else if (SourcePixelFormat == dm_444_16) {
|
||||
*BytePerPixelDETY = 2;
|
||||
*BytePerPixelDETC = 0;
|
||||
*BytePerPixelY = 2;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "dcn32/dcn32_resource.h"
|
||||
#include "dcn20/dcn20_resource.h"
|
||||
#include "display_mode_vba_util_32.h"
|
||||
#include "dml/dcn32/display_mode_vba_32.h"
|
||||
// We need this includes for WATERMARKS_* defines
|
||||
#include "clk_mgr/dcn32/dcn32_smu13_driver_if.h"
|
||||
#include "dcn30/dcn30_resource.h"
|
||||
@ -879,6 +880,10 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context, struc
|
||||
int16_t stretched_drr_us = 0;
|
||||
int16_t drr_stretched_vblank_us = 0;
|
||||
int16_t max_vblank_mallregion = 0;
|
||||
const struct dc_config *config = &dc->config;
|
||||
|
||||
if (config->disable_subvp_drr)
|
||||
return false;
|
||||
|
||||
// Find SubVP pipe
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
@ -1618,6 +1623,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
|
||||
}
|
||||
|
||||
dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
|
||||
context->bw_ctx.dml.soc.max_vratio_pre = dcn32_determine_max_vratio_prefetch(dc, context);
|
||||
|
||||
if (!fast_validate)
|
||||
dcn32_full_validate_bw_helper(dc, context, pipes, &vlevel, split, merge, &pipe_cnt);
|
||||
@ -2744,3 +2750,33 @@ bool dcn32_allow_subvp_with_active_margin(struct pipe_ctx *pipe)
|
||||
}
|
||||
return allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* *******************************************************************************************
|
||||
* dcn32_determine_max_vratio_prefetch: Determine max Vratio for prefetch by driver policy
|
||||
*
|
||||
* @param [in]: dc: Current DC state
|
||||
* @param [in]: context: New DC state to be programmed
|
||||
*
|
||||
* @return: Max vratio for prefetch
|
||||
*
|
||||
* *******************************************************************************************
|
||||
*/
|
||||
double dcn32_determine_max_vratio_prefetch(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
double max_vratio_pre = __DML_MAX_BW_RATIO_PRE__; // Default value is 4
|
||||
int i;
|
||||
|
||||
/* For single display MPO configs, allow the max vratio to be 8
|
||||
* if any plane is YUV420 format
|
||||
*/
|
||||
if (context->stream_count == 1 && context->stream_status[0].plane_count > 1) {
|
||||
for (i = 0; i < context->stream_status[0].plane_count; i++) {
|
||||
if (context->stream_status[0].plane_states[i]->format == SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr ||
|
||||
context->stream_status[0].plane_states[i]->format == SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb) {
|
||||
max_vratio_pre = __DML_MAX_VRATIO_PRE__;
|
||||
}
|
||||
}
|
||||
}
|
||||
return max_vratio_pre;
|
||||
}
|
||||
|
@ -896,8 +896,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
||||
if (v->DestinationLinesForPrefetch[k] < 2)
|
||||
DestinationLineTimesForPrefetchLessThan2 = true;
|
||||
|
||||
if (v->VRatioPrefetchY[k] > __DML_MAX_VRATIO_PRE__
|
||||
|| v->VRatioPrefetchC[k] > __DML_MAX_VRATIO_PRE__)
|
||||
if (v->VRatioPrefetchY[k] > v->MaxVRatioPre
|
||||
|| v->VRatioPrefetchC[k] > v->MaxVRatioPre)
|
||||
VRatioPrefetchMoreThanMax = true;
|
||||
|
||||
//bool DestinationLinesToRequestVMInVBlankEqualOrMoreThan32 = false;
|
||||
@ -942,6 +942,9 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
||||
v->UrgBurstFactorLumaPre,
|
||||
v->UrgBurstFactorChromaPre,
|
||||
v->UrgBurstFactorCursorPre,
|
||||
v->PrefetchBandwidth,
|
||||
v->VRatio,
|
||||
v->MaxVRatioPre,
|
||||
|
||||
/* output */
|
||||
&MaxTotalRDBandwidth,
|
||||
@ -972,6 +975,9 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
||||
v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.dummy_unit_vector,
|
||||
v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.dummy_unit_vector,
|
||||
v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.dummy_unit_vector,
|
||||
v->PrefetchBandwidth,
|
||||
v->VRatio,
|
||||
v->MaxVRatioPre,
|
||||
|
||||
/* output */
|
||||
&v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.dummy_single[0],
|
||||
@ -2347,8 +2353,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
|
||||
if (mode_lib->vba.DSCEnable[k] && mode_lib->vba.ForcedOutputLinkBPP[k] != 0)
|
||||
mode_lib->vba.DSCOnlyIfNecessaryWithBPP = true;
|
||||
if ((mode_lib->vba.DSCEnable[k] || mode_lib->vba.DSCEnable[k])
|
||||
&& mode_lib->vba.OutputFormat[k] == dm_n422
|
||||
if (mode_lib->vba.DSCEnable[k] && mode_lib->vba.OutputFormat[k] == dm_n422
|
||||
&& !mode_lib->vba.DSC422NativeSupport)
|
||||
mode_lib->vba.DSC422NativeNotSupported = true;
|
||||
|
||||
@ -3373,6 +3378,9 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.UrgentBurstFactorLumaPre,
|
||||
mode_lib->vba.UrgentBurstFactorChromaPre,
|
||||
mode_lib->vba.UrgentBurstFactorCursorPre,
|
||||
v->PrefetchBW,
|
||||
v->VRatio,
|
||||
v->MaxVRatioPre,
|
||||
|
||||
/* output */
|
||||
&v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.dummy_single[0], // Single *PrefetchBandwidth
|
||||
@ -3397,8 +3405,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
|
||||
mode_lib->vba.VRatioInPrefetchSupported[i][j] = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) {
|
||||
if (mode_lib->vba.VRatioPreY[i][j][k] > __DML_MAX_VRATIO_PRE__
|
||||
|| mode_lib->vba.VRatioPreC[i][j][k] > __DML_MAX_VRATIO_PRE__
|
||||
if (mode_lib->vba.VRatioPreY[i][j][k] > mode_lib->vba.MaxVRatioPre
|
||||
|| mode_lib->vba.VRatioPreC[i][j][k] > mode_lib->vba.MaxVRatioPre
|
||||
|| mode_lib->vba.NoTimeForPrefetch[i][j][k] == true) {
|
||||
mode_lib->vba.VRatioInPrefetchSupported[i][j] = false;
|
||||
}
|
||||
@ -3654,7 +3662,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
|
||||
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
|
||||
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
|
||||
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
|
||||
&& mode_lib->vba.SourcePixelFormat[k] != dm_444_8
|
||||
&& mode_lib->vba.SourcePixelFormat[k] != dm_rgbe) {
|
||||
if (mode_lib->vba.ViewportWidthChroma[k] > mode_lib->vba.SurfaceWidthC[k]
|
||||
|
@ -44,7 +44,8 @@
|
||||
#define __DML_MIN_DCFCLK_FACTOR__ 1.15
|
||||
|
||||
// Prefetch schedule max vratio
|
||||
#define __DML_MAX_VRATIO_PRE__ 4.0
|
||||
#define __DML_MAX_VRATIO_PRE__ 7.9
|
||||
#define __DML_MAX_BW_RATIO_PRE__ 4.0
|
||||
|
||||
#define __DML_VBA_MAX_DST_Y_PRE__ 63.75
|
||||
|
||||
|
@ -3480,7 +3480,7 @@ bool dml32_CalculatePrefetchSchedule(
|
||||
double prefetch_sw_bytes;
|
||||
double bytes_pp;
|
||||
double dep_bytes;
|
||||
unsigned int max_vratio_pre = __DML_MAX_VRATIO_PRE__;
|
||||
unsigned int max_vratio_pre = v->MaxVRatioPre;
|
||||
double min_Lsw;
|
||||
double Tsw_est1 = 0;
|
||||
double Tsw_est3 = 0;
|
||||
@ -6143,29 +6143,46 @@ void dml32_CalculatePrefetchBandwithSupport(unsigned int NumberOfActiveSurfaces,
|
||||
double UrgentBurstFactorLumaPre[],
|
||||
double UrgentBurstFactorChromaPre[],
|
||||
double UrgentBurstFactorCursorPre[],
|
||||
double PrefetchBW[],
|
||||
double VRatio[],
|
||||
double MaxVRatioPre,
|
||||
|
||||
/* output */
|
||||
double *PrefetchBandwidth,
|
||||
double *MaxPrefetchBandwidth,
|
||||
double *FractionOfUrgentBandwidth,
|
||||
bool *PrefetchBandwidthSupport)
|
||||
{
|
||||
unsigned int k;
|
||||
double ActiveBandwidthPerSurface;
|
||||
bool NotEnoughUrgentLatencyHiding = false;
|
||||
double TotalActiveBandwidth = 0;
|
||||
double TotalPrefetchBandwidth = 0;
|
||||
|
||||
for (k = 0; k < NumberOfActiveSurfaces; ++k) {
|
||||
if (NotUrgentLatencyHiding[k]) {
|
||||
NotEnoughUrgentLatencyHiding = true;
|
||||
}
|
||||
}
|
||||
|
||||
*PrefetchBandwidth = 0;
|
||||
*MaxPrefetchBandwidth = 0;
|
||||
for (k = 0; k < NumberOfActiveSurfaces; ++k) {
|
||||
*PrefetchBandwidth = *PrefetchBandwidth + dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
|
||||
ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k] + NumberOfDPP[k] * (meta_row_bandwidth[k] + dpte_row_bandwidth[k]),
|
||||
ActiveBandwidthPerSurface = ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k] + NumberOfDPP[k] * (meta_row_bandwidth[k] + dpte_row_bandwidth[k]);
|
||||
|
||||
TotalActiveBandwidth += ActiveBandwidthPerSurface;
|
||||
|
||||
TotalPrefetchBandwidth = TotalPrefetchBandwidth + PrefetchBW[k] * VRatio[k];
|
||||
|
||||
*MaxPrefetchBandwidth = *MaxPrefetchBandwidth + dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
|
||||
ActiveBandwidthPerSurface,
|
||||
NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k] + PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k]) + cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
|
||||
}
|
||||
|
||||
*PrefetchBandwidthSupport = (*PrefetchBandwidth <= ReturnBW) && !NotEnoughUrgentLatencyHiding;
|
||||
*FractionOfUrgentBandwidth = *PrefetchBandwidth / ReturnBW;
|
||||
if (MaxVRatioPre == __DML_MAX_VRATIO_PRE__)
|
||||
*PrefetchBandwidthSupport = (*MaxPrefetchBandwidth <= ReturnBW) && (TotalPrefetchBandwidth <= TotalActiveBandwidth * __DML_MAX_BW_RATIO_PRE__) && !NotEnoughUrgentLatencyHiding;
|
||||
else
|
||||
*PrefetchBandwidthSupport = (*MaxPrefetchBandwidth <= ReturnBW) && !NotEnoughUrgentLatencyHiding;
|
||||
|
||||
*FractionOfUrgentBandwidth = *MaxPrefetchBandwidth / ReturnBW;
|
||||
}
|
||||
|
||||
double dml32_CalculateBandwidthAvailableForImmediateFlip(unsigned int NumberOfActiveSurfaces,
|
||||
|
@ -1096,9 +1096,12 @@ void dml32_CalculatePrefetchBandwithSupport(unsigned int NumberOfActiveSurfaces,
|
||||
double UrgentBurstFactorLumaPre[],
|
||||
double UrgentBurstFactorChromaPre[],
|
||||
double UrgentBurstFactorCursorPre[],
|
||||
double PrefetchBW[],
|
||||
double VRatio[],
|
||||
double MaxVRatioPre,
|
||||
|
||||
/* output */
|
||||
double *PrefetchBandwidth,
|
||||
double *MaxPrefetchBandwidth,
|
||||
double *FractionOfUrgentBandwidth,
|
||||
bool *PrefetchBandwidthSupport);
|
||||
|
||||
|
@ -246,6 +246,7 @@ struct _vcs_dpi_soc_bounding_box_st {
|
||||
bool disable_dram_clock_change_vactive_support;
|
||||
bool allow_dram_clock_one_display_vactive;
|
||||
enum self_refresh_affinity allow_dram_self_refresh_or_dram_clock_change_in_vblank;
|
||||
double max_vratio_pre;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -412,6 +412,7 @@ static void fetch_socbb_params(struct display_mode_lib *mode_lib)
|
||||
soc->urgent_latency_adjustment_fabric_clock_component_us;
|
||||
mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference =
|
||||
soc->urgent_latency_adjustment_fabric_clock_reference_mhz;
|
||||
mode_lib->vba.MaxVRatioPre = soc->max_vratio_pre;
|
||||
}
|
||||
|
||||
static void fetch_ip_params(struct display_mode_lib *mode_lib)
|
||||
|
@ -263,6 +263,7 @@ struct vba_vars_st {
|
||||
int maxMpcComb;
|
||||
bool UseMaximumVStartup;
|
||||
|
||||
double MaxVRatioPre;
|
||||
double WritebackDISPCLK;
|
||||
double DPPCLKUsingSingleDPPLuma;
|
||||
double DPPCLKUsingSingleDPPChroma;
|
||||
|
@ -56,33 +56,6 @@ void enable_surface_flip_reporting(struct dc_plane_state *plane_state,
|
||||
#endif
|
||||
#include "link_hwss.h"
|
||||
|
||||
/************ link *****************/
|
||||
struct link_init_data {
|
||||
const struct dc *dc;
|
||||
struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */
|
||||
uint32_t connector_index; /* this will be mapped to the HPD pins */
|
||||
uint32_t link_index; /* this is mapped to DAL display_index
|
||||
TODO: remove it when DC is complete. */
|
||||
bool is_dpia_link;
|
||||
};
|
||||
|
||||
struct dc_link *link_create(const struct link_init_data *init_params);
|
||||
void link_destroy(struct dc_link **link);
|
||||
|
||||
enum dc_status dc_link_validate_mode_timing(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
const struct dc_crtc_timing *timing);
|
||||
|
||||
void core_link_resume(struct dc_link *link);
|
||||
|
||||
void core_link_enable_stream(
|
||||
struct dc_state *state,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
|
||||
void core_link_disable_stream(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
/********** DAL Core*********************/
|
||||
#include "transform.h"
|
||||
#include "dpp.h"
|
||||
|
@ -331,6 +331,7 @@ struct timing_generator_funcs {
|
||||
uint32_t vtotal_change_limit);
|
||||
|
||||
void (*init_odm)(struct timing_generator *tg);
|
||||
void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator *tg);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -40,6 +40,19 @@
|
||||
#include "core_types.h"
|
||||
#include "dc_link.h"
|
||||
|
||||
struct link_init_data {
|
||||
const struct dc *dc;
|
||||
struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */
|
||||
uint32_t connector_index; /* this will be mapped to the HPD pins */
|
||||
uint32_t link_index; /* this is mapped to DAL display_index
|
||||
TODO: remove it when DC is complete. */
|
||||
bool is_dpia_link;
|
||||
};
|
||||
|
||||
struct dc_link *link_create(const struct link_init_data *init_params);
|
||||
void link_destroy(struct dc_link **link);
|
||||
|
||||
// TODO - convert any function declarations below to function pointers
|
||||
struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
|
||||
struct graphics_object_id link_id,
|
||||
struct gpio_service *gpio_service);
|
||||
@ -105,5 +118,40 @@ bool link_power_alpm_dpcd_enable(struct dc_link *link, bool enable);
|
||||
bool link_set_sink_vtotal_in_psr_active(const struct dc_link *link,
|
||||
uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su);
|
||||
void link_get_psr_residency(const struct dc_link *link, uint32_t *residency);
|
||||
enum dc_status link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
|
||||
enum dc_status link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
|
||||
void link_blank_all_dp_displays(struct dc *dc);
|
||||
void link_blank_all_edp_displays(struct dc *dc);
|
||||
void link_blank_dp_stream(struct dc_link *link, bool hw_init);
|
||||
void link_resume(struct dc_link *link);
|
||||
void link_set_dpms_on(
|
||||
struct dc_state *state,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
void link_set_dpms_off(struct pipe_ctx *pipe_ctx);
|
||||
void link_dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
|
||||
void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool link_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool link_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
enum dc_status link_validate_mode_timing(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
const struct dc_crtc_timing *timing);
|
||||
bool link_detect(struct dc_link *link, enum dc_detect_reason reason);
|
||||
bool link_detect_connection_type(struct dc_link *link,
|
||||
enum dc_connection_type *type);
|
||||
const struct dc_link_status *link_get_status(const struct dc_link *link);
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
/* return true if the connected receiver supports the hdcp version */
|
||||
bool link_is_hdcp14(struct dc_link *link, enum signal_type signal);
|
||||
bool link_is_hdcp22(struct dc_link *link, enum signal_type signal);
|
||||
#endif
|
||||
void link_clear_dprx_states(struct dc_link *link);
|
||||
bool link_reset_cur_dp_mst_topology(struct dc_link *link);
|
||||
uint32_t dp_link_bandwidth_kbps(
|
||||
const struct dc_link *link,
|
||||
const struct dc_link_settings *link_settings);
|
||||
uint32_t link_timing_bandwidth_kbps(const struct dc_crtc_timing *timing);
|
||||
void link_get_cur_res_map(const struct dc *dc, uint32_t *map);
|
||||
void link_restore_res_map(const struct dc *dc, uint32_t *map);
|
||||
|
||||
#endif /* __DC_LINK_HPD_H__ */
|
||||
|
@ -165,10 +165,6 @@ bool resource_validate_attach_surfaces(
|
||||
struct dc_state *context,
|
||||
const struct resource_pool *pool);
|
||||
|
||||
void resource_validate_ctx_update_pointer_after_copy(
|
||||
const struct dc_state *src_ctx,
|
||||
struct dc_state *dst_ctx);
|
||||
|
||||
enum dc_status resource_map_clock_resources(
|
||||
const struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
|
||||
|
||||
enum dc_irq_source to_dal_irq_source_dcn201(
|
||||
static enum dc_irq_source to_dal_irq_source_dcn201(
|
||||
struct irq_service *irq_service,
|
||||
uint32_t src_id,
|
||||
uint32_t ext_id)
|
||||
|
@ -23,10 +23,17 @@
|
||||
# It abstracts the control and status of back end pipe such as DIO, HPO, DPIA,
|
||||
# PHY, HPD, DDC and etc).
|
||||
|
||||
LINK = link_detection.o link_dpms.o link_factory.o link_resource.o \
|
||||
link_validation.o
|
||||
|
||||
AMD_DAL_LINK = $(addprefix $(AMDDALPATH)/dc/link/, \
|
||||
$(LINK))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_LINK)
|
||||
###############################################################################
|
||||
# accessories
|
||||
###############################################################################
|
||||
LINK_ACCESSORIES = link_dp_trace.o link_dp_cts.o
|
||||
LINK_ACCESSORIES = link_dp_trace.o link_dp_cts.o link_fpga.o
|
||||
|
||||
AMD_DAL_LINK_ACCESSORIES = $(addprefix $(AMDDALPATH)/dc/link/accessories/, \
|
||||
$(LINK_ACCESSORIES))
|
||||
|
@ -23,10 +23,12 @@
|
||||
*
|
||||
*/
|
||||
#include "link_dp_cts.h"
|
||||
#include "link/link_resource.h"
|
||||
#include "link/protocols/link_dpcd.h"
|
||||
#include "link/protocols/link_dp_training.h"
|
||||
#include "link/protocols/link_dp_phy.h"
|
||||
#include "link/protocols/link_dp_training_fixed_vs_pe_retimer.h"
|
||||
#include "link/link_dpms.h"
|
||||
#include "resource.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
@ -77,37 +79,26 @@ void dp_retrain_link_dp_test(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern)
|
||||
{
|
||||
struct pipe_ctx *pipe;
|
||||
unsigned int i;
|
||||
struct pipe_ctx *pipes[MAX_PIPES];
|
||||
struct dc_state *state = link->dc->current_state;
|
||||
uint8_t count;
|
||||
int i;
|
||||
|
||||
udelay(100);
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream != NULL &&
|
||||
pipe->stream->link == link &&
|
||||
!pipe->stream->dpms_off &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
core_link_disable_stream(pipe);
|
||||
pipe->link_config.dp_link_settings = *link_setting;
|
||||
update_dp_encoder_resources_for_test_harness(
|
||||
link->dc,
|
||||
pipe->stream->ctx->dc->current_state,
|
||||
pipe);
|
||||
}
|
||||
link_get_master_pipes_with_dpms_on(link, state, &count, pipes);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
link_set_dpms_off(pipes[i]);
|
||||
pipes[i]->link_config.dp_link_settings = *link_setting;
|
||||
update_dp_encoder_resources_for_test_harness(
|
||||
link->dc,
|
||||
state,
|
||||
pipes[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream != NULL &&
|
||||
pipe->stream->link == link &&
|
||||
!pipe->stream->dpms_off &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
core_link_enable_stream(
|
||||
pipe->stream->ctx->dc->current_state,
|
||||
pipe);
|
||||
}
|
||||
}
|
||||
for (i = count-1; i >= 0; i--)
|
||||
link_set_dpms_on(state, pipes[i]);
|
||||
}
|
||||
|
||||
static void dp_test_send_link_training(struct dc_link *link)
|
||||
@ -965,7 +956,7 @@ void dc_link_set_drive_settings(struct dc *dc,
|
||||
if (i >= dc->link_count)
|
||||
ASSERT_CRITICAL(false);
|
||||
|
||||
dc_link_get_cur_link_res(link, &link_res);
|
||||
link_get_cur_link_res(link, &link_res);
|
||||
dp_set_drive_settings(dc->links[i], &link_res, lt_settings);
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,9 @@
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#include "dc_link.h"
|
||||
#include "link_dp_trace.h"
|
||||
#include "link/protocols/link_dpcd.h"
|
||||
#include "link.h"
|
||||
|
||||
void dp_trace_init(struct dc_link *link)
|
||||
{
|
||||
@ -164,3 +165,10 @@ uint64_t link_dp_trace_get_edp_poweroff_timestamp(struct dc_link *link)
|
||||
{
|
||||
return link->dp_trace.edp_trace_power_timestamps.poweroff;
|
||||
}
|
||||
|
||||
void link_dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
|
||||
{
|
||||
if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
|
||||
core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
|
||||
&dp_test_mode, sizeof(dp_test_mode));
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
#ifndef __LINK_DP_TRACE_H__
|
||||
#define __LINK_DP_TRACE_H__
|
||||
#include "link.h"
|
||||
|
||||
void dp_trace_init(struct dc_link *link);
|
||||
void dp_trace_reset(struct dc_link *link);
|
||||
|
95
drivers/gpu/drm/amd/display/dc/link/accessories/link_fpga.c
Normal file
95
drivers/gpu/drm/amd/display/dc/link/accessories/link_fpga.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2023 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#include "link_fpga.h"
|
||||
#include "link/link_dpms.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "link_hwss.h"
|
||||
#include "dccg.h"
|
||||
#include "resource.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
void dp_fpga_hpo_enable_link_and_stream(struct dc_state *state, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct link_mst_stream_allocation_table proposed_table = {0};
|
||||
struct fixed31_32 avg_time_slots_per_mtp;
|
||||
uint8_t req_slot_count = 0;
|
||||
uint8_t vc_id = 1; /// VC ID always 1 for SST
|
||||
struct dc_link_settings link_settings = pipe_ctx->link_config.dp_link_settings;
|
||||
const struct link_hwss *link_hwss = get_link_hwss(stream->link, &pipe_ctx->link_res);
|
||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||
|
||||
stream->link->cur_link_settings = link_settings;
|
||||
|
||||
if (link_hwss->ext.enable_dp_link_output)
|
||||
link_hwss->ext.enable_dp_link_output(stream->link, &pipe_ctx->link_res,
|
||||
stream->signal, pipe_ctx->clock_source->id,
|
||||
&link_settings);
|
||||
|
||||
/* Enable DP_STREAM_ENC */
|
||||
dc->hwss.enable_stream(pipe_ctx);
|
||||
|
||||
/* Set DPS PPS SDP (AKA "info frames") */
|
||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||
link_set_dsc_pps_packet(pipe_ctx, true, true);
|
||||
}
|
||||
|
||||
/* Allocate Payload */
|
||||
if ((stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) && (state->stream_count > 1)) {
|
||||
// MST case
|
||||
uint8_t i;
|
||||
|
||||
proposed_table.stream_count = state->stream_count;
|
||||
for (i = 0; i < state->stream_count; i++) {
|
||||
avg_time_slots_per_mtp = link_calculate_sst_avg_time_slots_per_mtp(state->streams[i], state->streams[i]->link);
|
||||
req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
|
||||
proposed_table.stream_allocations[i].slot_count = req_slot_count;
|
||||
proposed_table.stream_allocations[i].vcp_id = i+1;
|
||||
/* NOTE: This makes assumption that pipe_ctx index is same as stream index */
|
||||
proposed_table.stream_allocations[i].hpo_dp_stream_enc = state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc;
|
||||
}
|
||||
} else {
|
||||
// SST case
|
||||
avg_time_slots_per_mtp = link_calculate_sst_avg_time_slots_per_mtp(stream, stream->link);
|
||||
req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
|
||||
proposed_table.stream_count = 1; /// Always 1 stream for SST
|
||||
proposed_table.stream_allocations[0].slot_count = req_slot_count;
|
||||
proposed_table.stream_allocations[0].vcp_id = vc_id;
|
||||
proposed_table.stream_allocations[0].hpo_dp_stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
|
||||
}
|
||||
|
||||
link_hwss->ext.update_stream_allocation_table(stream->link,
|
||||
&pipe_ctx->link_res,
|
||||
&proposed_table);
|
||||
|
||||
if (link_hwss->ext.set_throttled_vcp_size)
|
||||
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
|
||||
|
||||
dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings);
|
||||
dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
}
|
||||
|
30
drivers/gpu/drm/amd/display/dc/link/accessories/link_fpga.h
Normal file
30
drivers/gpu/drm/amd/display/dc/link/accessories/link_fpga.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2023 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#ifndef __LINK_FPGA_H__
|
||||
#define __LINK_FPGA_H__
|
||||
#include "link.h"
|
||||
void dp_fpga_hpo_enable_link_and_stream(struct dc_state *state,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
#endif /* __LINK_FPGA_H__ */
|
@ -44,7 +44,7 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
|
||||
link_enc->funcs->connect_dig_be_to_fe(link_enc,
|
||||
pipe_ctx->stream_res.stream_enc->id, true);
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
link_dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
|
||||
if (stream_enc->funcs->enable_fifo)
|
||||
stream_enc->funcs->enable_fifo(stream_enc);
|
||||
@ -63,7 +63,7 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->stream_res.stream_enc->id,
|
||||
false);
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
link_dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
|
||||
|
||||
}
|
||||
@ -105,7 +105,7 @@ void setup_dio_stream_attribute(struct pipe_ctx *pipe_ctx)
|
||||
&stream->timing);
|
||||
|
||||
if (dc_is_dp_signal(stream->signal))
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
|
||||
}
|
||||
|
||||
void enable_dio_dp_link_output(struct dc_link *link,
|
||||
@ -126,7 +126,7 @@ void enable_dio_dp_link_output(struct dc_link *link,
|
||||
link_enc,
|
||||
link_settings,
|
||||
clock_source);
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
|
||||
}
|
||||
|
||||
void disable_dio_link_output(struct dc_link *link,
|
||||
@ -136,7 +136,7 @@ void disable_dio_link_output(struct dc_link *link,
|
||||
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
|
||||
|
||||
link_enc->funcs->disable_output(link_enc, signal);
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
|
||||
}
|
||||
|
||||
void set_dio_dp_link_test_pattern(struct dc_link *link,
|
||||
@ -146,7 +146,7 @@ void set_dio_dp_link_test_pattern(struct dc_link *link,
|
||||
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
|
||||
|
||||
link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params);
|
||||
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
|
||||
link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
|
||||
}
|
||||
|
||||
void set_dio_dp_lane_settings(struct dc_link *link,
|
||||
@ -195,7 +195,7 @@ void enable_dio_audio_packet(struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->stream_res.stream_enc, false);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
link_dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
DPCD_SOURCE_SEQ_AFTER_ENABLE_AUDIO_STREAM);
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ void disable_dio_audio_packet(struct pipe_ctx *pipe_ctx)
|
||||
}
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
link_dp_source_sequence_trace(pipe_ctx->stream->link,
|
||||
DPCD_SOURCE_SEQ_AFTER_DISABLE_AUDIO_STREAM);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user