mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
Merge tag 'amd-drm-next-6.4-2023-03-17' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.4-2023-03-17: amdgpu: - Misc code cleanups - Documentation fixes - Make kobj structures const - Add thermal throttling adjustments for supported APUs - UMC RAS fixes - Display reset fixes - DCN 3.2 fixes - Freesync fixes - DC code reorg - Generalize dmabuf import to work with KFD - DC DML fixes - SRIOV fixes - UVD code cleanups - IH 4.4.2 updates - HDP 4.4.2 updates - SDMA 4.4.2 updates - PSP 13.0.6 updates - Add capped/uncapped workload handling for supported APUs - DCN 3.1.4 updates - Re-org DC Kconfig - USB4 fixes - Reorg DC plane and stream handling - Register vga_switcheroo for apple-gmux - SMU 13.0.6 updates - Fix error checking in read_mm_registers functions for affected families - VCN 4.0.4 fix - Drop redundant pci_enable_pcie_error_reporting() call - RDNA2 SMU OD suspend/resume fix - Expose additional memory stats via fdinfo - RAS fixes - Misc display fixes - DP MST fixes - IOMMU regression fix for KFD amdkfd: - Make kobj structures const - Support for exporting buffers via dmabuf - Multi-VMA page migration fixes - NBIO fixes - Misc code cleanups - Fix possible double free - Fix possible UAF radeon: - iMac fix UAPI: - KFD dmabuf export support. Required for importing KFD buffers into GEM contexts and for RDMA P2P support. Proposed user mode changes: https://github.com/fxkamd/ROCT-Thunk-Interface/commits/fxkamd/dmabuf From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230317164416.138340-1-alexander.deucher@amd.com
This commit is contained in:
commit
90031bc33f
|
|
@ -173,7 +173,7 @@ The alpha blending equation is configured from DRM to DC interface by the
|
|||
following path:
|
||||
|
||||
1. When updating a :c:type:`drm_plane_state <drm_plane_state>`, DM calls
|
||||
:c:type:`fill_blending_from_plane_state()` that maps
|
||||
:c:type:`amdgpu_dm_plane_fill_blending_from_plane_state()` that maps
|
||||
:c:type:`drm_plane_state <drm_plane_state>` attributes to
|
||||
:c:type:`dc_plane_info <dc_plane_info>` struct to be handled in the
|
||||
OS-agnostic component (DC).
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
config DRM_AMDGPU
|
||||
tristate "AMD GPU"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on !UML
|
||||
select FW_LOADER
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HDMI_HELPER
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
|
|||
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
|
||||
amdgpu_gtt_mgr.o amdgpu_preempt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o \
|
||||
amdgpu_atomfirmware.o amdgpu_vf_error.o amdgpu_sched.o \
|
||||
amdgpu_debugfs.o amdgpu_ids.o amdgpu_gmc.o \
|
||||
amdgpu_debugfs.o amdgpu_ids.o amdgpu_gmc.o amdgpu_mmhub.o amdgpu_hdp.o \
|
||||
amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \
|
||||
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
|
||||
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
|
||||
|
|
@ -148,6 +148,7 @@ amdgpu-y += \
|
|||
sdma_v3_0.o \
|
||||
sdma_v4_0.o \
|
||||
sdma_v4_4.o \
|
||||
sdma_v4_4_2.o \
|
||||
sdma_v5_0.o \
|
||||
sdma_v5_2.o \
|
||||
sdma_v6_0.o
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
#include <linux/hashtable.h>
|
||||
#include <linux/dma-fence.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/aer.h>
|
||||
|
||||
#include <drm/ttm/ttm_bo.h>
|
||||
#include <drm/ttm/ttm_placement.h>
|
||||
|
|
@ -1005,7 +1004,6 @@ struct amdgpu_device {
|
|||
bool in_runpm;
|
||||
bool has_pr3;
|
||||
|
||||
bool pm_sysfs_en;
|
||||
bool ucode_sysfs_en;
|
||||
bool psp_sysfs_en;
|
||||
|
||||
|
|
@ -1095,18 +1093,14 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
|
|||
uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
|
||||
|
||||
u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr);
|
||||
u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr);
|
||||
void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u32 reg_data);
|
||||
void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u64 reg_data);
|
||||
|
||||
u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);
|
||||
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
|
||||
|
||||
|
|
|
|||
|
|
@ -308,6 +308,8 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
|
|||
uint64_t va, void *drm_priv,
|
||||
struct kgd_mem **mem, uint64_t *size,
|
||||
uint64_t *mmap_offset);
|
||||
int amdgpu_amdkfd_gpuvm_export_dmabuf(struct kgd_mem *mem,
|
||||
struct dma_buf **dmabuf);
|
||||
int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
|
||||
struct tile_config *config);
|
||||
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -711,6 +711,21 @@ kfd_mem_dmaunmap_attachment(struct kgd_mem *mem,
|
|||
}
|
||||
}
|
||||
|
||||
static int kfd_mem_export_dmabuf(struct kgd_mem *mem)
|
||||
{
|
||||
if (!mem->dmabuf) {
|
||||
struct dma_buf *ret = amdgpu_gem_prime_export(
|
||||
&mem->bo->tbo.base,
|
||||
mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
|
||||
DRM_RDWR : 0);
|
||||
if (IS_ERR(ret))
|
||||
return PTR_ERR(ret);
|
||||
mem->dmabuf = ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
struct amdgpu_bo **bo)
|
||||
|
|
@ -718,16 +733,9 @@ kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
|
|||
struct drm_gem_object *gobj;
|
||||
int ret;
|
||||
|
||||
if (!mem->dmabuf) {
|
||||
mem->dmabuf = amdgpu_gem_prime_export(&mem->bo->tbo.base,
|
||||
mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
|
||||
DRM_RDWR : 0);
|
||||
if (IS_ERR(mem->dmabuf)) {
|
||||
ret = PTR_ERR(mem->dmabuf);
|
||||
mem->dmabuf = NULL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = kfd_mem_export_dmabuf(mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
gobj = amdgpu_gem_prime_import(adev_to_drm(adev), mem->dmabuf);
|
||||
if (IS_ERR(gobj))
|
||||
|
|
@ -1575,7 +1583,7 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev)
|
|||
{
|
||||
uint64_t reserved_for_pt =
|
||||
ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
|
||||
size_t available;
|
||||
ssize_t available;
|
||||
|
||||
spin_lock(&kfd_mem_limit.mem_limit_lock);
|
||||
available = adev->gmc.real_vram_size
|
||||
|
|
@ -1584,6 +1592,9 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev)
|
|||
- reserved_for_pt;
|
||||
spin_unlock(&kfd_mem_limit.mem_limit_lock);
|
||||
|
||||
if (available < 0)
|
||||
available = 0;
|
||||
|
||||
return ALIGN_DOWN(available, VRAM_AVAILABLITY_ALIGN);
|
||||
}
|
||||
|
||||
|
|
@ -2210,30 +2221,27 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
|
|||
struct amdgpu_bo *bo;
|
||||
int ret;
|
||||
|
||||
if (dma_buf->ops != &amdgpu_dmabuf_ops)
|
||||
/* Can't handle non-graphics buffers */
|
||||
return -EINVAL;
|
||||
|
||||
obj = dma_buf->priv;
|
||||
if (drm_to_adev(obj->dev) != adev)
|
||||
/* Can't handle buffers from other devices */
|
||||
return -EINVAL;
|
||||
obj = amdgpu_gem_prime_import(adev_to_drm(adev), dma_buf);
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
|
||||
bo = gem_to_amdgpu_bo(obj);
|
||||
if (!(bo->preferred_domains & (AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT)))
|
||||
AMDGPU_GEM_DOMAIN_GTT))) {
|
||||
/* Only VRAM and GTT BOs are supported */
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_put_obj;
|
||||
}
|
||||
|
||||
*mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL);
|
||||
if (!*mem)
|
||||
return -ENOMEM;
|
||||
if (!*mem) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put_obj;
|
||||
}
|
||||
|
||||
ret = drm_vma_node_allow(&obj->vma_node, drm_priv);
|
||||
if (ret) {
|
||||
kfree(*mem);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto err_free_mem;
|
||||
|
||||
if (size)
|
||||
*size = amdgpu_bo_size(bo);
|
||||
|
|
@ -2250,7 +2258,8 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
|
|||
| KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE
|
||||
| KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE;
|
||||
|
||||
drm_gem_object_get(&bo->tbo.base);
|
||||
get_dma_buf(dma_buf);
|
||||
(*mem)->dmabuf = dma_buf;
|
||||
(*mem)->bo = bo;
|
||||
(*mem)->va = va;
|
||||
(*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ?
|
||||
|
|
@ -2262,6 +2271,29 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
|
|||
(*mem)->is_imported = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_mem:
|
||||
kfree(*mem);
|
||||
err_put_obj:
|
||||
drm_gem_object_put(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_export_dmabuf(struct kgd_mem *mem,
|
||||
struct dma_buf **dma_buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&mem->lock);
|
||||
ret = kfd_mem_export_dmabuf(mem);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
get_dma_buf(mem->dmabuf);
|
||||
*dma_buf = mem->dmabuf;
|
||||
out:
|
||||
mutex_unlock(&mem->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Evict a userptr BO by stopping the queues if necessary
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <linux/devcoredump.h>
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/pci-p2pdma.h>
|
||||
#include <linux/apple-gmux.h>
|
||||
|
||||
#include <drm/drm_aperture.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
|
|
@ -675,20 +676,20 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
|
|||
* amdgpu_device_indirect_rreg - read an indirect register
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pcie_index: mmio register offset
|
||||
* @pcie_data: mmio register offset
|
||||
* @reg_addr: indirect register address to read from
|
||||
*
|
||||
* Returns the value of indirect register @reg_addr
|
||||
*/
|
||||
u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 r;
|
||||
unsigned long flags, pcie_index, pcie_data;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
u32 r;
|
||||
|
||||
pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
|
|
@ -706,20 +707,20 @@ u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
|
|||
* amdgpu_device_indirect_rreg64 - read a 64bits indirect register
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pcie_index: mmio register offset
|
||||
* @pcie_data: mmio register offset
|
||||
* @reg_addr: indirect register address to read from
|
||||
*
|
||||
* Returns the value of indirect register @reg_addr
|
||||
*/
|
||||
u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u64 r;
|
||||
unsigned long flags, pcie_index, pcie_data;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
u64 r;
|
||||
|
||||
pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
|
|
@ -749,13 +750,15 @@ u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
|
|||
*
|
||||
*/
|
||||
void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u32 reg_data)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long flags, pcie_index, pcie_data;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
|
||||
pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
|
||||
|
|
@ -778,13 +781,15 @@ void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
|
|||
*
|
||||
*/
|
||||
void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u64 reg_data)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long flags, pcie_index, pcie_data;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
|
||||
pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
|
||||
|
|
@ -802,6 +807,18 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
|||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_get_rev_id - query device rev_id
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Return device rev_id
|
||||
*/
|
||||
u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
return adev->nbio.funcs->get_rev_id(adev);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_invalid_rreg - dummy reg read function
|
||||
*
|
||||
|
|
@ -3773,8 +3790,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
pci_enable_pcie_error_reporting(adev->pdev);
|
||||
|
||||
/* Post card if necessary */
|
||||
if (amdgpu_device_need_post(adev)) {
|
||||
if (!adev->bios) {
|
||||
|
|
@ -3864,11 +3879,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
adev->mm_stats.log2_max_MBps = ilog2(max(1u, max_MBps));
|
||||
|
||||
r = amdgpu_pm_sysfs_init(adev);
|
||||
if (r) {
|
||||
adev->pm_sysfs_en = false;
|
||||
DRM_ERROR("registering pm debugfs failed (%d).\n", r);
|
||||
} else
|
||||
adev->pm_sysfs_en = true;
|
||||
if (r)
|
||||
DRM_ERROR("registering pm sysfs failed (%d).\n", r);
|
||||
|
||||
r = amdgpu_ucode_sysfs_init(adev);
|
||||
if (r) {
|
||||
|
|
@ -3930,12 +3942,15 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
|
||||
vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
|
||||
|
||||
if (amdgpu_device_supports_px(ddev)) {
|
||||
px = true;
|
||||
px = amdgpu_device_supports_px(ddev);
|
||||
|
||||
if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
|
||||
apple_gmux_detect(NULL, NULL)))
|
||||
vga_switcheroo_register_client(adev->pdev,
|
||||
&amdgpu_switcheroo_ops, px);
|
||||
|
||||
if (px)
|
||||
vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
|
||||
}
|
||||
|
||||
if (adev->gmc.xgmi.pending_reset)
|
||||
queue_delayed_work(system_wq, &mgpu_info.delayed_reset_work,
|
||||
|
|
@ -4011,7 +4026,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
|||
if (adev->mman.initialized)
|
||||
drain_workqueue(adev->mman.bdev.wq);
|
||||
|
||||
if (adev->pm_sysfs_en)
|
||||
if (adev->pm.sysfs_initialized)
|
||||
amdgpu_pm_sysfs_fini(adev);
|
||||
if (adev->ucode_sysfs_en)
|
||||
amdgpu_ucode_sysfs_fini(adev);
|
||||
|
|
@ -4039,6 +4054,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
|||
void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
||||
{
|
||||
int idx;
|
||||
bool px;
|
||||
|
||||
amdgpu_fence_driver_sw_fini(adev);
|
||||
amdgpu_device_ip_fini(adev);
|
||||
|
|
@ -4057,10 +4073,16 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
|||
|
||||
kfree(adev->bios);
|
||||
adev->bios = NULL;
|
||||
if (amdgpu_device_supports_px(adev_to_drm(adev))) {
|
||||
|
||||
px = amdgpu_device_supports_px(adev_to_drm(adev));
|
||||
|
||||
if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
|
||||
apple_gmux_detect(NULL, NULL)))
|
||||
vga_switcheroo_unregister_client(adev->pdev);
|
||||
|
||||
if (px)
|
||||
vga_switcheroo_fini_domain_pm_ops(adev->dev);
|
||||
}
|
||||
|
||||
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
|
||||
vga_client_unregister(adev->pdev);
|
||||
|
||||
|
|
@ -4145,8 +4167,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3))
|
||||
DRM_WARN("smart shift update failed\n");
|
||||
|
||||
drm_kms_helper_poll_disable(dev);
|
||||
|
||||
if (fbcon)
|
||||
drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
|
||||
|
||||
|
|
@ -4243,8 +4263,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
|||
if (fbcon)
|
||||
drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
|
||||
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
|
||||
amdgpu_ras_resume(adev);
|
||||
|
||||
if (adev->mode_info.num_crtc) {
|
||||
|
|
@ -5582,7 +5600,7 @@ int amdgpu_device_baco_enter(struct drm_device *dev)
|
|||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
|
||||
if (!amdgpu_device_supports_baco(adev_to_drm(adev)))
|
||||
if (!amdgpu_device_supports_baco(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (ras && adev->ras_enabled &&
|
||||
|
|
@ -5598,7 +5616,7 @@ int amdgpu_device_baco_exit(struct drm_device *dev)
|
|||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
int ret = 0;
|
||||
|
||||
if (!amdgpu_device_supports_baco(adev_to_drm(adev)))
|
||||
if (!amdgpu_device_supports_baco(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
ret = amdgpu_dpm_baco_exit(adev);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "vega10_ih.h"
|
||||
#include "vega20_ih.h"
|
||||
#include "sdma_v4_0.h"
|
||||
#include "sdma_v4_4_2.h"
|
||||
#include "uvd_v7_0.h"
|
||||
#include "vce_v4_0.h"
|
||||
#include "vcn_v1_0.h"
|
||||
|
|
@ -711,7 +712,7 @@ static void ip_hw_instance_release(struct kobject *kobj)
|
|||
kfree(ip_hw_instance);
|
||||
}
|
||||
|
||||
static struct kobj_type ip_hw_instance_ktype = {
|
||||
static const struct kobj_type ip_hw_instance_ktype = {
|
||||
.release = ip_hw_instance_release,
|
||||
.sysfs_ops = &ip_hw_instance_sysfs_ops,
|
||||
.default_groups = ip_hw_instance_groups,
|
||||
|
|
@ -730,7 +731,7 @@ static void ip_hw_id_release(struct kobject *kobj)
|
|||
kfree(ip_hw_id);
|
||||
}
|
||||
|
||||
static struct kobj_type ip_hw_id_ktype = {
|
||||
static const struct kobj_type ip_hw_id_ktype = {
|
||||
.release = ip_hw_id_release,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
};
|
||||
|
|
@ -793,18 +794,18 @@ static const struct sysfs_ops ip_die_entry_sysfs_ops = {
|
|||
.show = ip_die_entry_attr_show,
|
||||
};
|
||||
|
||||
static struct kobj_type ip_die_entry_ktype = {
|
||||
static const struct kobj_type ip_die_entry_ktype = {
|
||||
.release = ip_die_entry_release,
|
||||
.sysfs_ops = &ip_die_entry_sysfs_ops,
|
||||
.default_groups = ip_die_entry_groups,
|
||||
};
|
||||
|
||||
static struct kobj_type die_kobj_ktype = {
|
||||
static const struct kobj_type die_kobj_ktype = {
|
||||
.release = die_kobj_release,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
};
|
||||
|
||||
static struct kobj_type ip_discovery_ktype = {
|
||||
static const struct kobj_type ip_discovery_ktype = {
|
||||
.release = ip_disc_release,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
};
|
||||
|
|
@ -1591,6 +1592,7 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(4, 2, 0):
|
||||
case IP_VERSION(4, 2, 1):
|
||||
case IP_VERSION(4, 4, 0):
|
||||
case IP_VERSION(4, 4, 2):
|
||||
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||
break;
|
||||
case IP_VERSION(5, 0, 0):
|
||||
|
|
@ -1649,6 +1651,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(13, 0, 2):
|
||||
case IP_VERSION(13, 0, 3):
|
||||
case IP_VERSION(13, 0, 5):
|
||||
case IP_VERSION(13, 0, 6):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
|
|
@ -1842,6 +1845,9 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(4, 4, 0):
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(4, 4, 2):
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_4_2_ip_block);
|
||||
break;
|
||||
case IP_VERSION(5, 0, 0):
|
||||
case IP_VERSION(5, 0, 1):
|
||||
case IP_VERSION(5, 0, 2):
|
||||
|
|
@ -2304,6 +2310,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(4, 2, 0):
|
||||
case IP_VERSION(4, 2, 1):
|
||||
case IP_VERSION(4, 4, 0):
|
||||
case IP_VERSION(4, 4, 2):
|
||||
adev->hdp.funcs = &hdp_v4_0_funcs;
|
||||
break;
|
||||
case IP_VERSION(5, 0, 0):
|
||||
|
|
|
|||
|
|
@ -1618,6 +1618,8 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
|
|||
struct drm_connector_list_iter iter;
|
||||
int r;
|
||||
|
||||
drm_kms_helper_poll_disable(dev);
|
||||
|
||||
/* turn off display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
|
|
@ -1694,6 +1696,8 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev)
|
|||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,12 +60,13 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f)
|
|||
struct amdgpu_fpriv *fpriv = file->driver_priv;
|
||||
struct amdgpu_vm *vm = &fpriv->vm;
|
||||
|
||||
uint64_t vram_mem = 0, gtt_mem = 0, cpu_mem = 0;
|
||||
struct amdgpu_mem_stats stats;
|
||||
ktime_t usage[AMDGPU_HW_IP_NUM];
|
||||
uint32_t bus, dev, fn, domain;
|
||||
unsigned int hw_ip;
|
||||
int ret;
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
bus = adev->pdev->bus->number;
|
||||
domain = pci_domain_nr(adev->pdev->bus);
|
||||
dev = PCI_SLOT(adev->pdev->devfn);
|
||||
|
|
@ -75,7 +76,7 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f)
|
|||
if (ret)
|
||||
return;
|
||||
|
||||
amdgpu_vm_get_memory(vm, &vram_mem, >t_mem, &cpu_mem);
|
||||
amdgpu_vm_get_memory(vm, &stats);
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
|
||||
amdgpu_ctx_mgr_usage(&fpriv->ctx_mgr, usage);
|
||||
|
|
@ -90,9 +91,22 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f)
|
|||
seq_printf(m, "drm-driver:\t%s\n", file->minor->dev->driver->name);
|
||||
seq_printf(m, "drm-pdev:\t%04x:%02x:%02x.%d\n", domain, bus, dev, fn);
|
||||
seq_printf(m, "drm-client-id:\t%Lu\n", vm->immediate.fence_context);
|
||||
seq_printf(m, "drm-memory-vram:\t%llu KiB\n", vram_mem/1024UL);
|
||||
seq_printf(m, "drm-memory-gtt: \t%llu KiB\n", gtt_mem/1024UL);
|
||||
seq_printf(m, "drm-memory-cpu: \t%llu KiB\n", cpu_mem/1024UL);
|
||||
seq_printf(m, "drm-memory-vram:\t%llu KiB\n", stats.vram/1024UL);
|
||||
seq_printf(m, "drm-memory-gtt: \t%llu KiB\n", stats.gtt/1024UL);
|
||||
seq_printf(m, "drm-memory-cpu: \t%llu KiB\n", stats.cpu/1024UL);
|
||||
seq_printf(m, "amd-memory-visible-vram:\t%llu KiB\n",
|
||||
stats.visible_vram/1024UL);
|
||||
seq_printf(m, "amd-evicted-vram:\t%llu KiB\n",
|
||||
stats.evicted_vram/1024UL);
|
||||
seq_printf(m, "amd-evicted-visible-vram:\t%llu KiB\n",
|
||||
stats.evicted_visible_vram/1024UL);
|
||||
seq_printf(m, "amd-requested-vram:\t%llu KiB\n",
|
||||
stats.requested_vram/1024UL);
|
||||
seq_printf(m, "amd-requested-visible-vram:\t%llu KiB\n",
|
||||
stats.requested_visible_vram/1024UL);
|
||||
seq_printf(m, "amd-requested-gtt:\t%llu KiB\n",
|
||||
stats.requested_gtt/1024UL);
|
||||
|
||||
for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) {
|
||||
if (!usage[hw_ip])
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -725,7 +725,7 @@ int amdgpu_gfx_ras_sw_init(struct amdgpu_device *adev)
|
|||
|
||||
/* If not define special ras_late_init function, use gfx default ras_late_init */
|
||||
if (!ras->ras_block.ras_late_init)
|
||||
ras->ras_block.ras_late_init = amdgpu_ras_block_late_init;
|
||||
ras->ras_block.ras_late_init = amdgpu_gfx_ras_late_init;
|
||||
|
||||
/* If not defined special ras_cb function, use default ras_cb */
|
||||
if (!ras->ras_block.ras_cb)
|
||||
|
|
|
|||
|
|
@ -447,13 +447,42 @@ void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
|
|||
} while (fault->timestamp < tmp);
|
||||
}
|
||||
|
||||
int amdgpu_gmc_ras_early_init(struct amdgpu_device *adev)
|
||||
int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!adev->gmc.xgmi.connected_to_cpu) {
|
||||
adev->gmc.xgmi.ras = &xgmi_ras;
|
||||
amdgpu_ras_register_ras_block(adev, &adev->gmc.xgmi.ras->ras_block);
|
||||
adev->gmc.xgmi.ras_if = &adev->gmc.xgmi.ras->ras_block.ras_comm;
|
||||
}
|
||||
int r;
|
||||
|
||||
/* umc ras block */
|
||||
r = amdgpu_umc_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* mmhub ras block */
|
||||
r = amdgpu_mmhub_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* hdp ras block */
|
||||
r = amdgpu_hdp_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* mca.x ras block */
|
||||
r = amdgpu_mca_mp0_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_mca_mp1_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_mca_mpio_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* xgmi ras block */
|
||||
r = amdgpu_xgmi_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ struct amdgpu_vmhub {
|
|||
uint32_t vm_cntx_cntl_vm_fault;
|
||||
uint32_t vm_l2_bank_select_reserved_cid2;
|
||||
|
||||
uint32_t vm_contexts_disable;
|
||||
|
||||
const struct amdgpu_vmhub_funcs *vmhub_funcs;
|
||||
};
|
||||
|
||||
|
|
@ -351,7 +353,7 @@ bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev,
|
|||
uint16_t pasid, uint64_t timestamp);
|
||||
void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
|
||||
uint16_t pasid);
|
||||
int amdgpu_gmc_ras_early_init(struct amdgpu_device *adev);
|
||||
int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
|
||||
void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
|
||||
|
|
|
|||
48
drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.c
Normal file
48
drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 "amdgpu.h"
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
int amdgpu_hdp_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_hdp_ras *ras;
|
||||
|
||||
if (!adev->hdp.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->hdp.ras;
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register hdp ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(ras->ras_block.ras_comm.name, "hdp");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__HDP;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->hdp.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
/* hdp ras follows amdgpu_ras_block_late_init_default for late init */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -43,5 +43,5 @@ struct amdgpu_hdp {
|
|||
struct amdgpu_hdp_ras *ras;
|
||||
};
|
||||
|
||||
int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
int amdgpu_hdp_ras_sw_init(struct amdgpu_device *adev);
|
||||
#endif /* __AMDGPU_HDP_H__ */
|
||||
|
|
|
|||
|
|
@ -236,19 +236,28 @@ int amdgpu_jpeg_process_poison_irq(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void jpeg_set_ras_funcs(struct amdgpu_device *adev)
|
||||
int amdgpu_jpeg_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_jpeg_ras *ras;
|
||||
|
||||
if (!adev->jpeg.ras)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
amdgpu_ras_register_ras_block(adev, &adev->jpeg.ras->ras_block);
|
||||
ras = adev->jpeg.ras;
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register jpeg ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(adev->jpeg.ras->ras_block.ras_comm.name, "jpeg");
|
||||
adev->jpeg.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__JPEG;
|
||||
adev->jpeg.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__POISON;
|
||||
adev->jpeg.ras_if = &adev->jpeg.ras->ras_block.ras_comm;
|
||||
strcpy(ras->ras_block.ras_comm.name, "jpeg");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__JPEG;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__POISON;
|
||||
adev->jpeg.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
/* If don't define special ras_late_init function, use default ras_late_init */
|
||||
if (!adev->jpeg.ras->ras_block.ras_late_init)
|
||||
adev->jpeg.ras->ras_block.ras_late_init = amdgpu_ras_block_late_init;
|
||||
if (!ras->ras_block.ras_late_init)
|
||||
ras->ras_block.ras_late_init = amdgpu_ras_block_late_init;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,6 @@ int amdgpu_jpeg_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout);
|
|||
int amdgpu_jpeg_process_poison_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
void jpeg_set_ras_funcs(struct amdgpu_device *adev);
|
||||
int amdgpu_jpeg_ras_sw_init(struct amdgpu_device *adev);
|
||||
|
||||
#endif /*__AMDGPU_JPEG_H__*/
|
||||
|
|
|
|||
|
|
@ -70,3 +70,75 @@ void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev,
|
|||
|
||||
amdgpu_mca_reset_error_count(adev, mc_status_addr);
|
||||
}
|
||||
|
||||
int amdgpu_mca_mp0_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_mca_ras_block *ras;
|
||||
|
||||
if (!adev->mca.mp0.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->mca.mp0.ras;
|
||||
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register mca.mp0 ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(ras->ras_block.ras_comm.name, "mca.mp0");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->mca.mp0.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_mca_mp1_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_mca_ras_block *ras;
|
||||
|
||||
if (!adev->mca.mp1.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->mca.mp1.ras;
|
||||
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register mca.mp1 ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(ras->ras_block.ras_comm.name, "mca.mp1");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->mca.mp1.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_mca_ras_block *ras;
|
||||
|
||||
if (!adev->mca.mpio.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->mca.mpio.ras;
|
||||
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register mca.mpio ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(ras->ras_block.ras_comm.name, "mca.mpio");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->mca.mpio.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,12 +30,7 @@ struct amdgpu_mca_ras {
|
|||
struct amdgpu_mca_ras_block *ras;
|
||||
};
|
||||
|
||||
struct amdgpu_mca_funcs {
|
||||
void (*init)(struct amdgpu_device *adev);
|
||||
};
|
||||
|
||||
struct amdgpu_mca {
|
||||
const struct amdgpu_mca_funcs *funcs;
|
||||
struct amdgpu_mca_ras mp0;
|
||||
struct amdgpu_mca_ras mp1;
|
||||
struct amdgpu_mca_ras mpio;
|
||||
|
|
@ -55,5 +50,7 @@ void amdgpu_mca_reset_error_count(struct amdgpu_device *adev,
|
|||
void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev,
|
||||
uint64_t mc_status_addr,
|
||||
void *ras_error_status);
|
||||
|
||||
int amdgpu_mca_mp0_ras_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_mca_mp1_ras_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev);
|
||||
#endif
|
||||
|
|
|
|||
46
drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.c
Normal file
46
drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 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) 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 "amdgpu.h"
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
int amdgpu_mmhub_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_mmhub_ras *ras;
|
||||
|
||||
if (!adev->mmhub.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->mmhub.ras;
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register mmhub ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(ras->ras_block.ras_comm.name, "mmhub");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MMHUB;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->mmhub.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
/* mmhub ras follows amdgpu_ras_block_late_init_default for late init */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -48,5 +48,7 @@ struct amdgpu_mmhub {
|
|||
struct amdgpu_mmhub_ras *ras;
|
||||
};
|
||||
|
||||
int amdgpu_mmhub_ras_sw_init(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,29 @@
|
|||
#include "amdgpu.h"
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
int amdgpu_nbio_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_nbio_ras *ras;
|
||||
|
||||
if (!adev->nbio.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->nbio.ras;
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register pcie_bif ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(ras->ras_block.ras_comm.name, "pcie_bif");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__PCIE_BIF;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->nbio.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
|
||||
{
|
||||
int r;
|
||||
|
|
|
|||
|
|
@ -106,5 +106,6 @@ struct amdgpu_nbio {
|
|||
struct amdgpu_nbio_ras *ras;
|
||||
};
|
||||
|
||||
int amdgpu_nbio_ras_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1265,24 +1265,41 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
|
|||
trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
|
||||
}
|
||||
|
||||
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem,
|
||||
uint64_t *gtt_mem, uint64_t *cpu_mem)
|
||||
void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
|
||||
struct amdgpu_mem_stats *stats)
|
||||
{
|
||||
unsigned int domain;
|
||||
uint64_t size = amdgpu_bo_size(bo);
|
||||
|
||||
domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
|
||||
switch (domain) {
|
||||
case AMDGPU_GEM_DOMAIN_VRAM:
|
||||
*vram_mem += amdgpu_bo_size(bo);
|
||||
stats->vram += size;
|
||||
if (amdgpu_bo_in_cpu_visible_vram(bo))
|
||||
stats->visible_vram += size;
|
||||
break;
|
||||
case AMDGPU_GEM_DOMAIN_GTT:
|
||||
*gtt_mem += amdgpu_bo_size(bo);
|
||||
stats->gtt += size;
|
||||
break;
|
||||
case AMDGPU_GEM_DOMAIN_CPU:
|
||||
default:
|
||||
*cpu_mem += amdgpu_bo_size(bo);
|
||||
stats->cpu += size;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) {
|
||||
stats->requested_vram += size;
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
|
||||
stats->requested_visible_vram += size;
|
||||
|
||||
if (domain != AMDGPU_GEM_DOMAIN_VRAM) {
|
||||
stats->evicted_vram += size;
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
|
||||
stats->evicted_visible_vram += size;
|
||||
}
|
||||
} else if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_GTT) {
|
||||
stats->requested_gtt += size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -126,6 +126,27 @@ struct amdgpu_bo_vm {
|
|||
struct amdgpu_vm_bo_base entries[];
|
||||
};
|
||||
|
||||
struct amdgpu_mem_stats {
|
||||
/* current VRAM usage, includes visible VRAM */
|
||||
uint64_t vram;
|
||||
/* current visible VRAM usage */
|
||||
uint64_t visible_vram;
|
||||
/* current GTT usage */
|
||||
uint64_t gtt;
|
||||
/* current system memory usage */
|
||||
uint64_t cpu;
|
||||
/* sum of evicted buffers, includes visible VRAM */
|
||||
uint64_t evicted_vram;
|
||||
/* sum of evicted buffers due to CPU access */
|
||||
uint64_t evicted_visible_vram;
|
||||
/* how much userspace asked for, includes vis.VRAM */
|
||||
uint64_t requested_vram;
|
||||
/* how much userspace asked for */
|
||||
uint64_t requested_visible_vram;
|
||||
/* how much userspace asked for */
|
||||
uint64_t requested_gtt;
|
||||
};
|
||||
|
||||
static inline struct amdgpu_bo *ttm_to_amdgpu_bo(struct ttm_buffer_object *tbo)
|
||||
{
|
||||
return container_of(tbo, struct amdgpu_bo, tbo);
|
||||
|
|
@ -325,8 +346,8 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv,
|
|||
int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr);
|
||||
u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo);
|
||||
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo);
|
||||
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem,
|
||||
uint64_t *gtt_mem, uint64_t *cpu_mem);
|
||||
void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
|
||||
struct amdgpu_mem_stats *stats);
|
||||
void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo);
|
||||
int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow,
|
||||
struct dma_fence **fence);
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ static int psp_early_init(void *handle)
|
|||
psp_v12_0_set_psp_funcs(psp);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 2):
|
||||
case IP_VERSION(13, 0, 6):
|
||||
psp_v13_0_set_psp_funcs(psp);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 1):
|
||||
|
|
|
|||
|
|
@ -2554,21 +2554,24 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
|
|||
/* initialize nbio ras function ahead of any other
|
||||
* ras functions so hardware fatal error interrupt
|
||||
* can be enabled as early as possible */
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_ALDEBARAN:
|
||||
if (!adev->gmc.xgmi.connected_to_cpu) {
|
||||
switch (adev->ip_versions[NBIO_HWIP][0]) {
|
||||
case IP_VERSION(7, 4, 0):
|
||||
case IP_VERSION(7, 4, 1):
|
||||
case IP_VERSION(7, 4, 4):
|
||||
if (!adev->gmc.xgmi.connected_to_cpu)
|
||||
adev->nbio.ras = &nbio_v7_4_ras;
|
||||
amdgpu_ras_register_ras_block(adev, &adev->nbio.ras->ras_block);
|
||||
adev->nbio.ras_if = &adev->nbio.ras->ras_block.ras_comm;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* nbio ras is not available */
|
||||
break;
|
||||
}
|
||||
|
||||
/* nbio ras block needs to be enabled ahead of other ras blocks
|
||||
* to handle fatal error */
|
||||
r = amdgpu_nbio_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (adev->nbio.ras &&
|
||||
adev->nbio.ras->init_ras_controller_interrupt) {
|
||||
r = adev->nbio.ras->init_ras_controller_interrupt(adev);
|
||||
|
|
@ -3073,9 +3076,6 @@ int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
|
|||
if (!adev || !ras_block_obj)
|
||||
return -EINVAL;
|
||||
|
||||
if (!amdgpu_ras_asic_supported(adev))
|
||||
return 0;
|
||||
|
||||
ras_node = kzalloc(sizeof(*ras_node), GFP_KERNEL);
|
||||
if (!ras_node)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -208,6 +208,36 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
|
|||
return amdgpu_umc_do_page_retirement(adev, ras_error_status, entry, true);
|
||||
}
|
||||
|
||||
int amdgpu_umc_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_umc_ras *ras;
|
||||
|
||||
if (!adev->umc.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->umc.ras;
|
||||
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register umc ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(adev->umc.ras->ras_block.ras_comm.name, "umc");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__UMC;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->umc.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
if (!ras->ras_block.ras_late_init)
|
||||
ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
|
||||
|
||||
if (ras->ras_block.ras_cb)
|
||||
ras->ras_block.ras_cb = amdgpu_umc_process_ras_data_cb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
|
||||
{
|
||||
int r;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ struct amdgpu_umc {
|
|||
unsigned long active_mask;
|
||||
};
|
||||
|
||||
int amdgpu_umc_ras_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev, bool reset);
|
||||
int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -1118,14 +1118,11 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct dma_fence *f = NULL;
|
||||
uint32_t offset, data[4];
|
||||
struct amdgpu_job *job;
|
||||
struct amdgpu_ib *ib;
|
||||
uint32_t data[4];
|
||||
uint64_t addr;
|
||||
long r;
|
||||
int i;
|
||||
unsigned offset_idx = 0;
|
||||
unsigned offset[3] = { UVD_BASE_SI, 0, 0 };
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, &adev->uvd.entity,
|
||||
AMDGPU_FENCE_OWNER_UNDEFINED,
|
||||
|
|
@ -1134,16 +1131,15 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (adev->asic_type >= CHIP_VEGA10) {
|
||||
offset_idx = 1 + ring->me;
|
||||
offset[1] = adev->reg_offset[UVD_HWIP][0][1];
|
||||
offset[2] = adev->reg_offset[UVD_HWIP][1][1];
|
||||
}
|
||||
if (adev->asic_type >= CHIP_VEGA10)
|
||||
offset = adev->reg_offset[UVD_HWIP][ring->me][1];
|
||||
else
|
||||
offset = UVD_BASE_SI;
|
||||
|
||||
data[0] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_DATA0, 0);
|
||||
data[1] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_DATA1, 0);
|
||||
data[2] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_CMD, 0);
|
||||
data[3] = PACKET0(offset[offset_idx] + UVD_NO_OP, 0);
|
||||
data[0] = PACKET0(offset + UVD_GPCOM_VCPU_DATA0, 0);
|
||||
data[1] = PACKET0(offset + UVD_GPCOM_VCPU_DATA1, 0);
|
||||
data[2] = PACKET0(offset + UVD_GPCOM_VCPU_CMD, 0);
|
||||
data[3] = PACKET0(offset + UVD_NO_OP, 0);
|
||||
|
||||
ib = &job->ibs[0];
|
||||
addr = amdgpu_bo_gpu_offset(bo);
|
||||
|
|
@ -1160,14 +1156,6 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||
ib->length_dw = 16;
|
||||
|
||||
if (direct) {
|
||||
r = dma_resv_wait_timeout(bo->tbo.base.resv,
|
||||
DMA_RESV_USAGE_KERNEL, false,
|
||||
msecs_to_jiffies(10));
|
||||
if (r == 0)
|
||||
r = -ETIMEDOUT;
|
||||
if (r < 0)
|
||||
goto err_free;
|
||||
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
if (r)
|
||||
goto err_free;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <drm/drm_drv.h>
|
||||
|
|
@ -114,6 +115,24 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||
adev->vcn.indirect_sram = true;
|
||||
|
||||
/*
|
||||
* Some Steam Deck's BIOS versions are incompatible with the
|
||||
* indirect SRAM mode, leading to amdgpu being unable to get
|
||||
* properly probed (and even potentially crashing the kernel).
|
||||
* Hence, check for these versions here - notice this is
|
||||
* restricted to Vangogh (Deck's APU).
|
||||
*/
|
||||
if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(3, 0, 2)) {
|
||||
const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
|
||||
|
||||
if (bios_ver && (!strncmp("F7A0113", bios_ver, 7) ||
|
||||
!strncmp("F7A0114", bios_ver, 7))) {
|
||||
adev->vcn.indirect_sram = false;
|
||||
dev_info(adev->dev,
|
||||
"Steam Deck quirk: indirect SRAM disabled on BIOS %s\n", bios_ver);
|
||||
}
|
||||
}
|
||||
|
||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||
adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
|
||||
|
||||
|
|
@ -1162,19 +1181,28 @@ int amdgpu_vcn_process_poison_irq(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_vcn_set_ras_funcs(struct amdgpu_device *adev)
|
||||
int amdgpu_vcn_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_vcn_ras *ras;
|
||||
|
||||
if (!adev->vcn.ras)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
amdgpu_ras_register_ras_block(adev, &adev->vcn.ras->ras_block);
|
||||
ras = adev->vcn.ras;
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register vcn ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(adev->vcn.ras->ras_block.ras_comm.name, "vcn");
|
||||
adev->vcn.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__VCN;
|
||||
adev->vcn.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__POISON;
|
||||
adev->vcn.ras_if = &adev->vcn.ras->ras_block.ras_comm;
|
||||
strcpy(ras->ras_block.ras_comm.name, "vcn");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__VCN;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__POISON;
|
||||
adev->vcn.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
/* If don't define special ras_late_init function, use default ras_late_init */
|
||||
if (!adev->vcn.ras->ras_block.ras_late_init)
|
||||
adev->vcn.ras->ras_block.ras_late_init = amdgpu_ras_block_late_init;
|
||||
if (!ras->ras_block.ras_late_init)
|
||||
ras->ras_block.ras_late_init = amdgpu_ras_block_late_init;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,6 +400,6 @@ void amdgpu_debugfs_vcn_fwlog_init(struct amdgpu_device *adev,
|
|||
int amdgpu_vcn_process_poison_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
void amdgpu_vcn_set_ras_funcs(struct amdgpu_device *adev);
|
||||
int amdgpu_vcn_ras_sw_init(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ enum AMDGIM_FEATURE_FLAG {
|
|||
AMDGIM_FEATURE_PP_ONE_VF = (1 << 4),
|
||||
/* Indirect Reg Access enabled */
|
||||
AMDGIM_FEATURE_INDIRECT_REG_ACCESS = (1 << 5),
|
||||
/* AV1 Support MODE*/
|
||||
AMDGIM_FEATURE_AV1_SUPPORT = (1 << 6),
|
||||
};
|
||||
|
||||
enum AMDGIM_REG_ACCESS_FLAG {
|
||||
|
|
@ -322,6 +324,8 @@ static inline bool is_virtual_machine(void)
|
|||
((!amdgpu_in_reset(adev)) && adev->virt.tdr_debug)
|
||||
#define amdgpu_sriov_is_normal(adev) \
|
||||
((!amdgpu_in_reset(adev)) && (!adev->virt.tdr_debug))
|
||||
#define amdgpu_sriov_is_av1_support(adev) \
|
||||
((adev)->virt.gim_feature & AMDGIM_FEATURE_AV1_SUPPORT)
|
||||
bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -867,6 +867,8 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
pages_addr[idx - 1] + PAGE_SIZE))
|
||||
break;
|
||||
}
|
||||
if (!contiguous)
|
||||
count--;
|
||||
num_entries = count *
|
||||
AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||
}
|
||||
|
|
@ -918,8 +920,8 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
return r;
|
||||
}
|
||||
|
||||
void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
||||
uint64_t *gtt_mem, uint64_t *cpu_mem)
|
||||
void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
|
||||
struct amdgpu_mem_stats *stats)
|
||||
{
|
||||
struct amdgpu_bo_va *bo_va, *tmp;
|
||||
|
||||
|
|
@ -927,41 +929,36 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
|||
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, stats);
|
||||
}
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, stats);
|
||||
}
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, stats);
|
||||
}
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, stats);
|
||||
}
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, stats);
|
||||
}
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->done, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, stats);
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_bo_update - update all BO mappings in the vm page table
|
||||
*
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct amdgpu_bo_va;
|
|||
struct amdgpu_job;
|
||||
struct amdgpu_bo_list_entry;
|
||||
struct amdgpu_bo_vm;
|
||||
struct amdgpu_mem_stats;
|
||||
|
||||
/*
|
||||
* GPUVM handling
|
||||
|
|
@ -457,8 +458,8 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm);
|
|||
|
||||
void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm);
|
||||
void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
||||
uint64_t *gtt_mem, uint64_t *cpu_mem);
|
||||
void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
|
||||
struct amdgpu_mem_stats *stats);
|
||||
|
||||
int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct amdgpu_bo_vm *vmbo, bool immediate);
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ static const struct sysfs_ops amdgpu_xgmi_hive_ops = {
|
|||
.show = amdgpu_xgmi_show_attrs,
|
||||
};
|
||||
|
||||
struct kobj_type amdgpu_xgmi_hive_type = {
|
||||
static const struct kobj_type amdgpu_xgmi_hive_type = {
|
||||
.release = amdgpu_xgmi_hive_release,
|
||||
.sysfs_ops = &amdgpu_xgmi_hive_ops,
|
||||
.default_groups = amdgpu_xgmi_hive_groups,
|
||||
|
|
@ -1048,12 +1048,30 @@ struct amdgpu_ras_block_hw_ops xgmi_ras_hw_ops = {
|
|||
|
||||
struct amdgpu_xgmi_ras xgmi_ras = {
|
||||
.ras_block = {
|
||||
.ras_comm = {
|
||||
.name = "xgmi_wafl",
|
||||
.block = AMDGPU_RAS_BLOCK__XGMI_WAFL,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
},
|
||||
.hw_ops = &xgmi_ras_hw_ops,
|
||||
.ras_late_init = amdgpu_xgmi_ras_late_init,
|
||||
},
|
||||
};
|
||||
|
||||
int amdgpu_xgmi_ras_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int err;
|
||||
struct amdgpu_xgmi_ras *ras;
|
||||
|
||||
if (!adev->gmc.xgmi.ras)
|
||||
return 0;
|
||||
|
||||
ras = adev->gmc.xgmi.ras;
|
||||
err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "Failed to register xgmi_wafl_pcs ras block!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
strcpy(ras->ras_block.ras_comm.name, "xgmi_wafl_pcs");
|
||||
ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__XGMI_WAFL;
|
||||
ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->gmc.xgmi.ras_if = &ras->ras_block.ras_comm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,5 +73,6 @@ static inline bool amdgpu_xgmi_same_hive(struct amdgpu_device *adev,
|
|||
adev->gmc.xgmi.hive_id &&
|
||||
adev->gmc.xgmi.hive_id == bo_adev->gmc.xgmi.hive_id);
|
||||
}
|
||||
int amdgpu_xgmi_ras_sw_init(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ union amd_sriov_msg_feature_flags {
|
|||
uint32_t mm_bw_management : 1;
|
||||
uint32_t pp_one_vf_mode : 1;
|
||||
uint32_t reg_indirect_acc : 1;
|
||||
uint32_t reserved : 26;
|
||||
uint32_t av1_support : 1;
|
||||
uint32_t reserved : 25;
|
||||
} flags;
|
||||
uint32_t all;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7266,7 +7266,6 @@ static int gfx_v10_0_hw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
uint32_t tmp;
|
||||
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
||||
|
|
@ -7285,17 +7284,9 @@ static int gfx_v10_0_hw_fini(void *handle)
|
|||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
gfx_v10_0_cp_gfx_enable(adev, false);
|
||||
/* Program KIQ position of RLC_CP_SCHEDULERS during destroy */
|
||||
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) {
|
||||
tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid);
|
||||
tmp &= 0xffffff00;
|
||||
WREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid, tmp);
|
||||
} else {
|
||||
tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS);
|
||||
tmp &= 0xffffff00;
|
||||
WREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS, tmp);
|
||||
}
|
||||
|
||||
/* Remove the steps of clearing KIQ position.
|
||||
* It causes GFX hang when another Win guest is rendering.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
gfx_v10_0_cp_enable(adev, false);
|
||||
|
|
|
|||
|
|
@ -699,25 +699,8 @@ static void gmc_v10_0_set_umc_funcs(struct amdgpu_device *adev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (adev->umc.ras) {
|
||||
amdgpu_ras_register_ras_block(adev, &adev->umc.ras->ras_block);
|
||||
|
||||
strcpy(adev->umc.ras->ras_block.ras_comm.name, "umc");
|
||||
adev->umc.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__UMC;
|
||||
adev->umc.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->umc.ras_if = &adev->umc.ras->ras_block.ras_comm;
|
||||
|
||||
/* If don't define special ras_late_init function, use default ras_late_init */
|
||||
if (!adev->umc.ras->ras_block.ras_late_init)
|
||||
adev->umc.ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
|
||||
|
||||
/* If not defined special ras_cb function, use default ras_cb */
|
||||
if (!adev->umc.ras->ras_block.ras_cb)
|
||||
adev->umc.ras->ras_block.ras_cb = amdgpu_umc_process_ras_data_cb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void gmc_v10_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->ip_versions[MMHUB_HWIP][0]) {
|
||||
|
|
@ -754,7 +737,6 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
|||
|
||||
static int gmc_v10_0_early_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
gmc_v10_0_set_mmhub_funcs(adev);
|
||||
|
|
@ -770,10 +752,6 @@ static int gmc_v10_0_early_init(void *handle)
|
|||
adev->gmc.private_aperture_end =
|
||||
adev->gmc.private_aperture_start + (4ULL << 30) - 1;
|
||||
|
||||
r = amdgpu_gmc_ras_early_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1024,6 +1002,10 @@ static int gmc_v10_0_sw_init(void *handle)
|
|||
|
||||
amdgpu_vm_manager_init(adev);
|
||||
|
||||
r = amdgpu_gmc_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -581,23 +581,6 @@ static void gmc_v11_0_set_umc_funcs(struct amdgpu_device *adev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (adev->umc.ras) {
|
||||
amdgpu_ras_register_ras_block(adev, &adev->umc.ras->ras_block);
|
||||
|
||||
strcpy(adev->umc.ras->ras_block.ras_comm.name, "umc");
|
||||
adev->umc.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__UMC;
|
||||
adev->umc.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->umc.ras_if = &adev->umc.ras->ras_block.ras_comm;
|
||||
|
||||
/* If don't define special ras_late_init function, use default ras_late_init */
|
||||
if (!adev->umc.ras->ras_block.ras_late_init)
|
||||
adev->umc.ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
|
||||
|
||||
/* If not define special ras_cb function, use default ras_cb */
|
||||
if (!adev->umc.ras->ras_block.ras_cb)
|
||||
adev->umc.ras->ras_block.ras_cb = amdgpu_umc_process_ras_data_cb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -846,6 +829,10 @@ static int gmc_v11_0_sw_init(void *handle)
|
|||
|
||||
amdgpu_vm_manager_init(adev);
|
||||
|
||||
r = amdgpu_gmc_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -875,6 +862,12 @@ static int gmc_v11_0_sw_fini(void *handle)
|
|||
|
||||
static void gmc_v11_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
|
||||
WREG32(hub->vm_contexts_disable, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1318,23 +1318,6 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (adev->umc.ras) {
|
||||
amdgpu_ras_register_ras_block(adev, &adev->umc.ras->ras_block);
|
||||
|
||||
strcpy(adev->umc.ras->ras_block.ras_comm.name, "umc");
|
||||
adev->umc.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__UMC;
|
||||
adev->umc.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->umc.ras_if = &adev->umc.ras->ras_block.ras_comm;
|
||||
|
||||
/* If don't define special ras_late_init function, use default ras_late_init */
|
||||
if (!adev->umc.ras->ras_block.ras_late_init)
|
||||
adev->umc.ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
|
||||
|
||||
/* If not defined special ras_cb function, use default ras_cb */
|
||||
if (!adev->umc.ras->ras_block.ras_cb)
|
||||
adev->umc.ras->ras_block.ras_cb = amdgpu_umc_process_ras_data_cb;
|
||||
}
|
||||
}
|
||||
|
||||
static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
||||
|
|
@ -1368,15 +1351,6 @@ static void gmc_v9_0_set_mmhub_ras_funcs(struct amdgpu_device *adev)
|
|||
/* mmhub ras is not available */
|
||||
break;
|
||||
}
|
||||
|
||||
if (adev->mmhub.ras) {
|
||||
amdgpu_ras_register_ras_block(adev, &adev->mmhub.ras->ras_block);
|
||||
|
||||
strcpy(adev->mmhub.ras->ras_block.ras_comm.name, "mmhub");
|
||||
adev->mmhub.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MMHUB;
|
||||
adev->mmhub.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
adev->mmhub.ras_if = &adev->mmhub.ras->ras_block.ras_comm;
|
||||
}
|
||||
}
|
||||
|
||||
static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
||||
|
|
@ -1387,26 +1361,34 @@ static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
|||
static void gmc_v9_0_set_hdp_ras_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->hdp.ras = &hdp_v4_0_ras;
|
||||
amdgpu_ras_register_ras_block(adev, &adev->hdp.ras->ras_block);
|
||||
adev->hdp.ras_if = &adev->hdp.ras->ras_block.ras_comm;
|
||||
}
|
||||
|
||||
static void gmc_v9_0_set_mca_funcs(struct amdgpu_device *adev)
|
||||
static void gmc_v9_0_set_mca_ras_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_mca *mca = &adev->mca;
|
||||
|
||||
/* is UMC the right IP to check for MCA? Maybe DF? */
|
||||
switch (adev->ip_versions[UMC_HWIP][0]) {
|
||||
case IP_VERSION(6, 7, 0):
|
||||
if (!adev->gmc.xgmi.connected_to_cpu)
|
||||
adev->mca.funcs = &mca_v3_0_funcs;
|
||||
if (!adev->gmc.xgmi.connected_to_cpu) {
|
||||
mca->mp0.ras = &mca_v3_0_mp0_ras;
|
||||
mca->mp1.ras = &mca_v3_0_mp1_ras;
|
||||
mca->mpio.ras = &mca_v3_0_mpio_ras;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gmc_v9_0_set_xgmi_ras_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!adev->gmc.xgmi.connected_to_cpu)
|
||||
adev->gmc.xgmi.ras = &xgmi_ras;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_early_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* ARCT and VEGA20 don't have XGMI defined in their IP discovery tables */
|
||||
|
|
@ -1427,7 +1409,8 @@ static int gmc_v9_0_early_init(void *handle)
|
|||
gmc_v9_0_set_mmhub_ras_funcs(adev);
|
||||
gmc_v9_0_set_gfxhub_funcs(adev);
|
||||
gmc_v9_0_set_hdp_ras_funcs(adev);
|
||||
gmc_v9_0_set_mca_funcs(adev);
|
||||
gmc_v9_0_set_mca_ras_funcs(adev);
|
||||
gmc_v9_0_set_xgmi_ras_funcs(adev);
|
||||
|
||||
adev->gmc.shared_aperture_start = 0x2000000000000000ULL;
|
||||
adev->gmc.shared_aperture_end =
|
||||
|
|
@ -1436,10 +1419,6 @@ static int gmc_v9_0_early_init(void *handle)
|
|||
adev->gmc.private_aperture_end =
|
||||
adev->gmc.private_aperture_start + (4ULL << 30) - 1;
|
||||
|
||||
r = amdgpu_gmc_ras_early_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1644,8 +1623,6 @@ static int gmc_v9_0_sw_init(void *handle)
|
|||
adev->gfxhub.funcs->init(adev);
|
||||
|
||||
adev->mmhub.funcs->init(adev);
|
||||
if (adev->mca.funcs)
|
||||
adev->mca.funcs->init(adev);
|
||||
|
||||
spin_lock_init(&adev->gmc.invalidate_lock);
|
||||
|
||||
|
|
@ -1798,6 +1775,10 @@ static int gmc_v9_0_sw_init(void *handle)
|
|||
|
||||
gmc_v9_0_save_registers(adev);
|
||||
|
||||
r = amdgpu_gmc_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@ static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev,
|
|||
static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring)
|
||||
{
|
||||
if (adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 4, 0))
|
||||
if (adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 4, 0) ||
|
||||
adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 4, 2))
|
||||
return;
|
||||
|
||||
if (!ring || !ring->funcs->emit_wreg)
|
||||
|
|
@ -160,11 +161,6 @@ struct amdgpu_ras_block_hw_ops hdp_v4_0_ras_hw_ops = {
|
|||
|
||||
struct amdgpu_hdp_ras hdp_v4_0_ras = {
|
||||
.ras_block = {
|
||||
.ras_comm = {
|
||||
.name = "hdp",
|
||||
.block = AMDGPU_RAS_BLOCK__HDP,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
},
|
||||
.hw_ops = &hdp_v4_0_ras_hw_ops,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -138,6 +138,10 @@ static int jpeg_v2_5_sw_init(void *handle)
|
|||
adev->jpeg.inst[i].external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_PITCH);
|
||||
}
|
||||
|
||||
r = amdgpu_jpeg_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -806,6 +810,4 @@ static void jpeg_v2_5_set_ras_funcs(struct amdgpu_device *adev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
jpeg_set_ras_funcs(adev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ static int jpeg_v4_0_sw_init(void *handle)
|
|||
adev->jpeg.internal.jpeg_pitch = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
|
||||
adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH);
|
||||
|
||||
r = amdgpu_jpeg_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -685,6 +689,4 @@ static void jpeg_v4_0_set_ras_funcs(struct amdgpu_device *adev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
jpeg_set_ras_funcs(adev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,19 +51,13 @@ static int mca_v3_0_ras_block_match(struct amdgpu_ras_block_object *block_obj,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
const struct amdgpu_ras_block_hw_ops mca_v3_0_mp0_hw_ops = {
|
||||
static const struct amdgpu_ras_block_hw_ops mca_v3_0_mp0_hw_ops = {
|
||||
.query_ras_error_count = mca_v3_0_mp0_query_ras_error_count,
|
||||
.query_ras_error_address = NULL,
|
||||
};
|
||||
|
||||
struct amdgpu_mca_ras_block mca_v3_0_mp0_ras = {
|
||||
.ras_block = {
|
||||
.ras_comm = {
|
||||
.block = AMDGPU_RAS_BLOCK__MCA,
|
||||
.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP0,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
.name = "mp0",
|
||||
},
|
||||
.hw_ops = &mca_v3_0_mp0_hw_ops,
|
||||
.ras_block_match = mca_v3_0_ras_block_match,
|
||||
},
|
||||
|
|
@ -77,19 +71,13 @@ static void mca_v3_0_mp1_query_ras_error_count(struct amdgpu_device *adev,
|
|||
ras_error_status);
|
||||
}
|
||||
|
||||
const struct amdgpu_ras_block_hw_ops mca_v3_0_mp1_hw_ops = {
|
||||
static const struct amdgpu_ras_block_hw_ops mca_v3_0_mp1_hw_ops = {
|
||||
.query_ras_error_count = mca_v3_0_mp1_query_ras_error_count,
|
||||
.query_ras_error_address = NULL,
|
||||
};
|
||||
|
||||
struct amdgpu_mca_ras_block mca_v3_0_mp1_ras = {
|
||||
.ras_block = {
|
||||
.ras_comm = {
|
||||
.block = AMDGPU_RAS_BLOCK__MCA,
|
||||
.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP1,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
.name = "mp1",
|
||||
},
|
||||
.hw_ops = &mca_v3_0_mp1_hw_ops,
|
||||
.ras_block_match = mca_v3_0_ras_block_match,
|
||||
},
|
||||
|
|
@ -103,40 +91,14 @@ static void mca_v3_0_mpio_query_ras_error_count(struct amdgpu_device *adev,
|
|||
ras_error_status);
|
||||
}
|
||||
|
||||
const struct amdgpu_ras_block_hw_ops mca_v3_0_mpio_hw_ops = {
|
||||
static const struct amdgpu_ras_block_hw_ops mca_v3_0_mpio_hw_ops = {
|
||||
.query_ras_error_count = mca_v3_0_mpio_query_ras_error_count,
|
||||
.query_ras_error_address = NULL,
|
||||
};
|
||||
|
||||
struct amdgpu_mca_ras_block mca_v3_0_mpio_ras = {
|
||||
.ras_block = {
|
||||
.ras_comm = {
|
||||
.block = AMDGPU_RAS_BLOCK__MCA,
|
||||
.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MPIO,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
.name = "mpio",
|
||||
},
|
||||
.hw_ops = &mca_v3_0_mpio_hw_ops,
|
||||
.ras_block_match = mca_v3_0_ras_block_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static void mca_v3_0_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_mca *mca = &adev->mca;
|
||||
|
||||
mca->mp0.ras = &mca_v3_0_mp0_ras;
|
||||
mca->mp1.ras = &mca_v3_0_mp1_ras;
|
||||
mca->mpio.ras = &mca_v3_0_mpio_ras;
|
||||
amdgpu_ras_register_ras_block(adev, &mca->mp0.ras->ras_block);
|
||||
amdgpu_ras_register_ras_block(adev, &mca->mp1.ras->ras_block);
|
||||
amdgpu_ras_register_ras_block(adev, &mca->mpio.ras->ras_block);
|
||||
mca->mp0.ras_if = &mca->mp0.ras->ras_block.ras_comm;
|
||||
mca->mp1.ras_if = &mca->mp1.ras->ras_block.ras_comm;
|
||||
mca->mpio.ras_if = &mca->mpio.ras->ras_block.ras_comm;
|
||||
}
|
||||
|
||||
const struct amdgpu_mca_funcs mca_v3_0_funcs = {
|
||||
.init = mca_v3_0_init,
|
||||
};
|
||||
|
|
@ -21,6 +21,8 @@
|
|||
#ifndef __MCA_V3_0_H__
|
||||
#define __MCA_V3_0_H__
|
||||
|
||||
extern const struct amdgpu_mca_funcs mca_v3_0_funcs;
|
||||
extern struct amdgpu_mca_ras_block mca_v3_0_mp0_ras;
|
||||
extern struct amdgpu_mca_ras_block mca_v3_0_mp1_ras;
|
||||
extern struct amdgpu_mca_ras_block mca_v3_0_mpio_ras;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -517,6 +517,9 @@ static void mmhub_v3_0_init(struct amdgpu_device *adev)
|
|||
hub->vm_l2_bank_select_reserved_cid2 =
|
||||
SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_BANK_SELECT_RESERVED_CID2);
|
||||
|
||||
hub->vm_contexts_disable =
|
||||
SOC15_REG_OFFSET(MMHUB, 0, regMMVM_CONTEXTS_DISABLE);
|
||||
|
||||
hub->vmhub_funcs = &mmhub_v3_0_vmhub_funcs;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -280,47 +280,6 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Indirect registers accessor
|
||||
*/
|
||||
static u32 nv_pcie_rreg(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long address, data;
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
return amdgpu_device_indirect_rreg(adev, address, data, reg);
|
||||
}
|
||||
|
||||
static void nv_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
|
||||
{
|
||||
unsigned long address, data;
|
||||
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
amdgpu_device_indirect_wreg(adev, address, data, reg, v);
|
||||
}
|
||||
|
||||
static u64 nv_pcie_rreg64(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long address, data;
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
return amdgpu_device_indirect_rreg64(adev, address, data, reg);
|
||||
}
|
||||
|
||||
static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
|
||||
{
|
||||
unsigned long address, data;
|
||||
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
amdgpu_device_indirect_wreg64(adev, address, data, reg, v);
|
||||
}
|
||||
|
||||
static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long flags, address, data;
|
||||
|
|
@ -561,21 +520,6 @@ static int nv_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void nv_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
|
||||
CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
|
||||
return;
|
||||
|
||||
/* todo */
|
||||
}
|
||||
|
||||
static void nv_program_aspm(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_device_should_use_aspm(adev))
|
||||
|
|
@ -608,11 +552,6 @@ void nv_set_virt_ops(struct amdgpu_device *adev)
|
|||
adev->virt.ops = &xgpu_nv_virt_ops;
|
||||
}
|
||||
|
||||
static uint32_t nv_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
return adev->nbio.funcs->get_rev_id(adev);
|
||||
}
|
||||
|
||||
static bool nv_need_full_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
return true;
|
||||
|
|
@ -738,10 +677,10 @@ static int nv_common_early_init(void *handle)
|
|||
}
|
||||
adev->smc_rreg = NULL;
|
||||
adev->smc_wreg = NULL;
|
||||
adev->pcie_rreg = &nv_pcie_rreg;
|
||||
adev->pcie_wreg = &nv_pcie_wreg;
|
||||
adev->pcie_rreg64 = &nv_pcie_rreg64;
|
||||
adev->pcie_wreg64 = &nv_pcie_wreg64;
|
||||
adev->pcie_rreg = &amdgpu_device_indirect_rreg;
|
||||
adev->pcie_wreg = &amdgpu_device_indirect_wreg;
|
||||
adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
|
||||
adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
|
||||
adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
|
||||
adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
|
||||
|
||||
|
|
@ -754,7 +693,7 @@ static int nv_common_early_init(void *handle)
|
|||
|
||||
adev->asic_funcs = &nv_asic_funcs;
|
||||
|
||||
adev->rev_id = nv_get_rev_id(adev);
|
||||
adev->rev_id = amdgpu_device_get_rev_id(adev);
|
||||
adev->external_rev_id = 0xff;
|
||||
/* TODO: split the GC and PG flags based on the relevant IP version for which
|
||||
* they are relevant.
|
||||
|
|
@ -1055,8 +994,8 @@ static int nv_common_late_init(void *handle)
|
|||
amdgpu_virt_update_sriov_video_codec(adev,
|
||||
sriov_sc_video_codecs_encode_array,
|
||||
ARRAY_SIZE(sriov_sc_video_codecs_encode_array),
|
||||
sriov_sc_video_codecs_decode_array_vcn1,
|
||||
ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn1));
|
||||
sriov_sc_video_codecs_decode_array_vcn0,
|
||||
ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1088,8 +1027,6 @@ static int nv_common_hw_init(void *handle)
|
|||
if (adev->nbio.funcs->apply_l1_link_width_reconfig_wa)
|
||||
adev->nbio.funcs->apply_l1_link_width_reconfig_wa(adev);
|
||||
|
||||
/* enable pcie gen2/3 link */
|
||||
nv_pcie_gen3_enable(adev);
|
||||
/* enable aspm */
|
||||
nv_program_aspm(adev);
|
||||
/* setup nbio registers */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
|
|||
MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_13_0_6_sos.bin");
|
||||
|
||||
/* For large FW files the time to complete can be very long */
|
||||
#define USBC_PD_POLLING_LIMIT_S 240
|
||||
|
|
@ -100,6 +101,7 @@ static int psp_v13_0_init_microcode(struct psp_context *psp)
|
|||
return err;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
case IP_VERSION(13, 0, 6):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
err = psp_init_sos_microcode(psp, ucode_prefix);
|
||||
|
|
|
|||
1967
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
Normal file
1967
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-15 Advanced Micro Devices, Inc.
|
||||
* Copyright 2022 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"),
|
||||
|
|
@ -19,9 +19,12 @@
|
|||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO - remove this file after external build dependencies is resolved.
|
||||
/* NOTE: This file is pending to be removed, do not add new code to this file */
|
||||
#ifndef __SDMA_V4_4_2_H__
|
||||
#define __SDMA_V4_4_2_H__
|
||||
|
||||
extern const struct amd_ip_funcs sdma_v4_4_2_ip_funcs;
|
||||
extern const struct amdgpu_ip_block_version sdma_v4_4_2_ip_block;
|
||||
|
||||
#endif
|
||||
|
|
@ -191,47 +191,6 @@ static int soc15_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Indirect registers accessor
|
||||
*/
|
||||
static u32 soc15_pcie_rreg(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long address, data;
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
return amdgpu_device_indirect_rreg(adev, address, data, reg);
|
||||
}
|
||||
|
||||
static void soc15_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
|
||||
{
|
||||
unsigned long address, data;
|
||||
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
amdgpu_device_indirect_wreg(adev, address, data, reg, v);
|
||||
}
|
||||
|
||||
static u64 soc15_pcie_rreg64(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long address, data;
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
return amdgpu_device_indirect_rreg64(adev, address, data, reg);
|
||||
}
|
||||
|
||||
static void soc15_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
|
||||
{
|
||||
unsigned long address, data;
|
||||
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
amdgpu_device_indirect_wreg64(adev, address, data, reg, v);
|
||||
}
|
||||
|
||||
static u32 soc15_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long flags, address, data;
|
||||
|
|
@ -651,24 +610,6 @@ static int soc15_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void soc15_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return;
|
||||
|
||||
if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
|
||||
CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
|
||||
return;
|
||||
|
||||
/* todo */
|
||||
}
|
||||
|
||||
static void soc15_program_aspm(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_device_should_use_aspm(adev))
|
||||
|
|
@ -695,11 +636,6 @@ const struct amdgpu_ip_block_version vega10_common_ip_block =
|
|||
.funcs = &soc15_common_ip_funcs,
|
||||
};
|
||||
|
||||
static uint32_t soc15_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
return adev->nbio.funcs->get_rev_id(adev);
|
||||
}
|
||||
|
||||
static void soc15_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Set IP register base before any HW register access */
|
||||
|
|
@ -936,10 +872,10 @@ static int soc15_common_early_init(void *handle)
|
|||
}
|
||||
adev->smc_rreg = NULL;
|
||||
adev->smc_wreg = NULL;
|
||||
adev->pcie_rreg = &soc15_pcie_rreg;
|
||||
adev->pcie_wreg = &soc15_pcie_wreg;
|
||||
adev->pcie_rreg64 = &soc15_pcie_rreg64;
|
||||
adev->pcie_wreg64 = &soc15_pcie_wreg64;
|
||||
adev->pcie_rreg = &amdgpu_device_indirect_rreg;
|
||||
adev->pcie_wreg = &amdgpu_device_indirect_wreg;
|
||||
adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
|
||||
adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
|
||||
adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg;
|
||||
adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;
|
||||
adev->didt_rreg = &soc15_didt_rreg;
|
||||
|
|
@ -949,7 +885,7 @@ static int soc15_common_early_init(void *handle)
|
|||
adev->se_cac_rreg = &soc15_se_cac_rreg;
|
||||
adev->se_cac_wreg = &soc15_se_cac_wreg;
|
||||
|
||||
adev->rev_id = soc15_get_rev_id(adev);
|
||||
adev->rev_id = amdgpu_device_get_rev_id(adev);
|
||||
adev->external_rev_id = 0xFF;
|
||||
/* TODO: split the GC and PG flags based on the relevant IP version for which
|
||||
* they are relevant.
|
||||
|
|
@ -1230,8 +1166,6 @@ static int soc15_common_hw_init(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* enable pcie gen2/3 link */
|
||||
soc15_pcie_gen3_enable(adev);
|
||||
/* enable aspm */
|
||||
soc15_program_aspm(adev);
|
||||
/* setup nbio registers */
|
||||
|
|
|
|||
|
|
@ -102,6 +102,59 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_decode_vcn1 =
|
|||
.codec_array = vcn_4_0_0_video_codecs_decode_array_vcn1,
|
||||
};
|
||||
|
||||
/* SRIOV SOC21, not const since data is controlled by host */
|
||||
static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn0[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn1[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_encode_vcn0 = {
|
||||
.codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn0),
|
||||
.codec_array = sriov_vcn_4_0_0_video_codecs_encode_array_vcn0,
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_encode_vcn1 = {
|
||||
.codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn1),
|
||||
.codec_array = sriov_vcn_4_0_0_video_codecs_encode_array_vcn1,
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_decode_array_vcn0[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_decode_array_vcn1[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_decode_vcn0 = {
|
||||
.codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn0),
|
||||
.codec_array = sriov_vcn_4_0_0_video_codecs_decode_array_vcn0,
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_decode_vcn1 = {
|
||||
.codec_count = ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn1),
|
||||
.codec_array = sriov_vcn_4_0_0_video_codecs_decode_array_vcn1,
|
||||
};
|
||||
|
||||
static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
||||
const struct amdgpu_video_codecs **codecs)
|
||||
{
|
||||
|
|
@ -112,62 +165,37 @@ static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
|||
case IP_VERSION(4, 0, 0):
|
||||
case IP_VERSION(4, 0, 2):
|
||||
case IP_VERSION(4, 0, 4):
|
||||
if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
|
||||
if (encode)
|
||||
*codecs = &vcn_4_0_0_video_codecs_encode_vcn1;
|
||||
else
|
||||
*codecs = &vcn_4_0_0_video_codecs_decode_vcn1;
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
if ((adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) ||
|
||||
!amdgpu_sriov_is_av1_support(adev)) {
|
||||
if (encode)
|
||||
*codecs = &sriov_vcn_4_0_0_video_codecs_encode_vcn1;
|
||||
else
|
||||
*codecs = &sriov_vcn_4_0_0_video_codecs_decode_vcn1;
|
||||
} else {
|
||||
if (encode)
|
||||
*codecs = &sriov_vcn_4_0_0_video_codecs_encode_vcn0;
|
||||
else
|
||||
*codecs = &sriov_vcn_4_0_0_video_codecs_decode_vcn0;
|
||||
}
|
||||
} else {
|
||||
if (encode)
|
||||
*codecs = &vcn_4_0_0_video_codecs_encode_vcn0;
|
||||
else
|
||||
*codecs = &vcn_4_0_0_video_codecs_decode_vcn0;
|
||||
if ((adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0)) {
|
||||
if (encode)
|
||||
*codecs = &vcn_4_0_0_video_codecs_encode_vcn1;
|
||||
else
|
||||
*codecs = &vcn_4_0_0_video_codecs_decode_vcn1;
|
||||
} else {
|
||||
if (encode)
|
||||
*codecs = &vcn_4_0_0_video_codecs_encode_vcn0;
|
||||
else
|
||||
*codecs = &vcn_4_0_0_video_codecs_decode_vcn0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Indirect registers accessor
|
||||
*/
|
||||
static u32 soc21_pcie_rreg(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long address, data;
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
return amdgpu_device_indirect_rreg(adev, address, data, reg);
|
||||
}
|
||||
|
||||
static void soc21_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
|
||||
{
|
||||
unsigned long address, data;
|
||||
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
amdgpu_device_indirect_wreg(adev, address, data, reg, v);
|
||||
}
|
||||
|
||||
static u64 soc21_pcie_rreg64(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
unsigned long address, data;
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
return amdgpu_device_indirect_rreg64(adev, address, data, reg);
|
||||
}
|
||||
|
||||
static void soc21_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
|
||||
{
|
||||
unsigned long address, data;
|
||||
|
||||
address = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
|
||||
amdgpu_device_indirect_wreg64(adev, address, data, reg, v);
|
||||
}
|
||||
|
||||
static u32 soc21_didt_rreg(struct amdgpu_device *adev, u32 reg)
|
||||
{
|
||||
|
|
@ -412,21 +440,6 @@ static int soc21_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void soc21_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
|
||||
CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
|
||||
return;
|
||||
|
||||
/* todo */
|
||||
}
|
||||
|
||||
static void soc21_program_aspm(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_device_should_use_aspm(adev))
|
||||
|
|
@ -453,11 +466,6 @@ const struct amdgpu_ip_block_version soc21_common_ip_block =
|
|||
.funcs = &soc21_common_ip_funcs,
|
||||
};
|
||||
|
||||
static uint32_t soc21_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
return adev->nbio.funcs->get_rev_id(adev);
|
||||
}
|
||||
|
||||
static bool soc21_need_full_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
|
|
@ -582,10 +590,10 @@ static int soc21_common_early_init(void *handle)
|
|||
adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
|
||||
adev->smc_rreg = NULL;
|
||||
adev->smc_wreg = NULL;
|
||||
adev->pcie_rreg = &soc21_pcie_rreg;
|
||||
adev->pcie_wreg = &soc21_pcie_wreg;
|
||||
adev->pcie_rreg64 = &soc21_pcie_rreg64;
|
||||
adev->pcie_wreg64 = &soc21_pcie_wreg64;
|
||||
adev->pcie_rreg = &amdgpu_device_indirect_rreg;
|
||||
adev->pcie_wreg = &amdgpu_device_indirect_wreg;
|
||||
adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
|
||||
adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
|
||||
adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
|
||||
adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
|
||||
|
||||
|
|
@ -598,7 +606,7 @@ static int soc21_common_early_init(void *handle)
|
|||
|
||||
adev->asic_funcs = &soc21_asic_funcs;
|
||||
|
||||
adev->rev_id = soc21_get_rev_id(adev);
|
||||
adev->rev_id = amdgpu_device_get_rev_id(adev);
|
||||
adev->external_rev_id = 0xff;
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
|
|
@ -730,8 +738,23 @@ static int soc21_common_late_init(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
xgpu_nv_mailbox_get_irq(adev);
|
||||
if ((adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) ||
|
||||
!amdgpu_sriov_is_av1_support(adev)) {
|
||||
amdgpu_virt_update_sriov_video_codec(adev,
|
||||
sriov_vcn_4_0_0_video_codecs_encode_array_vcn1,
|
||||
ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn1),
|
||||
sriov_vcn_4_0_0_video_codecs_decode_array_vcn1,
|
||||
ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn1));
|
||||
} else {
|
||||
amdgpu_virt_update_sriov_video_codec(adev,
|
||||
sriov_vcn_4_0_0_video_codecs_encode_array_vcn0,
|
||||
ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_encode_array_vcn0),
|
||||
sriov_vcn_4_0_0_video_codecs_decode_array_vcn0,
|
||||
ARRAY_SIZE(sriov_vcn_4_0_0_video_codecs_decode_array_vcn0));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -755,8 +778,6 @@ static int soc21_common_hw_init(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* enable pcie gen2/3 link */
|
||||
soc21_pcie_gen3_enable(adev);
|
||||
/* enable aspm */
|
||||
soc21_program_aspm(adev);
|
||||
/* setup nbio registers */
|
||||
|
|
|
|||
|
|
@ -225,6 +225,10 @@ static int vcn_v2_5_sw_init(void *handle)
|
|||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
adev->vcn.pause_dpg_mode = vcn_v2_5_pause_dpg_mode;
|
||||
|
||||
r = amdgpu_vcn_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2031,6 +2035,4 @@ static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
amdgpu_vcn_set_ras_funcs(adev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,6 +181,10 @@ static int vcn_v4_0_sw_init(void *handle)
|
|||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
adev->vcn.pause_dpg_mode = vcn_v4_0_pause_dpg_mode;
|
||||
|
||||
r = amdgpu_vcn_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2123,6 +2127,4 @@ static void vcn_v4_0_set_ras_funcs(struct amdgpu_device *adev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
amdgpu_vcn_set_ras_funcs(adev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,7 +321,8 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
|
|||
/* psp firmware won't program IH_CHICKEN for aldebaran
|
||||
* driver needs to program it properly according to
|
||||
* MC_SPACE type in IH_RB_CNTL */
|
||||
if (adev->ip_versions[OSSSYS_HWIP][0] == IP_VERSION(4, 4, 0)) {
|
||||
if ((adev->ip_versions[OSSSYS_HWIP][0] == IP_VERSION(4, 4, 0)) ||
|
||||
(adev->ip_versions[OSSSYS_HWIP][0] == IP_VERSION(4, 4, 2))) {
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_ALDEBARAN);
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
|
||||
|
|
@ -551,12 +552,14 @@ static int vega20_ih_sw_init(void *handle)
|
|||
adev->irq.ih1.use_doorbell = true;
|
||||
adev->irq.ih1.doorbell_index = (adev->doorbell_index.ih + 1) << 1;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
|
||||
if (r)
|
||||
return r;
|
||||
if (adev->ip_versions[OSSSYS_HWIP][0] != IP_VERSION(4, 4, 2)) {
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->irq.ih2.use_doorbell = true;
|
||||
adev->irq.ih2.doorbell_index = (adev->doorbell_index.ih + 2) << 1;
|
||||
adev->irq.ih2.use_doorbell = true;
|
||||
adev->irq.ih2.doorbell_index = (adev->doorbell_index.ih + 2) << 1;
|
||||
}
|
||||
|
||||
/* initialize ih control registers offset */
|
||||
vega20_ih_init_register_offset(adev);
|
||||
|
|
|
|||
|
|
@ -1105,24 +1105,6 @@ static int vi_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return;
|
||||
|
||||
if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
|
||||
CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
|
||||
return;
|
||||
|
||||
/* todo */
|
||||
}
|
||||
|
||||
static void vi_enable_aspm(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 data, orig;
|
||||
|
|
@ -1743,8 +1725,6 @@ static int vi_common_hw_init(void *handle)
|
|||
|
||||
/* move the golden regs per IP block */
|
||||
vi_init_golden_registers(adev);
|
||||
/* enable pcie gen2/3 link */
|
||||
vi_pcie_gen3_enable(adev);
|
||||
/* enable aspm */
|
||||
vi_program_aspm(adev);
|
||||
/* enable the doorbell aperture */
|
||||
|
|
|
|||
|
|
@ -1312,14 +1312,14 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
|
|||
args->n_success = i+1;
|
||||
}
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, (struct kgd_mem *) mem, true);
|
||||
if (err) {
|
||||
pr_debug("Sync memory failed, wait interrupted by user signal\n");
|
||||
goto sync_memory_failed;
|
||||
}
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
/* Flush TLBs after waiting for the page table updates to complete */
|
||||
for (i = 0; i < args->n_devices; i++) {
|
||||
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
|
||||
|
|
@ -1335,9 +1335,9 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
|
|||
bind_process_to_device_failed:
|
||||
get_mem_obj_from_handle_failed:
|
||||
map_memory_to_gpu_failed:
|
||||
sync_memory_failed:
|
||||
mutex_unlock(&p->mutex);
|
||||
copy_from_user_failed:
|
||||
sync_memory_failed:
|
||||
kfree(devices_arr);
|
||||
|
||||
return err;
|
||||
|
|
@ -1351,6 +1351,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
|||
void *mem;
|
||||
long err = 0;
|
||||
uint32_t *devices_arr = NULL, i;
|
||||
bool flush_tlb;
|
||||
|
||||
if (!args->n_devices) {
|
||||
pr_debug("Device IDs array empty\n");
|
||||
|
|
@ -1403,16 +1404,19 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
|||
}
|
||||
args->n_success = i+1;
|
||||
}
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
if (kfd_flush_tlb_after_unmap(pdd->dev)) {
|
||||
flush_tlb = kfd_flush_tlb_after_unmap(pdd->dev);
|
||||
if (flush_tlb) {
|
||||
err = amdgpu_amdkfd_gpuvm_sync_memory(pdd->dev->adev,
|
||||
(struct kgd_mem *) mem, true);
|
||||
if (err) {
|
||||
pr_debug("Sync memory failed, wait interrupted by user signal\n");
|
||||
goto sync_memory_failed;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
if (flush_tlb) {
|
||||
/* Flush TLBs after waiting for the page table updates to complete */
|
||||
for (i = 0; i < args->n_devices; i++) {
|
||||
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
|
||||
|
|
@ -1428,9 +1432,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
|||
bind_process_to_device_failed:
|
||||
get_mem_obj_from_handle_failed:
|
||||
unmap_memory_from_gpu_failed:
|
||||
sync_memory_failed:
|
||||
mutex_unlock(&p->mutex);
|
||||
copy_from_user_failed:
|
||||
sync_memory_failed:
|
||||
kfree(devices_arr);
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1586,6 +1590,58 @@ static int kfd_ioctl_import_dmabuf(struct file *filep,
|
|||
return r;
|
||||
}
|
||||
|
||||
static int kfd_ioctl_export_dmabuf(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
struct kfd_ioctl_export_dmabuf_args *args = data;
|
||||
struct kfd_process_device *pdd;
|
||||
struct dma_buf *dmabuf;
|
||||
struct kfd_dev *dev;
|
||||
void *mem;
|
||||
int ret = 0;
|
||||
|
||||
dev = kfd_device_by_id(GET_GPU_ID(args->handle));
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
|
||||
pdd = kfd_get_process_device_data(dev, p);
|
||||
if (!pdd) {
|
||||
ret = -EINVAL;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
mem = kfd_process_device_translate_handle(pdd,
|
||||
GET_IDR_HANDLE(args->handle));
|
||||
if (!mem) {
|
||||
ret = -EINVAL;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
ret = amdgpu_amdkfd_gpuvm_export_dmabuf(mem, &dmabuf);
|
||||
mutex_unlock(&p->mutex);
|
||||
if (ret)
|
||||
goto err_out;
|
||||
|
||||
ret = dma_buf_fd(dmabuf, args->flags);
|
||||
if (ret < 0) {
|
||||
dma_buf_put(dmabuf);
|
||||
goto err_out;
|
||||
}
|
||||
/* dma_buf_fd assigns the reference count to the fd, no need to
|
||||
* put the reference here.
|
||||
*/
|
||||
args->dmabuf_fd = ret;
|
||||
|
||||
return 0;
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&p->mutex);
|
||||
err_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Handle requests for watching SMI events */
|
||||
static int kfd_ioctl_smi_events(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
|
|
@ -2768,6 +2824,9 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
|
|||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_AVAILABLE_MEMORY,
|
||||
kfd_ioctl_get_available_memory, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_EXPORT_DMABUF,
|
||||
kfd_ioctl_export_dmabuf, 0),
|
||||
};
|
||||
|
||||
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
|
|||
unsigned int chunk_size);
|
||||
static void kfd_gtt_sa_fini(struct kfd_dev *kfd);
|
||||
|
||||
static int kfd_resume_iommu(struct kfd_dev *kfd);
|
||||
static int kfd_resume(struct kfd_dev *kfd);
|
||||
|
||||
static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
|
||||
|
|
@ -624,7 +625,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
|
||||
svm_migrate_init(kfd->adev);
|
||||
|
||||
if (kgd2kfd_resume_iommu(kfd))
|
||||
if (kfd_resume_iommu(kfd))
|
||||
goto device_iommu_error;
|
||||
|
||||
if (kfd_resume(kfd))
|
||||
|
|
@ -772,6 +773,14 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
|
|||
}
|
||||
|
||||
int kgd2kfd_resume_iommu(struct kfd_dev *kfd)
|
||||
{
|
||||
if (!kfd->init_complete)
|
||||
return 0;
|
||||
|
||||
return kfd_resume_iommu(kfd);
|
||||
}
|
||||
|
||||
static int kfd_resume_iommu(struct kfd_dev *kfd)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ static unsigned long svm_migrate_unsuccessful_pages(struct migrate_vma *migrate)
|
|||
static int
|
||||
svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct migrate_vma *migrate, struct dma_fence **mfence,
|
||||
dma_addr_t *scratch)
|
||||
dma_addr_t *scratch, uint64_t ttm_res_offset)
|
||||
{
|
||||
uint64_t npages = migrate->npages;
|
||||
struct device *dev = adev->dev;
|
||||
|
|
@ -299,19 +299,13 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
|||
uint64_t i, j;
|
||||
int r;
|
||||
|
||||
pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms, prange->start,
|
||||
prange->last);
|
||||
pr_debug("svms 0x%p [0x%lx 0x%lx 0x%llx]\n", prange->svms, prange->start,
|
||||
prange->last, ttm_res_offset);
|
||||
|
||||
src = scratch;
|
||||
dst = (uint64_t *)(scratch + npages);
|
||||
|
||||
r = svm_range_vram_node_new(adev, prange, true);
|
||||
if (r) {
|
||||
dev_dbg(adev->dev, "fail %d to alloc vram\n", r);
|
||||
goto out;
|
||||
}
|
||||
|
||||
amdgpu_res_first(prange->ttm_res, prange->offset << PAGE_SHIFT,
|
||||
amdgpu_res_first(prange->ttm_res, ttm_res_offset,
|
||||
npages << PAGE_SHIFT, &cursor);
|
||||
for (i = j = 0; i < npages; i++) {
|
||||
struct page *spage;
|
||||
|
|
@ -391,14 +385,14 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
|||
migrate->dst[i + 3] = 0;
|
||||
}
|
||||
#endif
|
||||
out:
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static long
|
||||
svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct vm_area_struct *vma, uint64_t start,
|
||||
uint64_t end, uint32_t trigger)
|
||||
uint64_t end, uint32_t trigger, uint64_t ttm_res_offset)
|
||||
{
|
||||
struct kfd_process *p = container_of(prange->svms, struct kfd_process, svms);
|
||||
uint64_t npages = (end - start) >> PAGE_SHIFT;
|
||||
|
|
@ -451,7 +445,7 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
|||
else
|
||||
pr_debug("0x%lx pages migrated\n", cpages);
|
||||
|
||||
r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence, scratch);
|
||||
r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence, scratch, ttm_res_offset);
|
||||
migrate_vma_pages(&migrate);
|
||||
|
||||
pr_debug("successful/cpages/npages 0x%lx/0x%lx/0x%lx\n",
|
||||
|
|
@ -499,6 +493,7 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
|||
unsigned long addr, start, end;
|
||||
struct vm_area_struct *vma;
|
||||
struct amdgpu_device *adev;
|
||||
uint64_t ttm_res_offset;
|
||||
unsigned long cpages = 0;
|
||||
long r = 0;
|
||||
|
||||
|
|
@ -520,6 +515,13 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
|||
start = prange->start << PAGE_SHIFT;
|
||||
end = (prange->last + 1) << PAGE_SHIFT;
|
||||
|
||||
r = svm_range_vram_node_new(adev, prange, true);
|
||||
if (r) {
|
||||
dev_dbg(adev->dev, "fail %ld to alloc vram\n", r);
|
||||
return r;
|
||||
}
|
||||
ttm_res_offset = prange->offset << PAGE_SHIFT;
|
||||
|
||||
for (addr = start; addr < end;) {
|
||||
unsigned long next;
|
||||
|
||||
|
|
@ -528,18 +530,21 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
|||
break;
|
||||
|
||||
next = min(vma->vm_end, end);
|
||||
r = svm_migrate_vma_to_vram(adev, prange, vma, addr, next, trigger);
|
||||
r = svm_migrate_vma_to_vram(adev, prange, vma, addr, next, trigger, ttm_res_offset);
|
||||
if (r < 0) {
|
||||
pr_debug("failed %ld to migrate\n", r);
|
||||
break;
|
||||
} else {
|
||||
cpages += r;
|
||||
}
|
||||
ttm_res_offset += next - addr;
|
||||
addr = next;
|
||||
}
|
||||
|
||||
if (cpages)
|
||||
prange->actual_loc = best_loc;
|
||||
else
|
||||
svm_range_vram_node_free(prange);
|
||||
|
||||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ static int kfd_init(void)
|
|||
|
||||
static void kfd_exit(void)
|
||||
{
|
||||
kfd_cleanup_processes();
|
||||
kfd_debugfs_fini();
|
||||
kfd_process_destroy_wq();
|
||||
kfd_procfs_shutdown();
|
||||
|
|
|
|||
|
|
@ -928,6 +928,7 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev);
|
|||
|
||||
int kfd_process_create_wq(void);
|
||||
void kfd_process_destroy_wq(void);
|
||||
void kfd_cleanup_processes(void);
|
||||
struct kfd_process *kfd_create_process(struct file *filep);
|
||||
struct kfd_process *kfd_get_process(const struct task_struct *task);
|
||||
struct kfd_process *kfd_lookup_process_by_pasid(u32 pasid);
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ static const struct sysfs_ops kfd_procfs_ops = {
|
|||
.show = kfd_procfs_show,
|
||||
};
|
||||
|
||||
static struct kobj_type procfs_type = {
|
||||
static const struct kobj_type procfs_type = {
|
||||
.release = kfd_procfs_kobj_release,
|
||||
.sysfs_ops = &kfd_procfs_ops,
|
||||
};
|
||||
|
|
@ -469,7 +469,7 @@ static const struct sysfs_ops procfs_queue_ops = {
|
|||
.show = kfd_procfs_queue_show,
|
||||
};
|
||||
|
||||
static struct kobj_type procfs_queue_type = {
|
||||
static const struct kobj_type procfs_queue_type = {
|
||||
.sysfs_ops = &procfs_queue_ops,
|
||||
.default_groups = procfs_queue_groups,
|
||||
};
|
||||
|
|
@ -478,7 +478,7 @@ static const struct sysfs_ops procfs_stats_ops = {
|
|||
.show = kfd_procfs_stats_show,
|
||||
};
|
||||
|
||||
static struct kobj_type procfs_stats_type = {
|
||||
static const struct kobj_type procfs_stats_type = {
|
||||
.sysfs_ops = &procfs_stats_ops,
|
||||
.release = kfd_procfs_kobj_release,
|
||||
};
|
||||
|
|
@ -487,7 +487,7 @@ static const struct sysfs_ops sysfs_counters_ops = {
|
|||
.show = kfd_sysfs_counters_show,
|
||||
};
|
||||
|
||||
static struct kobj_type sysfs_counters_type = {
|
||||
static const struct kobj_type sysfs_counters_type = {
|
||||
.sysfs_ops = &sysfs_counters_ops,
|
||||
.release = kfd_procfs_kobj_release,
|
||||
};
|
||||
|
|
@ -1167,6 +1167,17 @@ static void kfd_process_free_notifier(struct mmu_notifier *mn)
|
|||
kfd_unref_process(container_of(mn, struct kfd_process, mmu_notifier));
|
||||
}
|
||||
|
||||
static void kfd_process_notifier_release_internal(struct kfd_process *p)
|
||||
{
|
||||
cancel_delayed_work_sync(&p->eviction_work);
|
||||
cancel_delayed_work_sync(&p->restore_work);
|
||||
|
||||
/* Indicate to other users that MM is no longer valid */
|
||||
p->mm = NULL;
|
||||
|
||||
mmu_notifier_put(&p->mmu_notifier);
|
||||
}
|
||||
|
||||
static void kfd_process_notifier_release(struct mmu_notifier *mn,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
|
|
@ -1181,17 +1192,22 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
|
|||
return;
|
||||
|
||||
mutex_lock(&kfd_processes_mutex);
|
||||
/*
|
||||
* Do early return if table is empty.
|
||||
*
|
||||
* This could potentially happen if this function is called concurrently
|
||||
* by mmu_notifier and by kfd_cleanup_pocesses.
|
||||
*
|
||||
*/
|
||||
if (hash_empty(kfd_processes_table)) {
|
||||
mutex_unlock(&kfd_processes_mutex);
|
||||
return;
|
||||
}
|
||||
hash_del_rcu(&p->kfd_processes);
|
||||
mutex_unlock(&kfd_processes_mutex);
|
||||
synchronize_srcu(&kfd_processes_srcu);
|
||||
|
||||
cancel_delayed_work_sync(&p->eviction_work);
|
||||
cancel_delayed_work_sync(&p->restore_work);
|
||||
|
||||
/* Indicate to other users that MM is no longer valid */
|
||||
p->mm = NULL;
|
||||
|
||||
mmu_notifier_put(&p->mmu_notifier);
|
||||
kfd_process_notifier_release_internal(p);
|
||||
}
|
||||
|
||||
static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
|
||||
|
|
@ -1200,6 +1216,43 @@ static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
|
|||
.free_notifier = kfd_process_free_notifier,
|
||||
};
|
||||
|
||||
/*
|
||||
* This code handles the case when driver is being unloaded before all
|
||||
* mm_struct are released. We need to safely free the kfd_process and
|
||||
* avoid race conditions with mmu_notifier that might try to free them.
|
||||
*
|
||||
*/
|
||||
void kfd_cleanup_processes(void)
|
||||
{
|
||||
struct kfd_process *p;
|
||||
struct hlist_node *p_temp;
|
||||
unsigned int temp;
|
||||
HLIST_HEAD(cleanup_list);
|
||||
|
||||
/*
|
||||
* Move all remaining kfd_process from the process table to a
|
||||
* temp list for processing. Once done, callback from mmu_notifier
|
||||
* release will not see the kfd_process in the table and do early return,
|
||||
* avoiding double free issues.
|
||||
*/
|
||||
mutex_lock(&kfd_processes_mutex);
|
||||
hash_for_each_safe(kfd_processes_table, temp, p_temp, p, kfd_processes) {
|
||||
hash_del_rcu(&p->kfd_processes);
|
||||
synchronize_srcu(&kfd_processes_srcu);
|
||||
hlist_add_head(&p->kfd_processes, &cleanup_list);
|
||||
}
|
||||
mutex_unlock(&kfd_processes_mutex);
|
||||
|
||||
hlist_for_each_entry_safe(p, p_temp, &cleanup_list, kfd_processes)
|
||||
kfd_process_notifier_release_internal(p);
|
||||
|
||||
/*
|
||||
* Ensures that all outstanding free_notifier get called, triggering
|
||||
* the release of the kfd_process struct.
|
||||
*/
|
||||
mmu_notifier_synchronize();
|
||||
}
|
||||
|
||||
static int kfd_process_init_cwsr_apu(struct kfd_process *p, struct file *filep)
|
||||
{
|
||||
unsigned long offset;
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ static int init_user_queue(struct process_queue_manager *pqm,
|
|||
return 0;
|
||||
|
||||
cleanup:
|
||||
if (dev->shared_resources.enable_mes)
|
||||
uninit_queue(*q);
|
||||
uninit_queue(*q);
|
||||
*q = NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ static const struct sysfs_ops sysprops_ops = {
|
|||
.show = sysprops_show,
|
||||
};
|
||||
|
||||
static struct kobj_type sysprops_type = {
|
||||
static const struct kobj_type sysprops_type = {
|
||||
.release = kfd_topology_kobj_release,
|
||||
.sysfs_ops = &sysprops_ops,
|
||||
};
|
||||
|
|
@ -318,7 +318,7 @@ static const struct sysfs_ops iolink_ops = {
|
|||
.show = iolink_show,
|
||||
};
|
||||
|
||||
static struct kobj_type iolink_type = {
|
||||
static const struct kobj_type iolink_type = {
|
||||
.release = kfd_topology_kobj_release,
|
||||
.sysfs_ops = &iolink_ops,
|
||||
};
|
||||
|
|
@ -350,7 +350,7 @@ static const struct sysfs_ops mem_ops = {
|
|||
.show = mem_show,
|
||||
};
|
||||
|
||||
static struct kobj_type mem_type = {
|
||||
static const struct kobj_type mem_type = {
|
||||
.release = kfd_topology_kobj_release,
|
||||
.sysfs_ops = &mem_ops,
|
||||
};
|
||||
|
|
@ -395,7 +395,7 @@ static const struct sysfs_ops cache_ops = {
|
|||
.show = kfd_cache_show,
|
||||
};
|
||||
|
||||
static struct kobj_type cache_type = {
|
||||
static const struct kobj_type cache_type = {
|
||||
.release = kfd_topology_kobj_release,
|
||||
.sysfs_ops = &cache_ops,
|
||||
};
|
||||
|
|
@ -566,7 +566,7 @@ static const struct sysfs_ops node_ops = {
|
|||
.show = node_show,
|
||||
};
|
||||
|
||||
static struct kobj_type node_type = {
|
||||
static const struct kobj_type node_type = {
|
||||
.release = kfd_topology_kobj_release,
|
||||
.sysfs_ops = &node_ops,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ config DRM_AMD_DC
|
|||
depends on BROKEN || !CC_IS_CLANG || X86_64 || SPARC64 || ARM64
|
||||
select SND_HDA_COMPONENT if SND_HDA_CORE
|
||||
# !CC_IS_CLANG: https://github.com/ClangBuiltLinux/linux/issues/1752
|
||||
select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128 || (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG))
|
||||
select DRM_AMD_DC_FP if (X86 || PPC64 || (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG))
|
||||
help
|
||||
Choose this option if you want to use the new display engine
|
||||
support for AMDGPU. This adds required support for Vega and
|
||||
|
|
@ -20,16 +20,10 @@ config DRM_AMD_DC
|
|||
panic on most architectures. We'll revert this when the following bug report
|
||||
has been resolved: https://github.com/llvm/llvm-project/issues/41896.
|
||||
|
||||
config DRM_AMD_DC_DCN
|
||||
config DRM_AMD_DC_FP
|
||||
def_bool n
|
||||
help
|
||||
Raven, Navi, and newer family support for display engine
|
||||
|
||||
config DRM_AMD_DC_HDCP
|
||||
bool "Enable HDCP support in DC"
|
||||
depends on DRM_AMD_DC
|
||||
help
|
||||
Choose this option if you want to support HDCP authentication.
|
||||
Floating point support, required for DCN-based SoCs
|
||||
|
||||
config DRM_AMD_DC_SI
|
||||
bool "AMD DC support for Southern Islands ASICs"
|
||||
|
|
@ -50,7 +44,7 @@ config DEBUG_KERNEL_DC
|
|||
config DRM_AMD_SECURE_DISPLAY
|
||||
bool "Enable secure display support"
|
||||
depends on DEBUG_FS
|
||||
depends on DRM_AMD_DC_DCN
|
||||
depends on DRM_AMD_DC_FP
|
||||
help
|
||||
Choose this option if you want to
|
||||
support secure display
|
||||
|
|
|
|||
|
|
@ -36,18 +36,14 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/info_packet
|
|||
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/power
|
||||
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dmub/inc
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/hdcp
|
||||
endif
|
||||
|
||||
#TODO: remove when Timing Sync feature is complete
|
||||
subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
|
||||
|
||||
DAL_LIBS = amdgpu_dm dc modules/freesync modules/color modules/info_packet modules/power dmub/src
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
DAL_LIBS += modules/hdcp
|
||||
endif
|
||||
|
||||
AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/,$(DAL_LIBS)))
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ AMDGPUDM = \
|
|||
amdgpu_dm_mst_types.o \
|
||||
amdgpu_dm_color.o
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
ifdef CONFIG_DRM_AMD_DC_FP
|
||||
AMDGPUDM += dc_fpu.o
|
||||
endif
|
||||
|
||||
|
|
@ -41,9 +41,7 @@ ifneq ($(CONFIG_DRM_AMD_DC),)
|
|||
AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o amdgpu_dm_psr.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
AMDGPUDM += amdgpu_dm_hdcp.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_DEBUG_FS),)
|
||||
AMDGPUDM += amdgpu_dm_crc.o amdgpu_dm_debugfs.o
|
||||
|
|
|
|||
|
|
@ -52,10 +52,8 @@
|
|||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_plane.h"
|
||||
#include "amdgpu_dm_crtc.h"
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
#include "amdgpu_dm_hdcp.h"
|
||||
#include <drm/display/drm_hdcp_helper.h>
|
||||
#endif
|
||||
#include "amdgpu_pm.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
|
||||
|
|
@ -344,12 +342,52 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
|
|||
{
|
||||
if (new_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED)
|
||||
return true;
|
||||
else if (amdgpu_dm_vrr_active(old_state) != amdgpu_dm_vrr_active(new_state))
|
||||
else if (amdgpu_dm_crtc_vrr_active(old_state) != amdgpu_dm_crtc_vrr_active(new_state))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void reverse_planes_order(struct dc_surface_update *array_of_surface_update,
|
||||
int planes_count)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = planes_count - 1; i < j; i++, j--)
|
||||
swap(array_of_surface_update[i], array_of_surface_update[j]);
|
||||
}
|
||||
|
||||
/**
|
||||
* update_planes_and_stream_adapter() - Send planes to be updated in DC
|
||||
*
|
||||
* DC has a generic way to update planes and stream via
|
||||
* dc_update_planes_and_stream function; however, DM might need some
|
||||
* adjustments and preparation before calling it. This function is a wrapper
|
||||
* for the dc_update_planes_and_stream that does any required configuration
|
||||
* before passing control to DC.
|
||||
*/
|
||||
static inline bool update_planes_and_stream_adapter(struct dc *dc,
|
||||
int update_type,
|
||||
int planes_count,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_stream_update *stream_update,
|
||||
struct dc_surface_update *array_of_surface_update)
|
||||
{
|
||||
reverse_planes_order(array_of_surface_update, planes_count);
|
||||
|
||||
/*
|
||||
* Previous frame finished and HW is ready for optimization.
|
||||
*/
|
||||
if (update_type == UPDATE_TYPE_FAST)
|
||||
dc_post_update_surfaces_to_stream(dc);
|
||||
|
||||
return dc_update_planes_and_stream(dc,
|
||||
array_of_surface_update,
|
||||
planes_count,
|
||||
stream,
|
||||
stream_update);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_pflip_high_irq() - Handle pageflip interrupt
|
||||
* @interrupt_params: ignored
|
||||
|
|
@ -394,7 +432,7 @@ static void dm_pflip_high_irq(void *interrupt_params)
|
|||
|
||||
WARN_ON(!e);
|
||||
|
||||
vrr_active = amdgpu_dm_vrr_active_irq(amdgpu_crtc);
|
||||
vrr_active = amdgpu_dm_crtc_vrr_active_irq(amdgpu_crtc);
|
||||
|
||||
/* Fixed refresh rate, or VRR scanout position outside front-porch? */
|
||||
if (!vrr_active ||
|
||||
|
|
@ -468,7 +506,7 @@ static void dm_vupdate_high_irq(void *interrupt_params)
|
|||
acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE);
|
||||
|
||||
if (acrtc) {
|
||||
vrr_active = amdgpu_dm_vrr_active_irq(acrtc);
|
||||
vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc);
|
||||
drm_dev = acrtc->base.dev;
|
||||
vblank = &drm_dev->vblank[acrtc->base.index];
|
||||
previous_timestamp = atomic64_read(&irq_params->previous_timestamp);
|
||||
|
|
@ -492,7 +530,7 @@ static void dm_vupdate_high_irq(void *interrupt_params)
|
|||
* if a pageflip happened inside front-porch.
|
||||
*/
|
||||
if (vrr_active) {
|
||||
dm_crtc_handle_vblank(acrtc);
|
||||
amdgpu_dm_crtc_handle_vblank(acrtc);
|
||||
|
||||
/* BTR processing for pre-DCE12 ASICs */
|
||||
if (acrtc->dm_irq_params.stream &&
|
||||
|
|
@ -532,7 +570,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
|
|||
if (!acrtc)
|
||||
return;
|
||||
|
||||
vrr_active = amdgpu_dm_vrr_active_irq(acrtc);
|
||||
vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc);
|
||||
|
||||
DC_LOG_VBLANK("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id,
|
||||
vrr_active, acrtc->dm_irq_params.active_planes);
|
||||
|
|
@ -544,7 +582,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
|
|||
* to dm_vupdate_high_irq after end of front-porch.
|
||||
*/
|
||||
if (!vrr_active)
|
||||
dm_crtc_handle_vblank(acrtc);
|
||||
amdgpu_dm_crtc_handle_vblank(acrtc);
|
||||
|
||||
/**
|
||||
* Following stuff must happen at start of vblank, for crc
|
||||
|
|
@ -675,7 +713,14 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
|
|||
drm_for_each_connector_iter(connector, &iter) {
|
||||
aconnector = to_amdgpu_dm_connector(connector);
|
||||
if (link && aconnector->dc_link == link) {
|
||||
DRM_INFO("DMUB HPD callback: link_index=%u\n", link_index);
|
||||
if (notify->type == DMUB_NOTIFICATION_HPD)
|
||||
DRM_INFO("DMUB HPD callback: link_index=%u\n", link_index);
|
||||
else if (notify->type == DMUB_NOTIFICATION_HPD_IRQ)
|
||||
DRM_INFO("DMUB HPD IRQ callback: link_index=%u\n", link_index);
|
||||
else
|
||||
DRM_WARN("DMUB Unknown HPD callback type %d, link_index=%u\n",
|
||||
notify->type, link_index);
|
||||
|
||||
hpd_aconnector = aconnector;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1488,9 +1533,7 @@ static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
|
|||
static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct dc_init_data init_data;
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
struct dc_callback_init init_params;
|
||||
#endif
|
||||
int r;
|
||||
|
||||
adev->dm.ddev = adev_to_drm(adev);
|
||||
|
|
@ -1498,9 +1541,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
|
||||
/* Zero all the fields */
|
||||
memset(&init_data, 0, sizeof(init_data));
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
memset(&init_params, 0, sizeof(init_params));
|
||||
#endif
|
||||
|
||||
mutex_init(&adev->dm.dpia_aux_lock);
|
||||
mutex_init(&adev->dm.dc_lock);
|
||||
|
|
@ -1726,7 +1767,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) {
|
||||
adev->dm.hdcp_workqueue = hdcp_create_workqueue(adev, &init_params.cp_psp, adev->dm.dc);
|
||||
|
||||
|
|
@ -1737,7 +1777,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
|
||||
dc_init_callbacks(adev->dm.dc, &init_params);
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
adev->dm.secure_display_ctxs = amdgpu_dm_crtc_secure_display_create_contexts(adev);
|
||||
if (!adev->dm.secure_display_ctxs) {
|
||||
|
|
@ -1844,7 +1883,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
|
|||
adev->dm.secure_display_ctxs = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (adev->dm.hdcp_workqueue) {
|
||||
hdcp_destroy(&adev->dev->kobj, adev->dm.hdcp_workqueue);
|
||||
adev->dm.hdcp_workqueue = NULL;
|
||||
|
|
@ -1852,7 +1890,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
|
|||
|
||||
if (adev->dm.dc)
|
||||
dc_deinit_callbacks(adev->dm.dc);
|
||||
#endif
|
||||
|
||||
dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
|
||||
|
||||
|
|
@ -2273,7 +2310,7 @@ static int dm_late_init(void *handle)
|
|||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
int edp_num;
|
||||
|
||||
get_edp_links(adev->dm.dc, edp_links, &edp_num);
|
||||
dc_get_edp_links(adev->dm.dc, edp_links, &edp_num);
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
if (!dmub_init_abm_config(adev->dm.dc->res_pool, params, i))
|
||||
return -EINVAL;
|
||||
|
|
@ -2449,11 +2486,11 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev,
|
|||
enable ? "enable" : "disable");
|
||||
|
||||
if (enable) {
|
||||
rc = dm_enable_vblank(&acrtc->base);
|
||||
rc = amdgpu_dm_crtc_enable_vblank(&acrtc->base);
|
||||
if (rc)
|
||||
DRM_WARN("Failed to enable vblank interrupts\n");
|
||||
} else {
|
||||
dm_disable_vblank(&acrtc->base);
|
||||
amdgpu_dm_crtc_disable_vblank(&acrtc->base);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2496,7 +2533,7 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
res = dc_commit_state(dc, context);
|
||||
res = dc_commit_streams(dc, context->streams, context->stream_count);
|
||||
|
||||
fail:
|
||||
dc_release_state(context);
|
||||
|
|
@ -2682,10 +2719,13 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
|
|||
bundle->surface_updates[m].surface->force_full_update =
|
||||
true;
|
||||
}
|
||||
dc_commit_updates_for_stream(
|
||||
dm->dc, bundle->surface_updates,
|
||||
dc_state->stream_status->plane_count,
|
||||
dc_state->streams[k], &bundle->stream_update, dc_state);
|
||||
|
||||
update_planes_and_stream_adapter(dm->dc,
|
||||
UPDATE_TYPE_FULL,
|
||||
dc_state->stream_status->plane_count,
|
||||
dc_state->streams[k],
|
||||
&bundle->stream_update,
|
||||
bundle->surface_updates);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
|
@ -2755,7 +2795,7 @@ static int dm_resume(void *handle)
|
|||
dc_enable_dmub_outbox(adev->dm.dc);
|
||||
}
|
||||
|
||||
WARN_ON(!dc_commit_state(dm->dc, dc_state));
|
||||
WARN_ON(!dc_commit_streams(dm->dc, dc_state->streams, dc_state->stream_count));
|
||||
|
||||
dm_gpureset_commit_state(dm->cached_dc_state, dm);
|
||||
|
||||
|
|
@ -2923,7 +2963,7 @@ const struct amdgpu_ip_block_version dm_ip_block =
|
|||
|
||||
static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
|
||||
.fb_create = amdgpu_display_user_framebuffer_create,
|
||||
.get_format_info = amd_get_format_info,
|
||||
.get_format_info = amdgpu_dm_plane_get_format_info,
|
||||
.atomic_check = amdgpu_dm_atomic_check,
|
||||
.atomic_commit = drm_atomic_helper_commit,
|
||||
};
|
||||
|
|
@ -2974,8 +3014,14 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
|
|||
caps->aux_support = true;
|
||||
|
||||
luminance_range = &conn_base->display_info.luminance_range;
|
||||
caps->aux_min_input_signal = luminance_range->min_luminance;
|
||||
caps->aux_max_input_signal = luminance_range->max_luminance;
|
||||
|
||||
if (luminance_range->max_luminance) {
|
||||
caps->aux_min_input_signal = luminance_range->min_luminance;
|
||||
caps->aux_max_input_signal = luminance_range->max_luminance;
|
||||
} else {
|
||||
caps->aux_min_input_signal = 0;
|
||||
caps->aux_max_input_signal = 512;
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_dm_update_connector_after_detect(
|
||||
|
|
@ -3111,11 +3157,9 @@ void amdgpu_dm_update_connector_after_detect(
|
|||
aconnector->edid = NULL;
|
||||
kfree(aconnector->timing_requested);
|
||||
aconnector->timing_requested = NULL;
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
/* Set CP to DESIRED if it was ENABLED, so we can re-enable it again on hotplug */
|
||||
if (connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
|
||||
connector->state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
#endif
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
|
@ -3132,9 +3176,7 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
|
|||
struct drm_device *dev = connector->dev;
|
||||
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state);
|
||||
#endif
|
||||
bool ret = false;
|
||||
|
||||
if (adev->dm.disable_hpd_irq)
|
||||
|
|
@ -3146,12 +3188,10 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
|
|||
*/
|
||||
mutex_lock(&aconnector->hpd_lock);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (adev->dm.hdcp_workqueue) {
|
||||
hdcp_reset_display(adev->dm.hdcp_workqueue, aconnector->dc_link->link_index);
|
||||
dm_con_state->update_hdcp = true;
|
||||
}
|
||||
#endif
|
||||
if (aconnector->fake_enable)
|
||||
aconnector->fake_enable = false;
|
||||
|
||||
|
|
@ -3398,12 +3438,10 @@ static void handle_hpd_rx_irq(void *param)
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (hpd_irq_data.bytes.device_service_irq.bits.CP_IRQ) {
|
||||
if (adev->dm.hdcp_workqueue)
|
||||
hdcp_handle_cpirq(adev->dm.hdcp_workqueue, aconnector->base.index);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dc_link->type != dc_connection_mst_branch)
|
||||
drm_dp_cec_irq(&aconnector->dm_dp_aux.aux);
|
||||
|
|
@ -4320,9 +4358,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
|||
if (plane->type != DC_PLANE_TYPE_DCN_UNIVERSAL)
|
||||
continue;
|
||||
|
||||
if (!plane->blends_with_above || !plane->blends_with_below)
|
||||
continue;
|
||||
|
||||
if (!plane->pixel_format_support.argb8888)
|
||||
continue;
|
||||
|
||||
|
|
@ -4947,7 +4982,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = fill_plane_buffer_attributes(adev, afb, plane_info->format,
|
||||
ret = amdgpu_dm_plane_fill_plane_buffer_attributes(adev, afb, plane_info->format,
|
||||
plane_info->rotation, tiling_flags,
|
||||
&plane_info->tiling_info,
|
||||
&plane_info->plane_size,
|
||||
|
|
@ -4956,7 +4991,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
fill_blending_from_plane_state(
|
||||
amdgpu_dm_plane_fill_blending_from_plane_state(
|
||||
plane_state, &plane_info->per_pixel_alpha, &plane_info->pre_multiplied_alpha,
|
||||
&plane_info->global_alpha, &plane_info->global_alpha_value);
|
||||
|
||||
|
|
@ -4975,7 +5010,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||
int ret;
|
||||
bool force_disable_dcc = false;
|
||||
|
||||
ret = fill_dc_scaling_info(adev, plane_state, &scaling_info);
|
||||
ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, plane_state, &scaling_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -5105,9 +5140,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
|
|||
|
||||
for (; flip_addrs->dirty_rect_count < num_clips; clips++)
|
||||
fill_dc_dirty_rect(new_plane_state->plane,
|
||||
&dirty_rects[i], clips->x1,
|
||||
clips->y1, clips->x2 - clips->x1,
|
||||
clips->y2 - clips->y1,
|
||||
&dirty_rects[flip_addrs->dirty_rect_count],
|
||||
clips->x1, clips->y1,
|
||||
clips->x2 - clips->x1, clips->y2 - clips->y1,
|
||||
&flip_addrs->dirty_rect_count,
|
||||
false);
|
||||
return;
|
||||
|
|
@ -5753,7 +5788,6 @@ static bool is_freesync_video_mode(const struct drm_display_mode *mode,
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
|
||||
struct dc_sink *sink, struct dc_stream_state *stream,
|
||||
struct dsc_dec_dpcd_caps *dsc_caps)
|
||||
|
|
@ -5784,6 +5818,10 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
|
|||
struct dc *dc = sink->ctx->dc;
|
||||
struct dc_dsc_bw_range bw_range = {0};
|
||||
struct dc_dsc_config dsc_cfg = {0};
|
||||
struct dc_dsc_config_options dsc_options = {0};
|
||||
|
||||
dc_dsc_get_default_config_option(dc, &dsc_options);
|
||||
dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16;
|
||||
|
||||
verified_link_cap = dc_link_get_link_cap(stream->link);
|
||||
link_bw_in_kbps = dc_link_bandwidth_kbps(stream->link, verified_link_cap);
|
||||
|
|
@ -5806,8 +5844,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
|
|||
if (bw_range.max_kbps < link_bw_in_kbps) {
|
||||
if (dc_dsc_compute_config(dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
dc->debug.dsc_min_slice_height_override,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
&dsc_options,
|
||||
0,
|
||||
&stream->timing,
|
||||
&dsc_cfg)) {
|
||||
|
|
@ -5821,8 +5858,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
|
|||
|
||||
if (dc_dsc_compute_config(dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
dc->debug.dsc_min_slice_height_override,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
&dsc_options,
|
||||
link_bw_in_kbps,
|
||||
&stream->timing,
|
||||
&dsc_cfg)) {
|
||||
|
|
@ -5843,6 +5879,10 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
|||
u32 dsc_max_supported_bw_in_kbps;
|
||||
u32 max_dsc_target_bpp_limit_override =
|
||||
drm_connector->display_info.max_dsc_bpp;
|
||||
struct dc_dsc_config_options dsc_options = {0};
|
||||
|
||||
dc_dsc_get_default_config_option(dc, &dsc_options);
|
||||
dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16;
|
||||
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
dc_link_get_link_cap(aconnector->dc_link));
|
||||
|
|
@ -5861,8 +5901,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
|||
if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) {
|
||||
if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
&dsc_options,
|
||||
link_bandwidth_kbps,
|
||||
&stream->timing,
|
||||
&stream->timing.dsc_cfg)) {
|
||||
|
|
@ -5879,8 +5918,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
|||
dsc_max_supported_bw_in_kbps > 0)
|
||||
if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
&dsc_options,
|
||||
dsc_max_supported_bw_in_kbps,
|
||||
&stream->timing,
|
||||
&stream->timing.dsc_cfg)) {
|
||||
|
|
@ -5904,7 +5942,6 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
|||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
|
||||
stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
|
||||
}
|
||||
#endif /* CONFIG_DRM_AMD_DC_DCN */
|
||||
|
||||
static struct dc_stream_state *
|
||||
create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
|
|
@ -5927,9 +5964,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
int mode_refresh;
|
||||
int preferred_refresh = 0;
|
||||
enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dsc_dec_dpcd_caps dsc_caps;
|
||||
#endif
|
||||
|
||||
struct dc_sink *sink = NULL;
|
||||
|
||||
|
|
@ -6028,12 +6063,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
stream->timing = *aconnector->timing_requested;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* SST DSC determination policy */
|
||||
update_dsc_caps(aconnector, sink, stream, &dsc_caps);
|
||||
if (aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE && dsc_caps.is_dsc_supported)
|
||||
apply_dsc_policy_for_stream(aconnector, sink, stream, &dsc_caps);
|
||||
#endif
|
||||
|
||||
update_stream_scaling_settings(&mode, dm_state, stream);
|
||||
|
||||
|
|
@ -6759,7 +6792,6 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = {
|
|||
.atomic_check = dm_encoder_helper_atomic_check
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state,
|
||||
struct dsc_mst_fairness_vars *vars)
|
||||
|
|
@ -6833,7 +6865,6 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int to_drm_connector_type(enum signal_type st)
|
||||
{
|
||||
|
|
@ -7158,12 +7189,18 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
|
|||
to_amdgpu_dm_connector(connector);
|
||||
struct drm_encoder *encoder;
|
||||
struct edid *edid = amdgpu_dm_connector->edid;
|
||||
struct dc_link_settings *verified_link_cap =
|
||||
&amdgpu_dm_connector->dc_link->verified_link_cap;
|
||||
const struct dc *dc = amdgpu_dm_connector->dc_link->dc;
|
||||
|
||||
encoder = amdgpu_dm_connector_to_encoder(connector);
|
||||
|
||||
if (!drm_edid_is_valid(edid)) {
|
||||
amdgpu_dm_connector->num_modes =
|
||||
drm_add_modes_noedid(connector, 640, 480);
|
||||
if (dc->link_srv->dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING)
|
||||
amdgpu_dm_connector->num_modes +=
|
||||
drm_add_modes_noedid(connector, 1920, 1080);
|
||||
} else {
|
||||
amdgpu_dm_connector_ddc_get_modes(connector, edid);
|
||||
amdgpu_dm_connector_add_common_modes(encoder, connector);
|
||||
|
|
@ -7262,10 +7299,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
|
|||
if (!aconnector->mst_root)
|
||||
drm_connector_attach_vrr_capable_property(&aconnector->base);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (adev->dm.hdcp_workqueue)
|
||||
drm_connector_attach_content_protection_property(&aconnector->base, true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7527,7 +7562,6 @@ is_scaling_state_different(const struct dm_connector_state *dm_state,
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state,
|
||||
struct drm_crtc_state *old_crtc_state,
|
||||
struct drm_connector_state *new_conn_state,
|
||||
|
|
@ -7647,7 +7681,6 @@ static bool is_content_protection_different(struct drm_crtc_state *new_crtc_stat
|
|||
pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void remove_stream(struct amdgpu_device *adev,
|
||||
struct amdgpu_crtc *acrtc,
|
||||
|
|
@ -7716,7 +7749,7 @@ static void update_freesync_state_on_stream(
|
|||
&vrr_params);
|
||||
|
||||
if (adev->family < AMDGPU_FAMILY_AI &&
|
||||
amdgpu_dm_vrr_active(new_crtc_state)) {
|
||||
amdgpu_dm_crtc_vrr_active(new_crtc_state)) {
|
||||
mod_freesync_handle_v_update(dm->freesync_module,
|
||||
new_stream, &vrr_params);
|
||||
|
||||
|
|
@ -7834,8 +7867,8 @@ static void update_stream_irq_parameters(
|
|||
static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state,
|
||||
struct dm_crtc_state *new_state)
|
||||
{
|
||||
bool old_vrr_active = amdgpu_dm_vrr_active(old_state);
|
||||
bool new_vrr_active = amdgpu_dm_vrr_active(new_state);
|
||||
bool old_vrr_active = amdgpu_dm_crtc_vrr_active(old_state);
|
||||
bool new_vrr_active = amdgpu_dm_crtc_vrr_active(new_state);
|
||||
|
||||
if (!old_vrr_active && new_vrr_active) {
|
||||
/* Transition VRR inactive -> active:
|
||||
|
|
@ -7846,7 +7879,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state,
|
|||
* We also need vupdate irq for the actual core vblank handling
|
||||
* at end of vblank.
|
||||
*/
|
||||
WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, true) != 0);
|
||||
WARN_ON(amdgpu_dm_crtc_set_vupdate_irq(new_state->base.crtc, true) != 0);
|
||||
WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0);
|
||||
DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n",
|
||||
__func__, new_state->base.crtc->base.id);
|
||||
|
|
@ -7854,7 +7887,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state,
|
|||
/* Transition VRR active -> inactive:
|
||||
* Allow vblank irq disable again for fixed refresh rate.
|
||||
*/
|
||||
WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, false) != 0);
|
||||
WARN_ON(amdgpu_dm_crtc_set_vupdate_irq(new_state->base.crtc, false) != 0);
|
||||
drm_crtc_vblank_put(new_state->base.crtc);
|
||||
DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n",
|
||||
__func__, new_state->base.crtc->base.id);
|
||||
|
|
@ -7873,7 +7906,7 @@ static void amdgpu_dm_commit_cursors(struct drm_atomic_state *state)
|
|||
*/
|
||||
for_each_old_plane_in_state(state, plane, old_plane_state, i)
|
||||
if (plane->type == DRM_PLANE_TYPE_CURSOR)
|
||||
handle_cursor_update(plane, old_plane_state);
|
||||
amdgpu_dm_plane_handle_cursor_update(plane, old_plane_state);
|
||||
}
|
||||
|
||||
static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
|
|
@ -7896,7 +7929,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
int planes_count = 0, vpos, hpos;
|
||||
unsigned long flags;
|
||||
u32 target_vblank, last_flip_vblank;
|
||||
bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
|
||||
bool vrr_active = amdgpu_dm_crtc_vrr_active(acrtc_state);
|
||||
bool cursor_update = false;
|
||||
bool pflip_present = false;
|
||||
bool dirty_rects_changed = false;
|
||||
|
|
@ -7958,7 +7991,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
|
||||
}
|
||||
|
||||
fill_dc_scaling_info(dm->adev, new_plane_state,
|
||||
amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
|
||||
&bundle->scaling_infos[planes_count]);
|
||||
|
||||
bundle->surface_updates[planes_count].scaling_info =
|
||||
|
|
@ -8178,12 +8211,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
amdgpu_dm_psr_disable(acrtc_state->stream);
|
||||
|
||||
dc_commit_updates_for_stream(dm->dc,
|
||||
bundle->surface_updates,
|
||||
planes_count,
|
||||
acrtc_state->stream,
|
||||
&bundle->stream_update,
|
||||
dc_state);
|
||||
update_planes_and_stream_adapter(dm->dc,
|
||||
acrtc_state->update_type,
|
||||
planes_count,
|
||||
acrtc_state->stream,
|
||||
&bundle->stream_update,
|
||||
bundle->surface_updates);
|
||||
|
||||
/**
|
||||
* Enable or disable the interrupts on the backend.
|
||||
|
|
@ -8446,7 +8479,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
* aconnector as needed
|
||||
*/
|
||||
|
||||
if (modeset_required(new_crtc_state, dm_new_crtc_state->stream, dm_old_crtc_state->stream)) {
|
||||
if (amdgpu_dm_crtc_modeset_required(new_crtc_state, dm_new_crtc_state->stream, dm_old_crtc_state->stream)) {
|
||||
|
||||
DRM_DEBUG_ATOMIC("Atomic commit: SET crtc id %d: [%p]\n", acrtc->crtc_id, acrtc);
|
||||
|
||||
|
|
@ -8501,7 +8534,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
|
||||
dm_enable_per_frame_crtc_master_sync(dc_state);
|
||||
mutex_lock(&dm->dc_lock);
|
||||
WARN_ON(!dc_commit_state(dm->dc, dc_state));
|
||||
WARN_ON(!dc_commit_streams(dm->dc, dc_state->streams, dc_state->stream_count));
|
||||
|
||||
/* Allow idle optimization when vblank count is 0 for display off */
|
||||
if (dm->active_vblank_irq_count == 0)
|
||||
|
|
@ -8527,7 +8560,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
acrtc->otg_inst = status->primary_otg_inst;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
|
||||
struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
|
||||
|
|
@ -8638,7 +8670,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
new_con_state->hdcp_content_type, enable_encryption);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handle connector state changes */
|
||||
for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
|
||||
|
|
@ -8715,12 +8746,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
|
||||
|
||||
mutex_lock(&dm->dc_lock);
|
||||
dc_commit_updates_for_stream(dm->dc,
|
||||
dummy_updates,
|
||||
status->plane_count,
|
||||
dm_new_crtc_state->stream,
|
||||
&stream_update,
|
||||
dc_state);
|
||||
dc_update_planes_and_stream(dm->dc,
|
||||
dummy_updates,
|
||||
status->plane_count,
|
||||
dm_new_crtc_state->stream,
|
||||
&stream_update);
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
}
|
||||
|
||||
|
|
@ -9274,7 +9304,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
|||
if (modereset_required(new_crtc_state))
|
||||
goto skip_modeset;
|
||||
|
||||
if (modeset_required(new_crtc_state, new_stream,
|
||||
if (amdgpu_dm_crtc_modeset_required(new_crtc_state, new_stream,
|
||||
dm_old_crtc_state->stream)) {
|
||||
|
||||
WARN_ON(dm_new_crtc_state->stream);
|
||||
|
|
@ -9625,7 +9655,7 @@ static int dm_update_plane_state(struct dc *dc,
|
|||
if (!needs_reset)
|
||||
return 0;
|
||||
|
||||
ret = dm_plane_helper_check_state(new_plane_state, new_crtc_state);
|
||||
ret = amdgpu_dm_plane_helper_check_state(new_plane_state, new_crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -9771,7 +9801,6 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
|
|
@ -9797,7 +9826,6 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
|
|||
|
||||
return drm_dp_mst_add_affected_dsc_crtcs(state, &aconnector->mst_root->mst_mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
|
||||
|
|
@ -9841,11 +9869,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
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;
|
||||
struct drm_dp_mst_topology_state *mst_state;
|
||||
struct dsc_mst_fairness_vars vars[MAX_PIPES];
|
||||
#endif
|
||||
|
||||
trace_amdgpu_dm_atomic_check_begin(state);
|
||||
|
||||
|
|
@ -9876,7 +9902,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
new_crtc_state->connectors_changed = true;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dc_resource_is_dsc_encoding_supported(dc)) {
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
|
||||
|
|
@ -9888,7 +9913,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
|
||||
|
|
@ -10026,13 +10050,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dc_resource_is_dsc_encoding_supported(dc)) {
|
||||
ret = pre_validate_dsc(state, &dm_state, vars);
|
||||
if (ret != 0)
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Run this here since we want to validate the streams we created */
|
||||
ret = drm_atomic_helper_check_planes(dev, state);
|
||||
|
|
@ -10098,7 +10120,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
lock_and_validation_needed = true;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* set the slot info for each mst_state based on the link encoding format */
|
||||
for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
|
|
@ -10118,7 +10139,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
}
|
||||
drm_connector_list_iter_end(&iter);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Streams and planes are reset when there are changes that affect
|
||||
|
|
@ -10146,7 +10166,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
|
||||
|
|
@ -10158,7 +10177,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
DRM_DEBUG_DRIVER("dm_update_mst_vcpi_slots_for_dsc() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Perform validation of MST topology in the state:
|
||||
|
|
|
|||
|
|
@ -461,9 +461,7 @@ struct amdgpu_display_manager {
|
|||
struct amdgpu_dm_backlight_caps backlight_caps[AMDGPU_DM_MAX_NUM_EDP];
|
||||
|
||||
struct mod_freesync *freesync_module;
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
struct hdcp_workqueue *hdcp_workqueue;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @vblank_control_workqueue:
|
||||
|
|
@ -747,9 +745,7 @@ struct dm_connector_state {
|
|||
uint8_t underscan_hborder;
|
||||
bool underscan_enable;
|
||||
bool freesync_capable;
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
bool update_hdcp;
|
||||
#endif
|
||||
uint8_t abm_level;
|
||||
int vcpi_slots;
|
||||
uint64_t pbn;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "amdgpu_dm_trace.h"
|
||||
#include "amdgpu_dm_debugfs.h"
|
||||
|
||||
void dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc)
|
||||
void amdgpu_dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc)
|
||||
{
|
||||
struct drm_crtc *crtc = &acrtc->base;
|
||||
struct drm_device *dev = crtc->dev;
|
||||
|
|
@ -54,14 +54,14 @@ void dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc)
|
|||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
|
||||
bool modeset_required(struct drm_crtc_state *crtc_state,
|
||||
bool amdgpu_dm_crtc_modeset_required(struct drm_crtc_state *crtc_state,
|
||||
struct dc_stream_state *new_stream,
|
||||
struct dc_stream_state *old_stream)
|
||||
{
|
||||
return crtc_state->active && drm_atomic_crtc_needs_modeset(crtc_state);
|
||||
}
|
||||
|
||||
bool amdgpu_dm_vrr_active_irq(struct amdgpu_crtc *acrtc)
|
||||
bool amdgpu_dm_crtc_vrr_active_irq(struct amdgpu_crtc *acrtc)
|
||||
|
||||
{
|
||||
return acrtc->dm_irq_params.freesync_config.state ==
|
||||
|
|
@ -70,7 +70,7 @@ bool amdgpu_dm_vrr_active_irq(struct amdgpu_crtc *acrtc)
|
|||
VRR_STATE_ACTIVE_FIXED;
|
||||
}
|
||||
|
||||
int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable)
|
||||
int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable)
|
||||
{
|
||||
enum dc_irq_source irq_source;
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
|
@ -89,7 +89,7 @@ int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable)
|
|||
return rc;
|
||||
}
|
||||
|
||||
bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state)
|
||||
bool amdgpu_dm_crtc_vrr_active(struct dm_crtc_state *dm_state)
|
||||
{
|
||||
return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE ||
|
||||
dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED;
|
||||
|
|
@ -159,11 +159,11 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
|
|||
|
||||
if (enable) {
|
||||
/* vblank irq on -> Only need vupdate irq in vrr mode */
|
||||
if (amdgpu_dm_vrr_active(acrtc_state))
|
||||
rc = dm_set_vupdate_irq(crtc, true);
|
||||
if (amdgpu_dm_crtc_vrr_active(acrtc_state))
|
||||
rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, true);
|
||||
} else {
|
||||
/* vblank irq off -> vupdate irq off */
|
||||
rc = dm_set_vupdate_irq(crtc, false);
|
||||
rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, false);
|
||||
}
|
||||
|
||||
if (rc)
|
||||
|
|
@ -199,12 +199,12 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dm_enable_vblank(struct drm_crtc *crtc)
|
||||
int amdgpu_dm_crtc_enable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
return dm_set_vblank(crtc, true);
|
||||
}
|
||||
|
||||
void dm_disable_vblank(struct drm_crtc *crtc)
|
||||
void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
dm_set_vblank(crtc, false);
|
||||
}
|
||||
|
|
@ -300,8 +300,8 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
|
|||
.verify_crc_source = amdgpu_dm_crtc_verify_crc_source,
|
||||
.get_crc_sources = amdgpu_dm_crtc_get_crc_sources,
|
||||
.get_vblank_counter = amdgpu_get_vblank_counter_kms,
|
||||
.enable_vblank = dm_enable_vblank,
|
||||
.disable_vblank = dm_disable_vblank,
|
||||
.enable_vblank = amdgpu_dm_crtc_enable_vblank,
|
||||
.disable_vblank = amdgpu_dm_crtc_disable_vblank,
|
||||
.get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
.late_register = amdgpu_dm_crtc_late_register,
|
||||
|
|
@ -381,7 +381,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
|||
dm_update_crtc_active_planes(crtc, crtc_state);
|
||||
|
||||
if (WARN_ON(unlikely(!dm_crtc_state->stream &&
|
||||
modeset_required(crtc_state, NULL, dm_crtc_state->stream)))) {
|
||||
amdgpu_dm_crtc_modeset_required(crtc_state, NULL, dm_crtc_state->stream)))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,21 +27,21 @@
|
|||
#ifndef __AMDGPU_DM_CRTC_H__
|
||||
#define __AMDGPU_DM_CRTC_H__
|
||||
|
||||
void dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc);
|
||||
void amdgpu_dm_crtc_handle_vblank(struct amdgpu_crtc *acrtc);
|
||||
|
||||
bool modeset_required(struct drm_crtc_state *crtc_state,
|
||||
bool amdgpu_dm_crtc_modeset_required(struct drm_crtc_state *crtc_state,
|
||||
struct dc_stream_state *new_stream,
|
||||
struct dc_stream_state *old_stream);
|
||||
|
||||
int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable);
|
||||
int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable);
|
||||
|
||||
bool amdgpu_dm_vrr_active_irq(struct amdgpu_crtc *acrtc);
|
||||
bool amdgpu_dm_crtc_vrr_active_irq(struct amdgpu_crtc *acrtc);
|
||||
|
||||
bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state);
|
||||
bool amdgpu_dm_crtc_vrr_active(struct dm_crtc_state *dm_state);
|
||||
|
||||
int dm_enable_vblank(struct drm_crtc *crtc);
|
||||
int amdgpu_dm_crtc_enable_vblank(struct drm_crtc *crtc);
|
||||
|
||||
void dm_disable_vblank(struct drm_crtc *crtc);
|
||||
void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc);
|
||||
|
||||
int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
|
||||
struct drm_plane *plane,
|
||||
|
|
|
|||
|
|
@ -724,7 +724,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us
|
|||
for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++)
|
||||
link_training_settings.hw_lane_settings[i] = link->cur_lane_setting[i];
|
||||
|
||||
dc_link_set_test_pattern(
|
||||
dc_link_dp_set_test_pattern(
|
||||
link,
|
||||
test_pattern,
|
||||
DP_TEST_PATTERN_COLOR_SPACE_RGB,
|
||||
|
|
@ -947,7 +947,6 @@ static ssize_t dp_dsc_passthrough_set(struct file *f, const char __user *buf,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
/*
|
||||
* Returns the HDCP capability of the Display (1.4 for now).
|
||||
*
|
||||
|
|
@ -984,7 +983,6 @@ static int hdcp_sink_capability_show(struct seq_file *m, void *data)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns whether the connected display is internal and not hotpluggable.
|
||||
|
|
@ -2593,9 +2591,7 @@ DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support);
|
|||
DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
|
||||
DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
|
||||
DEFINE_SHOW_ATTRIBUTE(dp_lttpr_status);
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
|
||||
#endif
|
||||
DEFINE_SHOW_ATTRIBUTE(internal_display);
|
||||
DEFINE_SHOW_ATTRIBUTE(psr_capability);
|
||||
DEFINE_SHOW_ATTRIBUTE(dp_is_mst_connector);
|
||||
|
|
@ -2726,9 +2722,7 @@ static const struct {
|
|||
{"phy_settings", &dp_phy_settings_debugfs_fop},
|
||||
{"lttpr_status", &dp_lttpr_status_fops},
|
||||
{"test_pattern", &dp_phy_test_pattern_fops},
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
{"hdcp_sink_capability", &hdcp_sink_capability_fops},
|
||||
#endif
|
||||
{"sdp_message", &sdp_message_fops},
|
||||
{"aux_dpcd_address", &dp_dpcd_address_debugfs_fops},
|
||||
{"aux_dpcd_size", &dp_dpcd_size_debugfs_fops},
|
||||
|
|
@ -2749,14 +2743,13 @@ static const struct {
|
|||
{"is_dpia_link", &is_dpia_link_fops}
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
static const struct {
|
||||
char *name;
|
||||
const struct file_operations *fops;
|
||||
} hdmi_debugfs_entries[] = {
|
||||
{"hdcp_sink_capability", &hdcp_sink_capability_fops}
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Force YUV420 output if available from the given mode
|
||||
*/
|
||||
|
|
@ -2800,6 +2793,22 @@ static int psr_get(void *data, u64 *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read PSR state residency
|
||||
*/
|
||||
static int psr_read_residency(void *data, u64 *val)
|
||||
{
|
||||
struct amdgpu_dm_connector *connector = data;
|
||||
struct dc_link *link = connector->dc_link;
|
||||
u32 residency;
|
||||
|
||||
link->dc->link_srv->edp_get_psr_residency(link, &residency);
|
||||
|
||||
*val = (u64)residency;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set dmcub trace event IRQ enable or disable.
|
||||
* Usage to enable dmcub trace event IRQ: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
|
||||
|
|
@ -2835,6 +2844,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, dmcub_trace_event_state_g
|
|||
dmcub_trace_event_state_set, "%llu\n");
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL,
|
||||
"%llu\n");
|
||||
|
||||
DEFINE_SHOW_ATTRIBUTE(current_backlight);
|
||||
DEFINE_SHOW_ATTRIBUTE(target_backlight);
|
||||
|
|
@ -2998,6 +3009,8 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
|||
if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
|
||||
debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, &psr_capability_fops);
|
||||
debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops);
|
||||
debugfs_create_file_unsafe("psr_residency", 0444, dir,
|
||||
connector, &psr_residency_fops);
|
||||
debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector,
|
||||
¤t_backlight_fops);
|
||||
debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector,
|
||||
|
|
@ -3015,7 +3028,6 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
|||
connector->debugfs_dpcd_address = 0;
|
||||
connector->debugfs_dpcd_size = 0;
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) {
|
||||
debugfs_create_file(hdmi_debugfs_entries[i].name,
|
||||
|
|
@ -3023,7 +3035,6 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
|||
hdmi_debugfs_entries[i].fops);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
|
|
|
|||
|
|
@ -559,9 +559,10 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
|
|||
link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw;
|
||||
link->dp.assr_enabled = config->assr_enabled;
|
||||
link->dp.mst_enabled = config->mst_enabled;
|
||||
link->dp.dp2_enabled = config->dp2_enabled;
|
||||
link->dp.usb4_enabled = config->usb4_enabled;
|
||||
display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
|
||||
link->adjust.auth_delay = 0;
|
||||
link->adjust.auth_delay = 2;
|
||||
link->adjust.hdcp1.disable = 0;
|
||||
conn_state = aconnector->base.state;
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,40 @@ void dm_helpers_dp_update_branch_info(
|
|||
const struct dc_link *link)
|
||||
{}
|
||||
|
||||
static void dm_helpers_construct_old_payload(
|
||||
struct dc_link *link,
|
||||
int pbn_per_slot,
|
||||
struct drm_dp_mst_atomic_payload *new_payload,
|
||||
struct drm_dp_mst_atomic_payload *old_payload)
|
||||
{
|
||||
struct link_mst_stream_allocation_table current_link_table =
|
||||
link->mst_stream_alloc_table;
|
||||
struct link_mst_stream_allocation *dc_alloc;
|
||||
int i;
|
||||
|
||||
*old_payload = *new_payload;
|
||||
|
||||
/* Set correct time_slots/PBN of old payload.
|
||||
* other fields (delete & dsc_enabled) in
|
||||
* struct drm_dp_mst_atomic_payload are don't care fields
|
||||
* while calling drm_dp_remove_payload()
|
||||
*/
|
||||
for (i = 0; i < current_link_table.stream_count; i++) {
|
||||
dc_alloc =
|
||||
¤t_link_table.stream_allocations[i];
|
||||
|
||||
if (dc_alloc->vcp_id == new_payload->vcpi) {
|
||||
old_payload->time_slots = dc_alloc->slot_count;
|
||||
old_payload->pbn = dc_alloc->slot_count * pbn_per_slot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure there is an old payload*/
|
||||
ASSERT(i != current_link_table.stream_count);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes payload allocation table in immediate downstream device.
|
||||
*/
|
||||
|
|
@ -188,7 +222,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
|
|||
{
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct drm_dp_mst_topology_state *mst_state;
|
||||
struct drm_dp_mst_atomic_payload *payload;
|
||||
struct drm_dp_mst_atomic_payload *target_payload, *new_payload, old_payload;
|
||||
struct drm_dp_mst_topology_mgr *mst_mgr;
|
||||
|
||||
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
|
||||
|
|
@ -204,17 +238,26 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
|
|||
mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
|
||||
|
||||
/* It's OK for this to fail */
|
||||
payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
|
||||
if (enable)
|
||||
drm_dp_add_payload_part1(mst_mgr, mst_state, payload);
|
||||
else
|
||||
drm_dp_remove_payload(mst_mgr, mst_state, payload, payload);
|
||||
new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
|
||||
|
||||
if (enable) {
|
||||
target_payload = new_payload;
|
||||
|
||||
drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload);
|
||||
} else {
|
||||
/* construct old payload by VCPI*/
|
||||
dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
|
||||
new_payload, &old_payload);
|
||||
target_payload = &old_payload;
|
||||
|
||||
drm_dp_remove_payload(mst_mgr, mst_state, &old_payload, new_payload);
|
||||
}
|
||||
|
||||
/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
|
||||
* AUX message. The sequence is slot 1-63 allocated sequence for each
|
||||
* stream. AMD ASIC stream slot allocation should follow the same
|
||||
* sequence. copy DRM MST allocation to dc */
|
||||
fill_dc_mst_payload_table_from_drm(stream->link, enable, payload, proposed_table);
|
||||
fill_dc_mst_payload_table_from_drm(stream->link, enable, target_payload, proposed_table);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -468,8 +511,8 @@ bool dm_helpers_dp_read_dpcd(
|
|||
return false;
|
||||
}
|
||||
|
||||
return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address,
|
||||
data, size) > 0;
|
||||
return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address, data,
|
||||
size) == size;
|
||||
}
|
||||
|
||||
bool dm_helpers_dp_write_dpcd(
|
||||
|
|
@ -525,7 +568,6 @@ bool dm_helpers_submit_i2c(
|
|||
return result;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static bool execute_synaptics_rc_command(struct drm_dp_aux *aux,
|
||||
bool is_write_cmd,
|
||||
unsigned char cmd,
|
||||
|
|
@ -693,7 +735,6 @@ static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool dm_helpers_dp_write_dsc_enable(
|
||||
struct dc_context *ctx,
|
||||
|
|
@ -719,13 +760,11 @@ bool dm_helpers_dp_write_dsc_enable(
|
|||
if (!aconnector->dsc_aux)
|
||||
return false;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
// apply w/a to synaptics
|
||||
if (needs_dsc_aux_workaround(aconnector->dc_link) &&
|
||||
(aconnector->mst_downstream_port_present.byte & 0x7) != 0x3)
|
||||
return write_dsc_enable_synaptics_non_virtual_dpcd_mst(
|
||||
aconnector->dsc_aux, stream, enable_dsc);
|
||||
#endif
|
||||
|
||||
port = aconnector->mst_output_port;
|
||||
|
||||
|
|
@ -763,17 +802,13 @@ bool dm_helpers_dp_write_dsc_enable(
|
|||
}
|
||||
|
||||
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) {
|
||||
#endif
|
||||
ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
|
||||
DC_LOG_DC("Send DSC %s to SST RX\n", enable_dsc ? "enable" : "disable");
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
} else if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) {
|
||||
ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
|
||||
DC_LOG_DC("Send DSC %s to DP-HDMI PCON\n", enable_dsc ? "enable" : "disable");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -31,10 +31,7 @@
|
|||
#include "amdgpu.h"
|
||||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_mst_types.h"
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
#include "amdgpu_dm_hdcp.h"
|
||||
#endif
|
||||
|
||||
#include "dc.h"
|
||||
#include "dm_helpers.h"
|
||||
|
|
@ -201,7 +198,6 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
|
|||
.early_unregister = amdgpu_dm_mst_connector_early_unregister,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
bool needs_dsc_aux_workaround(struct dc_link *link)
|
||||
{
|
||||
if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
|
||||
|
|
@ -212,6 +208,21 @@ bool needs_dsc_aux_workaround(struct dc_link *link)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port)
|
||||
{
|
||||
u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F
|
||||
|
||||
if (drm_dp_dpcd_read(port->mgr->aux, DP_BRANCH_VENDOR_SPECIFIC_START, &branch_vendor_data, 4) == 4) {
|
||||
if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
|
||||
IS_SYNAPTICS_CASCADED_PANAMERA(link->dpcd_caps.branch_dev_name, branch_vendor_data)) {
|
||||
DRM_INFO("Synaptics Cascaded MST hub\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
struct dc_sink *dc_sink = aconnector->dc_sink;
|
||||
|
|
@ -235,6 +246,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
|
|||
needs_dsc_aux_workaround(aconnector->dc_link))
|
||||
aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux;
|
||||
|
||||
/* synaptics cascaded MST hub case */
|
||||
if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port))
|
||||
aconnector->dsc_aux = port->mgr->aux;
|
||||
|
||||
if (!aconnector->dsc_aux)
|
||||
return false;
|
||||
|
||||
|
|
@ -271,7 +286,6 @@ static bool retrieve_downstream_port_device(struct amdgpu_dm_connector *aconnect
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
|
|
@ -362,7 +376,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|||
* plugged back with same display index, its hdcp properties
|
||||
* will be retrieved from hdcp_work within dm_dp_mst_get_modes
|
||||
*/
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (aconnector->dc_sink && connector->state) {
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
|
|
@ -374,13 +387,11 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|||
connector->state->content_protection =
|
||||
hdcp_w->content_protection[connector->index];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aconnector->dc_sink) {
|
||||
amdgpu_dm_update_freesync_caps(
|
||||
connector, aconnector->edid);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (!validate_dsc_caps_on_connector(aconnector))
|
||||
memset(&aconnector->dc_sink->dsc_caps,
|
||||
0, sizeof(aconnector->dc_sink->dsc_caps));
|
||||
|
|
@ -388,7 +399,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|||
if (!retrieve_downstream_port_device(aconnector))
|
||||
memset(&aconnector->mst_downstream_port_present,
|
||||
0, sizeof(aconnector->mst_downstream_port_present));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -647,8 +657,6 @@ int dm_mst_get_pbn_divider(struct dc_link *link)
|
|||
dc_link_get_link_cap(link)) / (8 * 1000 * 54);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
|
||||
struct dsc_mst_fairness_params {
|
||||
struct dc_crtc_timing *timing;
|
||||
struct dc_sink *sink;
|
||||
|
|
@ -662,12 +670,25 @@ struct dsc_mst_fairness_params {
|
|||
struct amdgpu_dm_connector *aconnector;
|
||||
};
|
||||
|
||||
static int kbps_to_peak_pbn(int kbps)
|
||||
static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link)
|
||||
{
|
||||
u8 link_coding_cap;
|
||||
uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B;
|
||||
|
||||
link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link);
|
||||
if (link_coding_cap == DP_128b_132b_ENCODING)
|
||||
fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B;
|
||||
|
||||
return fec_overhead_multiplier_x1000;
|
||||
}
|
||||
|
||||
static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000)
|
||||
{
|
||||
u64 peak_kbps = kbps;
|
||||
|
||||
peak_kbps *= 1006;
|
||||
peak_kbps = div_u64(peak_kbps, 1000);
|
||||
peak_kbps *= fec_overhead_multiplier_x1000;
|
||||
peak_kbps = div_u64(peak_kbps, 1000 * 1000);
|
||||
return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000));
|
||||
}
|
||||
|
||||
|
|
@ -678,16 +699,19 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
|
|||
{
|
||||
struct drm_connector *drm_connector;
|
||||
int i;
|
||||
struct dc_dsc_config_options dsc_options = {0};
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
drm_connector = ¶ms[i].aconnector->base;
|
||||
|
||||
dc_dsc_get_default_config_option(params[i].sink->ctx->dc, &dsc_options);
|
||||
dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;
|
||||
|
||||
memset(¶ms[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg));
|
||||
if (vars[i + k].dsc_enabled && dc_dsc_compute_config(
|
||||
params[i].sink->ctx->dc->res_pool->dscs[0],
|
||||
¶ms[i].sink->dsc_caps.dsc_dec_caps,
|
||||
params[i].sink->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
drm_connector->display_info.max_dsc_bpp,
|
||||
&dsc_options,
|
||||
0,
|
||||
params[i].timing,
|
||||
¶ms[i].timing->dsc_cfg)) {
|
||||
|
|
@ -730,15 +754,16 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
|
|||
u64 kbps;
|
||||
|
||||
struct drm_connector *drm_connector = ¶m.aconnector->base;
|
||||
uint32_t max_dsc_target_bpp_limit_override =
|
||||
drm_connector->display_info.max_dsc_bpp;
|
||||
struct dc_dsc_config_options dsc_options = {0};
|
||||
|
||||
dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options);
|
||||
dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;
|
||||
|
||||
kbps = div_u64((u64)pbn * 994 * 8 * 54, 64);
|
||||
dc_dsc_compute_config(
|
||||
param.sink->ctx->dc->res_pool->dscs[0],
|
||||
¶m.sink->dsc_caps.dsc_dec_caps,
|
||||
param.sink->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
&dsc_options,
|
||||
(int) kbps, param.timing, &dsc_config);
|
||||
|
||||
return dsc_config.bits_per_pixel;
|
||||
|
|
@ -761,11 +786,12 @@ static int increase_dsc_bpp(struct drm_atomic_state *state,
|
|||
int link_timeslots_used;
|
||||
int fair_pbn_alloc;
|
||||
int ret = 0;
|
||||
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (vars[i + k].dsc_enabled) {
|
||||
initial_slack[i] =
|
||||
kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i + k].pbn;
|
||||
kbps_to_peak_pbn(params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn;
|
||||
bpp_increased[i] = false;
|
||||
remaining_to_increase += 1;
|
||||
} else {
|
||||
|
|
@ -861,6 +887,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
|
|||
int next_index;
|
||||
int remaining_to_try = 0;
|
||||
int ret;
|
||||
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (vars[i + k].dsc_enabled
|
||||
|
|
@ -890,7 +917,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
|
|||
if (next_index == -1)
|
||||
break;
|
||||
|
||||
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps);
|
||||
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
|
||||
ret = drm_dp_atomic_find_time_slots(state,
|
||||
params[next_index].port->mgr,
|
||||
params[next_index].port,
|
||||
|
|
@ -903,7 +930,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
|
|||
vars[next_index].dsc_enabled = false;
|
||||
vars[next_index].bpp_x16 = 0;
|
||||
} else {
|
||||
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps);
|
||||
vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000);
|
||||
ret = drm_dp_atomic_find_time_slots(state,
|
||||
params[next_index].port->mgr,
|
||||
params[next_index].port,
|
||||
|
|
@ -932,6 +959,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
int count = 0;
|
||||
int i, k, ret;
|
||||
bool debugfs_overwrite = false;
|
||||
uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
|
||||
|
||||
memset(params, 0, sizeof(params));
|
||||
|
||||
|
|
@ -993,7 +1021,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
/* Try no compression */
|
||||
for (i = 0; i < count; i++) {
|
||||
vars[i + k].aconnector = params[i].aconnector;
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
|
||||
vars[i + k].dsc_enabled = false;
|
||||
vars[i + k].bpp_x16 = 0;
|
||||
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port,
|
||||
|
|
@ -1012,7 +1040,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
/* Try max compression */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) {
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps);
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000);
|
||||
vars[i + k].dsc_enabled = true;
|
||||
vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
|
||||
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
|
||||
|
|
@ -1020,7 +1048,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
|
||||
vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
|
||||
vars[i + k].dsc_enabled = false;
|
||||
vars[i + k].bpp_x16 = 0;
|
||||
ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
|
||||
|
|
@ -1154,6 +1182,7 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
|||
bool computed_streams[MAX_PIPES];
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct drm_dp_mst_topology_mgr *mst_mgr;
|
||||
struct resource_pool *res_pool;
|
||||
int link_vars_start_index = 0;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -1162,6 +1191,7 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
|||
|
||||
for (i = 0; i < dc_state->stream_count; i++) {
|
||||
stream = dc_state->streams[i];
|
||||
res_pool = stream->ctx->dc->res_pool;
|
||||
|
||||
if (stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
continue;
|
||||
|
|
@ -1177,7 +1207,8 @@ int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
|||
if (computed_streams[i])
|
||||
continue;
|
||||
|
||||
if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK)
|
||||
if (!res_pool->funcs->remove_stream_from_ctx ||
|
||||
res_pool->funcs->remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK)
|
||||
return -EINVAL;
|
||||
|
||||
if (!is_dsc_need_re_compute(state, dc_state, stream->link))
|
||||
|
|
@ -1435,14 +1466,12 @@ static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
|
|||
|
||||
return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16;
|
||||
}
|
||||
#endif /* CONFIG_DRM_AMD_DC_DCN */
|
||||
|
||||
enum dc_status dm_dp_mst_is_port_support_mode(
|
||||
struct amdgpu_dm_connector *aconnector,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
int bpp, pbn, branch_max_throughput_mps = 0;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dc_link_settings cur_link_settings;
|
||||
unsigned int end_to_end_bw_in_kbps = 0;
|
||||
unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
|
||||
|
|
@ -1484,16 +1513,13 @@ enum dc_status dm_dp_mst_is_port_support_mode(
|
|||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
/* check if mode could be supported within full_pbn */
|
||||
bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
|
||||
pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false);
|
||||
|
||||
if (pbn > aconnector->mst_output_port->full_pbn)
|
||||
return DC_FAIL_BANDWIDTH_VALIDATE;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
|
||||
switch (stream->timing.pixel_encoding) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,21 @@
|
|||
#define SYNAPTICS_RC_OFFSET 0x4BC
|
||||
#define SYNAPTICS_RC_DATA 0x4C0
|
||||
|
||||
#define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C
|
||||
|
||||
/**
|
||||
* Panamera MST Hub detection
|
||||
* Offset DPCD 050Eh == 0x5A indicates cascaded MST hub case
|
||||
* Check from beginning of branch device vendor specific field (050Ch)
|
||||
*/
|
||||
#define IS_SYNAPTICS_PANAMERA(branchDevName) (((int)branchDevName[4] & 0xF0) == 0x50 ? 1 : 0)
|
||||
#define BRANCH_HW_REVISION_PANAMERA_A2 0x10
|
||||
#define SYNAPTICS_CASCADED_HUB_ID 0x5A
|
||||
#define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0)
|
||||
|
||||
#define PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B 1031
|
||||
#define PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B 1000
|
||||
|
||||
struct amdgpu_display_manager;
|
||||
struct amdgpu_dm_connector;
|
||||
|
||||
|
|
|
|||
|
|
@ -90,12 +90,12 @@ enum dm_micro_swizzle {
|
|||
MICRO_SWIZZLE_R = 3
|
||||
};
|
||||
|
||||
const struct drm_format_info *amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
|
||||
const struct drm_format_info *amdgpu_dm_plane_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
|
||||
{
|
||||
return amdgpu_lookup_format_info(cmd->pixel_format, cmd->modifier[0]);
|
||||
}
|
||||
|
||||
void fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
|
||||
void amdgpu_dm_plane_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)
|
||||
{
|
||||
|
|
@ -741,25 +741,7 @@ static int get_plane_formats(const struct drm_plane *plane,
|
|||
return num_formats;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDR
|
||||
static int attach_color_mgmt_properties(struct amdgpu_display_manager *dm, struct drm_plane *plane)
|
||||
{
|
||||
drm_object_attach_property(&plane->base,
|
||||
dm->degamma_lut_property,
|
||||
0);
|
||||
drm_object_attach_property(&plane->base,
|
||||
dm->degamma_lut_size_property,
|
||||
MAX_COLOR_LUT_ENTRIES);
|
||||
drm_object_attach_property(&plane->base, dm->ctm_property,
|
||||
0);
|
||||
drm_object_attach_property(&plane->base, dm->sdr_boost_property,
|
||||
DEFAULT_SDR_BOOST);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
||||
int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
||||
const struct amdgpu_framebuffer *afb,
|
||||
const enum surface_pixel_format format,
|
||||
const enum dc_rotation_angle rotation,
|
||||
|
|
@ -918,7 +900,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
dm_plane_state_new->dc_state;
|
||||
bool force_disable_dcc = !plane_state->dcc.enable;
|
||||
|
||||
fill_plane_buffer_attributes(
|
||||
amdgpu_dm_plane_fill_plane_buffer_attributes(
|
||||
adev, afb, plane_state->format, plane_state->rotation,
|
||||
afb->tiling_flags,
|
||||
&plane_state->tiling_info, &plane_state->plane_size,
|
||||
|
|
@ -999,7 +981,7 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev,
|
|||
*min_downscale = 1000;
|
||||
}
|
||||
|
||||
int dm_plane_helper_check_state(struct drm_plane_state *state,
|
||||
int amdgpu_dm_plane_helper_check_state(struct drm_plane_state *state,
|
||||
struct drm_crtc_state *new_crtc_state)
|
||||
{
|
||||
struct drm_framebuffer *fb = state->fb;
|
||||
|
|
@ -1053,7 +1035,7 @@ int dm_plane_helper_check_state(struct drm_plane_state *state,
|
|||
state, new_crtc_state, min_scale, max_scale, true, true);
|
||||
}
|
||||
|
||||
int fill_dc_scaling_info(struct amdgpu_device *adev,
|
||||
int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev,
|
||||
const struct drm_plane_state *state,
|
||||
struct dc_scaling_info *scaling_info)
|
||||
{
|
||||
|
|
@ -1161,11 +1143,11 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
|
|||
if (!new_crtc_state)
|
||||
return -EINVAL;
|
||||
|
||||
ret = dm_plane_helper_check_state(new_plane_state, new_crtc_state);
|
||||
ret = amdgpu_dm_plane_helper_check_state(new_plane_state, new_crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = fill_dc_scaling_info(adev, new_plane_state, &scaling_info);
|
||||
ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1229,7 +1211,7 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void handle_cursor_update(struct drm_plane *plane,
|
||||
void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_plane_state)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(plane->dev);
|
||||
|
|
@ -1314,7 +1296,7 @@ static void dm_plane_atomic_async_update(struct drm_plane *plane,
|
|||
plane->state->crtc_w = new_state->crtc_w;
|
||||
plane->state->crtc_h = new_state->crtc_h;
|
||||
|
||||
handle_cursor_update(plane, old_state);
|
||||
amdgpu_dm_plane_handle_cursor_update(plane, old_state);
|
||||
}
|
||||
|
||||
static const struct drm_plane_helper_funcs dm_plane_helper_funcs = {
|
||||
|
|
@ -1337,10 +1319,6 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
|
|||
|
||||
if (amdgpu_state)
|
||||
__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDR
|
||||
if (amdgpu_state)
|
||||
amdgpu_state->sdr_boost = DEFAULT_SDR_BOOST;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct drm_plane_state *
|
||||
|
|
@ -1360,15 +1338,6 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
|
|||
dc_plane_state_retain(dm_plane_state->dc_state);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDR
|
||||
if (dm_plane_state->degamma_lut)
|
||||
drm_property_blob_get(dm_plane_state->degamma_lut);
|
||||
if (dm_plane_state->ctm)
|
||||
drm_property_blob_get(dm_plane_state->ctm);
|
||||
|
||||
dm_plane_state->sdr_boost = old_dm_plane_state->sdr_boost;
|
||||
#endif
|
||||
|
||||
return &dm_plane_state->base;
|
||||
}
|
||||
|
||||
|
|
@ -1436,103 +1405,12 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
|
|||
{
|
||||
struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDR
|
||||
drm_property_blob_put(dm_plane_state->degamma_lut);
|
||||
drm_property_blob_put(dm_plane_state->ctm);
|
||||
#endif
|
||||
if (dm_plane_state->dc_state)
|
||||
dc_plane_state_release(dm_plane_state->dc_state);
|
||||
|
||||
drm_atomic_helper_plane_destroy_state(plane, state);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDR
|
||||
/* copied from drm_atomic_uapi.c */
|
||||
static int atomic_replace_property_blob_from_id(struct drm_device *dev,
|
||||
struct drm_property_blob **blob,
|
||||
uint64_t blob_id,
|
||||
ssize_t expected_size,
|
||||
ssize_t expected_elem_size,
|
||||
bool *replaced)
|
||||
{
|
||||
struct drm_property_blob *new_blob = NULL;
|
||||
|
||||
if (blob_id != 0) {
|
||||
new_blob = drm_property_lookup_blob(dev, blob_id);
|
||||
if (new_blob == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (expected_size > 0 &&
|
||||
new_blob->length != expected_size) {
|
||||
drm_property_blob_put(new_blob);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (expected_elem_size > 0 &&
|
||||
new_blob->length % expected_elem_size != 0) {
|
||||
drm_property_blob_put(new_blob);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
*replaced |= drm_property_replace_blob(blob, new_blob);
|
||||
drm_property_blob_put(new_blob);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_drm_plane_set_property(struct drm_plane *plane,
|
||||
struct drm_plane_state *state,
|
||||
struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(plane->dev);
|
||||
struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
|
||||
int ret = 0;
|
||||
bool replaced;
|
||||
|
||||
if (property == adev->dm.degamma_lut_property) {
|
||||
ret = atomic_replace_property_blob_from_id(adev_to_drm(adev),
|
||||
&dm_plane_state->degamma_lut,
|
||||
val, -1, sizeof(struct drm_color_lut),
|
||||
&replaced);
|
||||
} else if (property == adev->dm.ctm_property) {
|
||||
ret = atomic_replace_property_blob_from_id(adev_to_drm(adev),
|
||||
&dm_plane_state->ctm,
|
||||
val,
|
||||
sizeof(struct drm_color_ctm), -1,
|
||||
&replaced);
|
||||
} else if (property == adev->dm.sdr_boost_property) {
|
||||
dm_plane_state->sdr_boost = val;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dm_drm_plane_get_property(struct drm_plane *plane,
|
||||
const struct drm_plane_state *state,
|
||||
struct drm_property *property,
|
||||
uint64_t *val)
|
||||
{
|
||||
struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
|
||||
struct amdgpu_device *adev = drm_to_adev(plane->dev);
|
||||
|
||||
if (property == adev->dm.degamma_lut_property) {
|
||||
*val = (dm_plane_state->degamma_lut) ?
|
||||
dm_plane_state->degamma_lut->base.id : 0;
|
||||
} else if (property == adev->dm.ctm_property) {
|
||||
*val = (dm_plane_state->ctm) ? dm_plane_state->ctm->base.id : 0;
|
||||
} else if (property == adev->dm.sdr_boost_property) {
|
||||
*val = dm_plane_state->sdr_boost;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct drm_plane_funcs dm_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
|
|
@ -1541,10 +1419,6 @@ static const struct drm_plane_funcs dm_plane_funcs = {
|
|||
.atomic_duplicate_state = dm_drm_plane_duplicate_state,
|
||||
.atomic_destroy_state = dm_drm_plane_destroy_state,
|
||||
.format_mod_supported = dm_plane_format_mod_supported,
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDR
|
||||
.atomic_set_property = dm_drm_plane_set_property,
|
||||
.atomic_get_property = dm_drm_plane_get_property,
|
||||
#endif
|
||||
};
|
||||
|
||||
int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
|
||||
|
|
@ -1615,9 +1489,6 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
|
|||
|
||||
drm_plane_helper_add(plane, &dm_plane_helper_funcs);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDR
|
||||
attach_color_mgmt_properties(dm, plane);
|
||||
#endif
|
||||
/* Create (reset) the plane state */
|
||||
if (plane->funcs->reset)
|
||||
plane->funcs->reset(plane);
|
||||
|
|
|
|||
|
|
@ -29,17 +29,17 @@
|
|||
|
||||
#include "dc.h"
|
||||
|
||||
void handle_cursor_update(struct drm_plane *plane,
|
||||
void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_plane_state);
|
||||
|
||||
int fill_dc_scaling_info(struct amdgpu_device *adev,
|
||||
int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev,
|
||||
const struct drm_plane_state *state,
|
||||
struct dc_scaling_info *scaling_info);
|
||||
|
||||
int dm_plane_helper_check_state(struct drm_plane_state *state,
|
||||
int amdgpu_dm_plane_helper_check_state(struct drm_plane_state *state,
|
||||
struct drm_crtc_state *new_crtc_state);
|
||||
|
||||
int fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
||||
int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
||||
const struct amdgpu_framebuffer *afb,
|
||||
const enum surface_pixel_format format,
|
||||
const enum dc_rotation_angle rotation,
|
||||
|
|
@ -56,9 +56,9 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
|
|||
unsigned long possible_crtcs,
|
||||
const struct dc_plane_cap *plane_cap);
|
||||
|
||||
const struct drm_format_info *amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
|
||||
const struct drm_format_info *amdgpu_dm_plane_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
|
||||
|
||||
void fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
|
||||
void amdgpu_dm_plane_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);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,14 +22,13 @@
|
|||
#
|
||||
# Makefile for Display Core (dc) component.
|
||||
|
||||
DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual
|
||||
DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual dsc
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
ifdef CONFIG_DRM_AMD_DC_FP
|
||||
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
DC_LIBS += dcn20
|
||||
DC_LIBS += dsc
|
||||
DC_LIBS += dcn10
|
||||
DC_LIBS += dcn21
|
||||
DC_LIBS += dcn201
|
||||
|
|
@ -56,9 +55,7 @@ ifdef CONFIG_DRM_AMD_DC_SI
|
|||
DC_LIBS += dce60
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
DC_LIBS += hdcp
|
||||
endif
|
||||
|
||||
AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LIBS)))
|
||||
|
||||
|
|
|
|||
|
|
@ -2064,7 +2064,7 @@ static enum bp_result bios_parser_get_encoder_cap_info(
|
|||
if (!info)
|
||||
return BP_RESULT_BADINPUT;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
/* encoder cap record not available in v1_5 */
|
||||
if (bp->object_info_tbl.revision.minor == 5)
|
||||
return BP_RESULT_NORECORD;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ CLK_MGR_DCE120 = dce120_clk_mgr.o
|
|||
AMD_DAL_CLK_MGR_DCE120 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dce120/,$(CLK_MGR_DCE120))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCE120)
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
ifdef CONFIG_DRM_AMD_DC_FP
|
||||
###############################################################################
|
||||
# DCN10
|
||||
###############################################################################
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
|
|||
int edp_num;
|
||||
unsigned int panel_inst;
|
||||
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
dc_get_edp_links(dc, edp_links, &edp_num);
|
||||
if (dc->hwss.exit_optimized_pwr_state)
|
||||
dc->hwss.exit_optimized_pwr_state(dc, dc->current_state);
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
|
|||
if (!edp_link->psr_settings.psr_feature_enabled)
|
||||
continue;
|
||||
clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
|
||||
dc_link_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
|
||||
dc->link_srv->edp_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,13 +129,13 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
|
|||
int edp_num;
|
||||
unsigned int panel_inst;
|
||||
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
dc_get_edp_links(dc, edp_links, &edp_num);
|
||||
if (edp_num) {
|
||||
for (panel_inst = 0; panel_inst < edp_num; panel_inst++) {
|
||||
edp_link = edp_links[panel_inst];
|
||||
if (!edp_link->psr_settings.psr_feature_enabled)
|
||||
continue;
|
||||
dc_link_set_psr_allow_active(edp_link,
|
||||
dc->link_srv->edp_set_psr_allow_active(edp_link,
|
||||
&clk_mgr->psr_allow_active_cache, false, false, NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
|
|||
dce120_clk_mgr_construct(ctx, clk_mgr);
|
||||
return &clk_mgr->base;
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
case FAMILY_RV: {
|
||||
struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL);
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
|
|||
}
|
||||
break;
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_DRM_AMD_DC_FP - Family RV */
|
||||
default:
|
||||
ASSERT(0); /* Unknown Asic */
|
||||
break;
|
||||
|
|
@ -364,7 +364,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
|
|||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
#ifdef CONFIG_DRM_AMD_DC_FP
|
||||
switch (clk_mgr_base->ctx->asic_id.chip_family) {
|
||||
case FAMILY_NV:
|
||||
if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
|
||||
|
|
@ -405,7 +405,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_DRM_AMD_DC_FP */
|
||||
|
||||
kfree(clk_mgr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ static void dcn201_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
}
|
||||
}
|
||||
|
||||
struct clk_mgr_funcs dcn201_funcs = {
|
||||
static struct clk_mgr_funcs dcn201_funcs = {
|
||||
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
|
||||
.update_clocks = dcn201_update_clocks,
|
||||
.init_clocks = dcn201_init_clocks,
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ void rn_clk_mgr_construct(
|
|||
enum pp_smu_status status = 0;
|
||||
int is_green_sardine = 0;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
is_green_sardine = ASICREV_IS_GREEN_SARDINE(ctx->asic_id.hw_internal_rev);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,11 @@ static int dcn314_get_active_display_cnt_wa(
|
|||
stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
|
||||
stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
|
||||
tmds_present = true;
|
||||
|
||||
/* Checking stream / link detection ensuring that PHY is active*/
|
||||
if (dc_is_dp_signal(stream->signal) && !stream->dpms_off)
|
||||
display_count++;
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
|
|
|
|||
|
|
@ -255,27 +255,60 @@ static void dcn32_update_dppclk_dispclk_freq(struct clk_mgr_internal *clk_mgr, s
|
|||
}
|
||||
}
|
||||
|
||||
void dcn32_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
|
||||
struct dc_state *context, bool safe_to_lower)
|
||||
{
|
||||
int i;
|
||||
|
||||
clk_mgr->dccg->ref_dppclk = clk_mgr->base.clks.dppclk_khz;
|
||||
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
|
||||
int dpp_inst, dppclk_khz, prev_dppclk_khz;
|
||||
|
||||
dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
|
||||
|
||||
if (context->res_ctx.pipe_ctx[i].plane_res.dpp)
|
||||
dpp_inst = context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
|
||||
else if (!context->res_ctx.pipe_ctx[i].plane_res.dpp && dppclk_khz == 0) {
|
||||
/* dpp == NULL && dppclk_khz == 0 is valid because of pipe harvesting.
|
||||
* In this case just continue in loop
|
||||
*/
|
||||
continue;
|
||||
} else if (!context->res_ctx.pipe_ctx[i].plane_res.dpp && dppclk_khz > 0) {
|
||||
/* The software state is not valid if dpp resource is NULL and
|
||||
* dppclk_khz > 0.
|
||||
*/
|
||||
ASSERT(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
prev_dppclk_khz = clk_mgr->dccg->pipe_dppclk_khz[i];
|
||||
|
||||
if (safe_to_lower || prev_dppclk_khz < dppclk_khz)
|
||||
clk_mgr->dccg->funcs->update_dpp_dto(
|
||||
clk_mgr->dccg, dpp_inst, dppclk_khz);
|
||||
}
|
||||
}
|
||||
|
||||
static void dcn32_update_clocks_update_dentist(
|
||||
struct clk_mgr_internal *clk_mgr,
|
||||
struct dc_state *context,
|
||||
uint32_t old_dispclk_khz)
|
||||
struct dc_state *context)
|
||||
{
|
||||
uint32_t new_disp_divider = 0;
|
||||
uint32_t old_disp_divider = 0;
|
||||
uint32_t new_dispclk_wdivider = 0;
|
||||
uint32_t old_dispclk_wdivider = 0;
|
||||
uint32_t i;
|
||||
uint32_t dentist_dispclk_wdivider_readback = 0;
|
||||
struct dc *dc = clk_mgr->base.ctx->dc;
|
||||
|
||||
if (old_dispclk_khz == 0 || clk_mgr->base.clks.dispclk_khz == 0)
|
||||
if (clk_mgr->base.clks.dispclk_khz == 0)
|
||||
return;
|
||||
|
||||
new_disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
||||
* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
|
||||
old_disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
||||
* clk_mgr->base.dentist_vco_freq_khz / old_dispclk_khz;
|
||||
|
||||
new_dispclk_wdivider = dentist_get_did_from_divider(new_disp_divider);
|
||||
old_dispclk_wdivider = dentist_get_did_from_divider(old_disp_divider);
|
||||
REG_GET(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DISPCLK_WDIVIDER, &old_dispclk_wdivider);
|
||||
|
||||
/* When changing divider to or from 127, some extra programming is required to prevent corruption */
|
||||
if (old_dispclk_wdivider == 127 && new_dispclk_wdivider != 127) {
|
||||
|
|
@ -314,6 +347,17 @@ static void dcn32_update_clocks_update_dentist(
|
|||
if (clk_mgr->smu_present)
|
||||
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(temp_dispclk_khz));
|
||||
|
||||
if (dc->debug.override_dispclk_programming) {
|
||||
REG_GET(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DISPCLK_WDIVIDER, &dentist_dispclk_wdivider_readback);
|
||||
|
||||
if (dentist_dispclk_wdivider_readback != 126) {
|
||||
REG_UPDATE(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DISPCLK_WDIVIDER, 126);
|
||||
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
struct dccg *dccg = clk_mgr->base.ctx->dc->res_pool->dccg;
|
||||
|
|
@ -341,6 +385,18 @@ static void dcn32_update_clocks_update_dentist(
|
|||
/* do requested DISPCLK updates*/
|
||||
if (clk_mgr->smu_present)
|
||||
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, khz_to_mhz_ceil(clk_mgr->base.clks.dispclk_khz));
|
||||
|
||||
if (dc->debug.override_dispclk_programming) {
|
||||
REG_GET(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DISPCLK_WDIVIDER, &dentist_dispclk_wdivider_readback);
|
||||
|
||||
if (dentist_dispclk_wdivider_readback > new_dispclk_wdivider) {
|
||||
REG_UPDATE(DENTIST_DISPCLK_CNTL,
|
||||
DENTIST_DISPCLK_WDIVIDER, new_dispclk_wdivider);
|
||||
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
|
|
@ -361,7 +417,6 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
bool p_state_change_support;
|
||||
bool fclk_p_state_change_support;
|
||||
int total_plane_count;
|
||||
int old_dispclk_khz = clk_mgr_base->clks.dispclk_khz;
|
||||
|
||||
if (dc->work_arounds.skip_clock_update)
|
||||
return;
|
||||
|
|
@ -503,19 +558,19 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) {
|
||||
if (dpp_clock_lowered) {
|
||||
/* if clock is being lowered, increase DTO before lowering refclk */
|
||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
|
||||
dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz);
|
||||
dcn32_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
|
||||
dcn32_update_clocks_update_dentist(clk_mgr, context);
|
||||
if (clk_mgr->smu_present)
|
||||
dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz));
|
||||
} else {
|
||||
/* if clock is being raised, increase refclk before lowering DTO */
|
||||
if (update_dppclk || update_dispclk)
|
||||
dcn32_update_clocks_update_dentist(clk_mgr, context, old_dispclk_khz);
|
||||
dcn32_update_clocks_update_dentist(clk_mgr, context);
|
||||
/* There is a check inside dcn20_update_clocks_update_dpp_dto which ensures
|
||||
* that we do not lower dto when it is not safe to lower. We do not need to
|
||||
* compare the current and new dppclk before calling this function.
|
||||
*/
|
||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
|
||||
dcn32_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ void dcn32_clk_mgr_construct(struct dc_context *ctx,
|
|||
struct pp_smu_funcs *pp_smu,
|
||||
struct dccg *dccg);
|
||||
|
||||
void dcn32_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
|
||||
struct dc_state *context, bool safe_to_lower);
|
||||
|
||||
void dcn32_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
#include "link_encoder.h"
|
||||
#include "link_enc_cfg.h"
|
||||
|
||||
#include "dc_link.h"
|
||||
#include "link.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "mem_input.h"
|
||||
|
|
@ -74,6 +73,8 @@
|
|||
|
||||
#include "dc_trace.h"
|
||||
|
||||
#include "hw_sequencer_private.h"
|
||||
|
||||
#include "dce/dmub_outbox.h"
|
||||
|
||||
#define CTX \
|
||||
|
|
@ -147,7 +148,7 @@ static void destroy_links(struct dc *dc)
|
|||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
if (NULL != dc->links[i])
|
||||
link_destroy(&dc->links[i]);
|
||||
dc->link_srv->destroy_link(&dc->links[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +217,7 @@ static bool create_links(
|
|||
link_init_params.connector_index = i;
|
||||
link_init_params.link_index = dc->link_count;
|
||||
link_init_params.dc = dc;
|
||||
link = link_create(&link_init_params);
|
||||
link = dc->link_srv->create_link(&link_init_params);
|
||||
|
||||
if (link) {
|
||||
dc->links[dc->link_count] = link;
|
||||
|
|
@ -238,7 +239,7 @@ static bool create_links(
|
|||
link_init_params.dc = dc;
|
||||
link_init_params.is_dpia_link = true;
|
||||
|
||||
link = link_create(&link_init_params);
|
||||
link = dc->link_srv->create_link(&link_init_params);
|
||||
if (link) {
|
||||
dc->links[dc->link_count] = link;
|
||||
link->dc = dc;
|
||||
|
|
@ -399,6 +400,14 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
|||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Don't adjust DRR while there's bandwidth optimizations pending to
|
||||
* avoid conflicting with firmware updates.
|
||||
*/
|
||||
if (dc->ctx->dce_version > DCE_VERSION_MAX)
|
||||
if (dc->optimized_required || dc->wm_optimized_required)
|
||||
return false;
|
||||
|
||||
stream->adjust.v_total_max = adjust->v_total_max;
|
||||
stream->adjust.v_total_mid = adjust->v_total_mid;
|
||||
stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
|
||||
|
|
@ -814,6 +823,9 @@ static void dc_destruct(struct dc *dc)
|
|||
|
||||
dc_destroy_resource_pool(dc);
|
||||
|
||||
if (dc->link_srv)
|
||||
link_destroy_link_service(&dc->link_srv);
|
||||
|
||||
if (dc->ctx->gpio_service)
|
||||
dal_gpio_service_destroy(&dc->ctx->gpio_service);
|
||||
|
||||
|
|
@ -973,6 +985,8 @@ static bool dc_construct(struct dc *dc,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
dc->link_srv = link_create_link_service();
|
||||
|
||||
dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version);
|
||||
if (!dc->res_pool)
|
||||
goto fail;
|
||||
|
|
@ -984,7 +998,7 @@ static bool dc_construct(struct dc *dc,
|
|||
dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg);
|
||||
if (!dc->clk_mgr)
|
||||
goto fail;
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
#ifdef CONFIG_DRM_AMD_DC_FP
|
||||
dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present;
|
||||
|
||||
if (dc->res_pool->funcs->update_bw_bounding_box) {
|
||||
|
|
@ -1057,6 +1071,53 @@ static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *contex
|
|||
}
|
||||
}
|
||||
|
||||
static void phantom_pipe_blank(
|
||||
struct dc *dc,
|
||||
struct timing_generator *tg,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
enum dc_color_space color_space;
|
||||
struct tg_color black_color = {0};
|
||||
struct output_pixel_processor *opp = NULL;
|
||||
uint32_t num_opps, opp_id_src0, opp_id_src1;
|
||||
uint32_t otg_active_width, otg_active_height;
|
||||
uint32_t i;
|
||||
|
||||
/* program opp dpg blank color */
|
||||
color_space = COLOR_SPACE_SRGB;
|
||||
color_space_to_black_color(dc, color_space, &black_color);
|
||||
|
||||
otg_active_width = width;
|
||||
otg_active_height = height;
|
||||
|
||||
/* get the OPTC source */
|
||||
tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
|
||||
ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
|
||||
|
||||
for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
|
||||
if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
|
||||
opp = dc->res_pool->opps[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (opp && opp->funcs->opp_set_disp_pattern_generator)
|
||||
opp->funcs->opp_set_disp_pattern_generator(
|
||||
opp,
|
||||
CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
|
||||
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
|
||||
COLOR_DEPTH_UNDEFINED,
|
||||
&black_color,
|
||||
otg_active_width,
|
||||
otg_active_height,
|
||||
0);
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg))
|
||||
hws->funcs.wait_for_blank_complete(opp);
|
||||
}
|
||||
|
||||
static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
int i, j;
|
||||
|
|
@ -1115,8 +1176,14 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
|||
* again for different use.
|
||||
*/
|
||||
if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
if (tg->funcs->enable_crtc)
|
||||
if (tg->funcs->enable_crtc) {
|
||||
int main_pipe_width, main_pipe_height;
|
||||
|
||||
main_pipe_width = old_stream->mall_stream_config.paired_stream->dst.width;
|
||||
main_pipe_height = old_stream->mall_stream_config.paired_stream->dst.height;
|
||||
phantom_pipe_blank(dc, tg, main_pipe_width, main_pipe_height);
|
||||
tg->funcs->enable_crtc(tg);
|
||||
}
|
||||
}
|
||||
dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
|
||||
disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
|
||||
|
|
@ -1199,7 +1266,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) {
|
||||
link_set_dpms_off(pipe);
|
||||
dc->link_srv->set_dpms_off(pipe);
|
||||
pipe->stream->dpms_off = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1298,7 +1365,7 @@ static void detect_edp_presence(struct dc *dc)
|
|||
int i;
|
||||
int edp_num;
|
||||
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
dc_get_edp_links(dc, edp_links, &edp_num);
|
||||
if (!edp_num)
|
||||
return;
|
||||
|
||||
|
|
@ -1324,16 +1391,12 @@ void dc_hardware_init(struct dc *dc)
|
|||
void dc_init_callbacks(struct dc *dc,
|
||||
const struct dc_callback_init *init_params)
|
||||
{
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
dc->ctx->cp_psp = init_params->cp_psp;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dc_deinit_callbacks(struct dc *dc)
|
||||
{
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp));
|
||||
#endif
|
||||
}
|
||||
|
||||
void dc_destroy(struct dc **dc)
|
||||
|
|
@ -1658,7 +1721,7 @@ bool dc_validate_boot_timing(const struct dc *dc,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (link_is_edp_ilr_optimization_required(link, crtc_timing)) {
|
||||
if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) {
|
||||
DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2001,53 +2064,6 @@ enum dc_status dc_commit_streams(struct dc *dc,
|
|||
return res;
|
||||
}
|
||||
|
||||
/* TODO: When the transition to the new commit sequence is done, remove this
|
||||
* function in favor of dc_commit_streams. */
|
||||
bool dc_commit_state(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
enum dc_status result = DC_ERROR_UNEXPECTED;
|
||||
int i;
|
||||
|
||||
/* TODO: Since change commit sequence can have a huge impact,
|
||||
* we decided to only enable it for DCN3x. However, as soon as
|
||||
* we get more confident about this change we'll need to enable
|
||||
* the new sequence for all ASICs. */
|
||||
if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
|
||||
result = dc_commit_streams(dc, context->streams, context->stream_count);
|
||||
return result == DC_OK;
|
||||
}
|
||||
|
||||
if (!streams_changed(dc, context->streams, context->stream_count)) {
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
DC_LOG_DC("%s: %d streams\n",
|
||||
__func__, context->stream_count);
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
struct dc_stream_state *stream = context->streams[i];
|
||||
|
||||
dc_stream_log(dc, stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Previous validation was perfomred with fast_validation = true and
|
||||
* the full DML state required for hardware programming was skipped.
|
||||
*
|
||||
* Re-validate here to calculate these parameters / watermarks.
|
||||
*/
|
||||
result = dc_validate_global_state(dc, context, false);
|
||||
if (result != DC_OK) {
|
||||
DC_LOG_ERROR("DC commit global validation failure: %s (%d)",
|
||||
dc_status_to_str(result), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = dc_commit_state_no_check(dc, context);
|
||||
|
||||
return (result == DC_OK);
|
||||
}
|
||||
|
||||
bool dc_acquire_release_mpc_3dlut(
|
||||
struct dc *dc, bool acquire,
|
||||
struct dc_stream_state *stream,
|
||||
|
|
@ -2134,27 +2150,33 @@ void dc_post_update_surfaces_to_stream(struct dc *dc)
|
|||
|
||||
post_surface_trace(dc);
|
||||
|
||||
if (dc->ctx->dce_version >= DCE_VERSION_MAX)
|
||||
TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk);
|
||||
else
|
||||
/*
|
||||
* Only relevant for DCN behavior where we can guarantee the optimization
|
||||
* is safe to apply - retain the legacy behavior for DCE.
|
||||
*/
|
||||
|
||||
if (dc->ctx->dce_version < DCE_VERSION_MAX)
|
||||
TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce);
|
||||
else {
|
||||
TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk);
|
||||
|
||||
if (is_flip_pending_in_pipes(dc, context))
|
||||
return;
|
||||
if (is_flip_pending_in_pipes(dc, context))
|
||||
return;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].stream == NULL ||
|
||||
context->res_ctx.pipe_ctx[i].plane_state == NULL) {
|
||||
context->res_ctx.pipe_ctx[i].pipe_idx = i;
|
||||
dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
|
||||
}
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].stream == NULL ||
|
||||
context->res_ctx.pipe_ctx[i].plane_state == NULL) {
|
||||
context->res_ctx.pipe_ctx[i].pipe_idx = i;
|
||||
dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
|
||||
}
|
||||
|
||||
process_deferred_updates(dc);
|
||||
process_deferred_updates(dc);
|
||||
|
||||
dc->hwss.optimize_bandwidth(dc, context);
|
||||
dc->hwss.optimize_bandwidth(dc, context);
|
||||
|
||||
if (dc->debug.enable_double_buffered_dsc_pg_support)
|
||||
dc->hwss.update_dsc_pg(dc, context, true);
|
||||
if (dc->debug.enable_double_buffered_dsc_pg_support)
|
||||
dc->hwss.update_dsc_pg(dc, context, true);
|
||||
}
|
||||
|
||||
dc->optimized_required = false;
|
||||
dc->wm_optimized_required = false;
|
||||
|
|
@ -3173,7 +3195,9 @@ 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))
|
||||
link_dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
|
||||
dc->link_srv->dp_trace_source_sequence(
|
||||
pipe_ctx->stream->link,
|
||||
DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
|
||||
}
|
||||
|
||||
if (stream_update->hdr_static_metadata &&
|
||||
|
|
@ -3209,13 +3233,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
|||
continue;
|
||||
|
||||
if (stream_update->dsc_config)
|
||||
link_update_dsc_config(pipe_ctx);
|
||||
dc->link_srv->update_dsc_config(pipe_ctx);
|
||||
|
||||
if (stream_update->mst_bw_update) {
|
||||
if (stream_update->mst_bw_update->is_increase)
|
||||
link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
|
||||
dc->link_srv->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);
|
||||
dc->link_srv->reduce_mst_payload(pipe_ctx,
|
||||
stream_update->mst_bw_update->mst_stream_bw);
|
||||
}
|
||||
|
||||
if (stream_update->pending_test_pattern) {
|
||||
|
|
@ -3229,7 +3255,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
|||
|
||||
if (stream_update->dpms_off) {
|
||||
if (*stream_update->dpms_off) {
|
||||
link_set_dpms_off(pipe_ctx);
|
||||
dc->link_srv->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 +3265,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);
|
||||
link_set_dpms_on(dc->current_state, pipe_ctx);
|
||||
dc->link_srv->set_dpms_on(dc->current_state, pipe_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3510,14 +3536,9 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
/* Since phantom pipe programming is moved to post_unlock_program_front_end,
|
||||
* move the SubVP lock to after the phantom pipes have been setup
|
||||
*/
|
||||
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
|
||||
} else {
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
|
||||
}
|
||||
|
||||
if (dc->hwss.subvp_pipe_control_lock)
|
||||
dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes,
|
||||
NULL, subvp_prev_use);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4083,24 +4104,30 @@ void dc_commit_updates_for_stream(struct dc *dc,
|
|||
struct dc_context *dc_ctx = dc->ctx;
|
||||
int i, j;
|
||||
|
||||
stream_status = dc_stream_get_status(stream);
|
||||
context = dc->current_state;
|
||||
|
||||
update_type = dc_check_update_surfaces_for_stream(
|
||||
dc, srf_updates, surface_count, stream_update, stream_status);
|
||||
|
||||
/* TODO: Since change commit sequence can have a huge impact,
|
||||
* we decided to only enable it for DCN3x. However, as soon as
|
||||
* we get more confident about this change we'll need to enable
|
||||
* the new sequence for all ASICs.
|
||||
*/
|
||||
if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
|
||||
/*
|
||||
* Previous frame finished and HW is ready for optimization.
|
||||
*/
|
||||
if (update_type == UPDATE_TYPE_FAST)
|
||||
dc_post_update_surfaces_to_stream(dc);
|
||||
|
||||
dc_update_planes_and_stream(dc, srf_updates,
|
||||
surface_count, stream,
|
||||
stream_update);
|
||||
return;
|
||||
}
|
||||
|
||||
stream_status = dc_stream_get_status(stream);
|
||||
context = dc->current_state;
|
||||
|
||||
update_type = dc_check_update_surfaces_for_stream(
|
||||
dc, srf_updates, surface_count, stream_update, stream_status);
|
||||
|
||||
if (update_type >= update_surface_trace_level)
|
||||
update_surface_trace(dc, srf_updates, surface_count);
|
||||
|
||||
|
|
@ -4123,12 +4150,9 @@ void dc_commit_updates_for_stream(struct dc *dc,
|
|||
if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
|
||||
new_pipe->plane_state->force_full_update = true;
|
||||
}
|
||||
} else if (update_type == UPDATE_TYPE_FAST && dc_ctx->dce_version >= DCE_VERSION_MAX) {
|
||||
} else if (update_type == UPDATE_TYPE_FAST) {
|
||||
/*
|
||||
* Previous frame finished and HW is ready for optimization.
|
||||
*
|
||||
* Only relevant for DCN behavior where we can guarantee the optimization
|
||||
* is safe to apply - retain the legacy behavior for DCE.
|
||||
*/
|
||||
dc_post_update_surfaces_to_stream(dc);
|
||||
}
|
||||
|
|
@ -4305,7 +4329,7 @@ void dc_resume(struct dc *dc)
|
|||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++)
|
||||
link_resume(dc->links[i]);
|
||||
dc->link_srv->resume(dc->links[i]);
|
||||
}
|
||||
|
||||
bool dc_is_dmcu_initialized(struct dc *dc)
|
||||
|
|
@ -4317,157 +4341,6 @@ bool dc_is_dmcu_initialized(struct dc *dc)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool dc_is_oem_i2c_device_present(
|
||||
struct dc *dc,
|
||||
size_t slave_address)
|
||||
{
|
||||
if (dc->res_pool->oem_device)
|
||||
return dce_i2c_oem_device_present(
|
||||
dc->res_pool,
|
||||
dc->res_pool->oem_device,
|
||||
slave_address);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dc_submit_i2c(
|
||||
struct dc *dc,
|
||||
uint32_t link_index,
|
||||
struct i2c_command *cmd)
|
||||
{
|
||||
|
||||
struct dc_link *link = dc->links[link_index];
|
||||
struct ddc_service *ddc = link->ddc;
|
||||
return dce_i2c_submit_command(
|
||||
dc->res_pool,
|
||||
ddc->ddc_pin,
|
||||
cmd);
|
||||
}
|
||||
|
||||
bool dc_submit_i2c_oem(
|
||||
struct dc *dc,
|
||||
struct i2c_command *cmd)
|
||||
{
|
||||
struct ddc_service *ddc = dc->res_pool->oem_device;
|
||||
if (ddc)
|
||||
return dce_i2c_submit_command(
|
||||
dc->res_pool,
|
||||
ddc->ddc_pin,
|
||||
cmd);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
|
||||
{
|
||||
if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return false;
|
||||
}
|
||||
|
||||
dc_sink_retain(sink);
|
||||
|
||||
dc_link->remote_sinks[dc_link->sink_count] = sink;
|
||||
dc_link->sink_count++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* dc_link_add_remote_sink() - Create a sink and attach it to an existing link
|
||||
*
|
||||
* EDID length is in bytes
|
||||
*/
|
||||
struct dc_sink *dc_link_add_remote_sink(
|
||||
struct dc_link *link,
|
||||
const uint8_t *edid,
|
||||
int len,
|
||||
struct dc_sink_init_data *init_data)
|
||||
{
|
||||
struct dc_sink *dc_sink;
|
||||
enum dc_edid_status edid_status;
|
||||
|
||||
if (len > DC_MAX_EDID_BUFFER_SIZE) {
|
||||
dm_error("Max EDID buffer size breached!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!init_data) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!init_data->link) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dc_sink = dc_sink_create(init_data);
|
||||
|
||||
if (!dc_sink)
|
||||
return NULL;
|
||||
|
||||
memmove(dc_sink->dc_edid.raw_edid, edid, len);
|
||||
dc_sink->dc_edid.length = len;
|
||||
|
||||
if (!link_add_remote_sink_helper(
|
||||
link,
|
||||
dc_sink))
|
||||
goto fail_add_sink;
|
||||
|
||||
edid_status = dm_helpers_parse_edid_caps(
|
||||
link,
|
||||
&dc_sink->dc_edid,
|
||||
&dc_sink->edid_caps);
|
||||
|
||||
/*
|
||||
* Treat device as no EDID device if EDID
|
||||
* parsing fails
|
||||
*/
|
||||
if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) {
|
||||
dc_sink->dc_edid.length = 0;
|
||||
dm_error("Bad EDID, status%d!\n", edid_status);
|
||||
}
|
||||
|
||||
return dc_sink;
|
||||
|
||||
fail_add_sink:
|
||||
dc_sink_release(dc_sink);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* dc_link_remove_remote_sink() - Remove a remote sink from a dc_link
|
||||
*
|
||||
* Note that this just removes the struct dc_sink - it doesn't
|
||||
* program hardware or alter other members of dc_link
|
||||
*/
|
||||
void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!link->sink_count) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < link->sink_count; i++) {
|
||||
if (link->remote_sinks[i] == sink) {
|
||||
dc_sink_release(sink);
|
||||
link->remote_sinks[i] = NULL;
|
||||
|
||||
/* shrink array to remove empty place */
|
||||
while (i < link->sink_count - 1) {
|
||||
link->remote_sinks[i] = link->remote_sinks[i+1];
|
||||
i++;
|
||||
}
|
||||
link->remote_sinks[i] = NULL;
|
||||
link->sink_count--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
|
||||
{
|
||||
info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz;
|
||||
|
|
@ -4990,7 +4863,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
|
|||
return;
|
||||
}
|
||||
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
dc_get_edp_links(dc, edp_links, &edp_num);
|
||||
|
||||
/* Determine panel inst */
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
|
|
|
|||
|
|
@ -73,28 +73,38 @@ struct out_csc_color_matrix_type {
|
|||
|
||||
static const struct out_csc_color_matrix_type output_csc_matrix[] = {
|
||||
{ COLOR_SPACE_RGB_TYPE,
|
||||
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{ 0x2000, 0, 0, 0,
|
||||
0, 0x2000, 0, 0,
|
||||
0, 0, 0x2000, 0} },
|
||||
{ COLOR_SPACE_RGB_LIMITED_TYPE,
|
||||
{ 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
|
||||
{ 0x1B67, 0, 0, 0x201,
|
||||
0, 0x1B67, 0, 0x201,
|
||||
0, 0, 0x1B67, 0x201} },
|
||||
{ COLOR_SPACE_YCBCR601_TYPE,
|
||||
{ 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45,
|
||||
0xF6B7, 0xE04, 0x1004} },
|
||||
{ 0xE04, 0xF444, 0xFDB9, 0x1004,
|
||||
0x831, 0x1016, 0x320, 0x201,
|
||||
0xFB45, 0xF6B7, 0xE04, 0x1004} },
|
||||
{ COLOR_SPACE_YCBCR709_TYPE,
|
||||
{ 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA,
|
||||
0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} },
|
||||
{ 0xE04, 0xF345, 0xFEB7, 0x1004,
|
||||
0x5D3, 0x1399, 0x1FA, 0x201,
|
||||
0xFCCA, 0xF533, 0xE04, 0x1004} },
|
||||
/* TODO: correct values below */
|
||||
{ COLOR_SPACE_YCBCR601_LIMITED_TYPE,
|
||||
{ 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
|
||||
0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
|
||||
{ 0xE00, 0xF447, 0xFDB9, 0x1000,
|
||||
0x991, 0x12C9, 0x3A6, 0x200,
|
||||
0xFB47, 0xF6B9, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR709_LIMITED_TYPE,
|
||||
{ 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
|
||||
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
|
||||
{ 0xE00, 0xF349, 0xFEB7, 0x1000,
|
||||
0x6CE, 0x16E3, 0x24F, 0x200,
|
||||
0xFCCB, 0xF535, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR2020_TYPE,
|
||||
{ 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
|
||||
0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
|
||||
{ 0x1000, 0xF149, 0xFEB7, 0x1004,
|
||||
0x0868, 0x15B2, 0x01E6, 0x201,
|
||||
0xFB88, 0xF478, 0x1000, 0x1004} },
|
||||
{ COLOR_SPACE_YCBCR709_BLACK_TYPE,
|
||||
{ 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000,
|
||||
0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x1000,
|
||||
0x0000, 0x0000, 0x0000, 0x0200,
|
||||
0x0000, 0x0000, 0x0000, 0x1000} },
|
||||
};
|
||||
|
||||
static bool is_rgb_type(
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream)
|
|||
/* DIGs do not support DP2.0 streams with 128b/132b encoding. */
|
||||
struct dc_link_settings link_settings = {0};
|
||||
|
||||
link_decide_link_settings(stream, &link_settings);
|
||||
stream->ctx->dc->link_srv->dp_decide_link_settings(stream, &link_settings);
|
||||
if ((link_settings.link_rate >= LINK_RATE_LOW) &&
|
||||
link_settings.link_rate <= LINK_RATE_HIGH3) {
|
||||
is_dig_stream = true;
|
||||
|
|
|
|||
|
|
@ -34,70 +34,443 @@
|
|||
* in this file which calls link functions.
|
||||
*/
|
||||
#include "link.h"
|
||||
#include "dce/dce_i2c.h"
|
||||
struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index)
|
||||
{
|
||||
return dc->links[link_index];
|
||||
}
|
||||
|
||||
void dc_get_edp_links(const struct dc *dc,
|
||||
struct dc_link **edp_links,
|
||||
int *edp_num)
|
||||
{
|
||||
int i;
|
||||
|
||||
*edp_num = 0;
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
// report any eDP links, even unconnected DDI's
|
||||
if (!dc->links[i])
|
||||
continue;
|
||||
if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) {
|
||||
edp_links[*edp_num] = dc->links[i];
|
||||
if (++(*edp_num) == MAX_NUM_EDP)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dc_get_edp_link_panel_inst(const struct dc *dc,
|
||||
const struct dc_link *link,
|
||||
unsigned int *inst_out)
|
||||
{
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
int edp_num, i;
|
||||
|
||||
*inst_out = 0;
|
||||
if (link->connector_signal != SIGNAL_TYPE_EDP)
|
||||
return false;
|
||||
dc_get_edp_links(dc, edp_links, &edp_num);
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
if (link == edp_links[i])
|
||||
break;
|
||||
(*inst_out)++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
|
||||
{
|
||||
return link_detect(link, reason);
|
||||
return link->dc->link_srv->detect_link(link, reason);
|
||||
}
|
||||
|
||||
bool dc_link_detect_connection_type(struct dc_link *link,
|
||||
enum dc_connection_type *type)
|
||||
{
|
||||
return link_detect_connection_type(link, type);
|
||||
return link->dc->link_srv->detect_connection_type(link, type);
|
||||
}
|
||||
|
||||
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
|
||||
{
|
||||
return link_get_status(link);
|
||||
return link->dc->link_srv->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);
|
||||
return link->dc->link_srv->is_hdcp1x_supported(link, signal);
|
||||
}
|
||||
|
||||
bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
|
||||
{
|
||||
return link_is_hdcp22(link, signal);
|
||||
return link->dc->link_srv->is_hdcp2x_supported(link, signal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void dc_link_clear_dprx_states(struct dc_link *link)
|
||||
{
|
||||
link_clear_dprx_states(link);
|
||||
link->dc->link_srv->clear_dprx_states(link);
|
||||
}
|
||||
|
||||
bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link)
|
||||
{
|
||||
return link_reset_cur_dp_mst_topology(link);
|
||||
return link->dc->link_srv->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);
|
||||
return link->dc->link_srv->dp_link_bandwidth_kbps(link, link_settings);
|
||||
}
|
||||
|
||||
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
|
||||
{
|
||||
link_get_cur_res_map(dc, map);
|
||||
dc->link_srv->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);
|
||||
dc->link_srv->restore_res_map(dc, map);
|
||||
}
|
||||
|
||||
bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
return link_update_dsc_config(pipe_ctx);
|
||||
struct dc_link *link = pipe_ctx->stream->link;
|
||||
|
||||
return link->dc->link_srv->update_dsc_config(pipe_ctx);
|
||||
}
|
||||
|
||||
bool dc_is_oem_i2c_device_present(
|
||||
struct dc *dc,
|
||||
size_t slave_address)
|
||||
{
|
||||
if (dc->res_pool->oem_device)
|
||||
return dce_i2c_oem_device_present(
|
||||
dc->res_pool,
|
||||
dc->res_pool->oem_device,
|
||||
slave_address);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dc_submit_i2c(
|
||||
struct dc *dc,
|
||||
uint32_t link_index,
|
||||
struct i2c_command *cmd)
|
||||
{
|
||||
|
||||
struct dc_link *link = dc->links[link_index];
|
||||
struct ddc_service *ddc = link->ddc;
|
||||
|
||||
return dce_i2c_submit_command(
|
||||
dc->res_pool,
|
||||
ddc->ddc_pin,
|
||||
cmd);
|
||||
}
|
||||
|
||||
bool dc_submit_i2c_oem(
|
||||
struct dc *dc,
|
||||
struct i2c_command *cmd)
|
||||
{
|
||||
struct ddc_service *ddc = dc->res_pool->oem_device;
|
||||
|
||||
if (ddc)
|
||||
return dce_i2c_submit_command(
|
||||
dc->res_pool,
|
||||
ddc->ddc_pin,
|
||||
cmd);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void dc_link_dp_handle_automated_test(struct dc_link *link)
|
||||
{
|
||||
link->dc->link_srv->dp_handle_automated_test(link);
|
||||
}
|
||||
|
||||
bool dc_link_dp_set_test_pattern(
|
||||
struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
enum dp_test_pattern_color_space test_pattern_color_space,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size)
|
||||
{
|
||||
return link->dc->link_srv->dp_set_test_pattern(link, test_pattern,
|
||||
test_pattern_color_space, p_link_settings,
|
||||
p_custom_pattern, cust_pattern_size);
|
||||
}
|
||||
|
||||
void dc_link_set_drive_settings(struct dc *dc,
|
||||
struct link_training_settings *lt_settings,
|
||||
struct dc_link *link)
|
||||
{
|
||||
struct link_resource link_res;
|
||||
|
||||
dc->link_srv->get_cur_link_res(link, &link_res);
|
||||
dc->link_srv->dp_set_drive_settings(link, &link_res, lt_settings);
|
||||
}
|
||||
|
||||
void dc_link_set_preferred_link_settings(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link *link)
|
||||
{
|
||||
dc->link_srv->dp_set_preferred_link_settings(dc, link_setting, link);
|
||||
}
|
||||
|
||||
void dc_link_set_preferred_training_settings(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link_training_overrides *lt_overrides,
|
||||
struct dc_link *link,
|
||||
bool skip_immediate_retrain)
|
||||
{
|
||||
dc->link_srv->dp_set_preferred_training_settings(dc, link_setting,
|
||||
lt_overrides, link, skip_immediate_retrain);
|
||||
}
|
||||
|
||||
bool dc_dp_trace_is_initialized(struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->dp_trace_is_initialized(link);
|
||||
}
|
||||
|
||||
void dc_dp_trace_set_is_logged_flag(struct dc_link *link,
|
||||
bool in_detection,
|
||||
bool is_logged)
|
||||
{
|
||||
link->dc->link_srv->dp_trace_set_is_logged_flag(link, in_detection, is_logged);
|
||||
}
|
||||
|
||||
bool dc_dp_trace_is_logged(struct dc_link *link, bool in_detection)
|
||||
{
|
||||
return link->dc->link_srv->dp_trace_is_logged(link, in_detection);
|
||||
}
|
||||
|
||||
unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link,
|
||||
bool in_detection)
|
||||
{
|
||||
return link->dc->link_srv->dp_trace_get_lt_end_timestamp(link, in_detection);
|
||||
}
|
||||
|
||||
const struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link,
|
||||
bool in_detection)
|
||||
{
|
||||
return link->dc->link_srv->dp_trace_get_lt_counts(link, in_detection);
|
||||
}
|
||||
|
||||
unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->dp_trace_get_link_loss_count(link);
|
||||
}
|
||||
|
||||
struct dc_sink *dc_link_add_remote_sink(
|
||||
struct dc_link *link,
|
||||
const uint8_t *edid,
|
||||
int len,
|
||||
struct dc_sink_init_data *init_data)
|
||||
{
|
||||
return link->dc->link_srv->add_remote_sink(link, edid, len, init_data);
|
||||
}
|
||||
|
||||
void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
|
||||
{
|
||||
link->dc->link_srv->remove_remote_sink(link, sink);
|
||||
}
|
||||
|
||||
int dc_link_aux_transfer_raw(struct ddc_service *ddc,
|
||||
struct aux_payload *payload,
|
||||
enum aux_return_code_type *operation_result)
|
||||
{
|
||||
const struct dc *dc = ddc->link->dc;
|
||||
|
||||
return dc->link_srv->aux_transfer_raw(
|
||||
ddc, payload, operation_result);
|
||||
}
|
||||
|
||||
uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(
|
||||
struct dc *dc, uint8_t bw)
|
||||
{
|
||||
return dc->link_srv->bw_kbps_from_raw_frl_link_rate_data(bw);
|
||||
}
|
||||
|
||||
bool dc_link_decide_edp_link_settings(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting, uint32_t req_bw)
|
||||
{
|
||||
return link->dc->link_srv->edp_decide_link_settings(link, link_setting, req_bw);
|
||||
}
|
||||
|
||||
|
||||
bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link,
|
||||
struct dc_link_settings *max_link_enc_cap)
|
||||
{
|
||||
return link->dc->link_srv->dp_get_max_link_enc_cap(link, max_link_enc_cap);
|
||||
}
|
||||
|
||||
enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(
|
||||
const struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->mst_decide_link_encoding_format(link);
|
||||
}
|
||||
|
||||
const struct dc_link_settings *dc_link_get_link_cap(const struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->dp_get_verified_link_cap(link);
|
||||
}
|
||||
|
||||
bool dc_link_is_dp_sink_present(struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->dp_is_sink_present(link);
|
||||
}
|
||||
|
||||
bool dc_link_is_fec_supported(const struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->dp_is_fec_supported(link);
|
||||
}
|
||||
|
||||
void dc_link_overwrite_extended_receiver_cap(
|
||||
struct dc_link *link)
|
||||
{
|
||||
link->dc->link_srv->dp_overwrite_extended_receiver_cap(link);
|
||||
}
|
||||
|
||||
bool dc_link_should_enable_fec(const struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->dp_should_enable_fec(link);
|
||||
}
|
||||
|
||||
int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(
|
||||
struct dc_link *link, int peak_bw)
|
||||
{
|
||||
return link->dc->link_srv->dpia_handle_usb4_bandwidth_allocation_for_link(link, peak_bw);
|
||||
}
|
||||
|
||||
void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result)
|
||||
{
|
||||
link->dc->link_srv->dpia_handle_bw_alloc_response(link, bw, result);
|
||||
}
|
||||
|
||||
bool dc_link_check_link_loss_status(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data)
|
||||
{
|
||||
return link->dc->link_srv->dp_parse_link_loss_status(link, hpd_irq_dpcd_data);
|
||||
}
|
||||
|
||||
bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->dp_should_allow_hpd_rx_irq(link);
|
||||
}
|
||||
|
||||
void dc_link_dp_handle_link_loss(struct dc_link *link)
|
||||
{
|
||||
link->dc->link_srv->dp_handle_link_loss(link);
|
||||
}
|
||||
|
||||
enum dc_status dc_link_dp_read_hpd_rx_irq_data(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *irq_data)
|
||||
{
|
||||
return link->dc->link_srv->dp_read_hpd_rx_irq_data(link, irq_data);
|
||||
}
|
||||
|
||||
bool dc_link_handle_hpd_rx_irq(struct dc_link *link,
|
||||
union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss,
|
||||
bool defer_handling, bool *has_left_work)
|
||||
{
|
||||
return link->dc->link_srv->dp_handle_hpd_rx_irq(link, out_hpd_irq_dpcd_data,
|
||||
out_link_loss, defer_handling, has_left_work);
|
||||
}
|
||||
|
||||
void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on)
|
||||
{
|
||||
link->dc->link_srv->dpcd_write_rx_power_ctrl(link, on);
|
||||
}
|
||||
|
||||
enum lttpr_mode dc_link_decide_lttpr_mode(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting)
|
||||
{
|
||||
return link->dc->link_srv->dp_decide_lttpr_mode(link, link_setting);
|
||||
}
|
||||
|
||||
void dc_link_edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd)
|
||||
{
|
||||
link->dc->link_srv->edp_panel_backlight_power_on(link, wait_for_hpd);
|
||||
}
|
||||
|
||||
int dc_link_get_backlight_level(const struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->edp_get_backlight_level(link);
|
||||
}
|
||||
|
||||
bool dc_link_get_backlight_level_nits(struct dc_link *link,
|
||||
uint32_t *backlight_millinits_avg,
|
||||
uint32_t *backlight_millinits_peak)
|
||||
{
|
||||
return link->dc->link_srv->edp_get_backlight_level_nits(link,
|
||||
backlight_millinits_avg,
|
||||
backlight_millinits_peak);
|
||||
}
|
||||
|
||||
bool dc_link_set_backlight_level(const struct dc_link *link,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp)
|
||||
{
|
||||
return link->dc->link_srv->edp_set_backlight_level(link,
|
||||
backlight_pwm_u16_16, frame_ramp);
|
||||
}
|
||||
|
||||
bool dc_link_set_backlight_level_nits(struct dc_link *link,
|
||||
bool isHDR,
|
||||
uint32_t backlight_millinits,
|
||||
uint32_t transition_time_in_ms)
|
||||
{
|
||||
return link->dc->link_srv->edp_set_backlight_level_nits(link, isHDR,
|
||||
backlight_millinits, transition_time_in_ms);
|
||||
}
|
||||
|
||||
int dc_link_get_target_backlight_pwm(const struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->edp_get_target_backlight_pwm(link);
|
||||
}
|
||||
|
||||
bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state)
|
||||
{
|
||||
return link->dc->link_srv->edp_get_psr_state(link, state);
|
||||
}
|
||||
|
||||
bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active,
|
||||
bool wait, bool force_static, const unsigned int *power_opts)
|
||||
{
|
||||
return link->dc->link_srv->edp_set_psr_allow_active(link, allow_active, wait,
|
||||
force_static, power_opts);
|
||||
}
|
||||
|
||||
bool dc_link_setup_psr(struct dc_link *link,
|
||||
const struct dc_stream_state *stream, struct psr_config *psr_config,
|
||||
struct psr_context *psr_context)
|
||||
{
|
||||
return link->dc->link_srv->edp_setup_psr(link, stream, psr_config, psr_context);
|
||||
}
|
||||
|
||||
bool dc_link_wait_for_t12(struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->edp_wait_for_t12(link);
|
||||
}
|
||||
|
||||
bool dc_link_get_hpd_state(struct dc_link *link)
|
||||
{
|
||||
return link->dc->link_srv->get_hpd_state(link);
|
||||
}
|
||||
|
||||
void dc_link_enable_hpd(const struct dc_link *link)
|
||||
{
|
||||
link->dc->link_srv->enable_hpd(link);
|
||||
}
|
||||
|
||||
void dc_link_disable_hpd(const struct dc_link *link)
|
||||
{
|
||||
link->dc->link_srv->disable_hpd(link);
|
||||
}
|
||||
|
||||
void dc_link_enable_hpd_filter(struct dc_link *link, bool enable)
|
||||
{
|
||||
link->dc->link_srv->enable_hpd_filter(link, enable);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
|
|||
init_data->num_virtual_links, dc);
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
case DCN_VERSION_1_0:
|
||||
case DCN_VERSION_1_01:
|
||||
res_pool = dcn10_create_resource_pool(init_data, dc);
|
||||
|
|
@ -276,7 +276,7 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
|
|||
case DCN_VERSION_3_21:
|
||||
res_pool = dcn321_create_resource_pool(init_data, dc);
|
||||
break;
|
||||
#endif
|
||||
#endif /* CONFIG_DRM_AMD_DC_FP */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2213,7 +2213,7 @@ enum dc_status dc_remove_stream_from_ctx(
|
|||
del_pipe->stream_res.stream_enc,
|
||||
false);
|
||||
|
||||
if (link_is_dp_128b_132b_signal(del_pipe)) {
|
||||
if (dc->link_srv->dp_is_128b_132b_signal(del_pipe)) {
|
||||
update_hpo_dp_stream_engine_usage(
|
||||
&new_ctx->res_ctx, dc->res_pool,
|
||||
del_pipe->stream_res.hpo_dp_stream_enc,
|
||||
|
|
@ -2513,9 +2513,10 @@ enum dc_status resource_map_pool_resources(
|
|||
* and link settings
|
||||
*/
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
if (!link_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings))
|
||||
if (!dc->link_srv->dp_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings))
|
||||
return DC_FAIL_DP_LINK_BANDWIDTH;
|
||||
if (link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
|
||||
if (dc->link_srv->dp_get_encoding_format(
|
||||
&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc =
|
||||
find_first_free_match_hpo_dp_stream_enc_for_link(
|
||||
&context->res_ctx, pool, stream);
|
||||
|
|
@ -3685,7 +3686,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 = link_validate_mode_timing(stream,
|
||||
res = dc->link_srv->validate_mode_timing(stream,
|
||||
link,
|
||||
&stream->timing);
|
||||
|
||||
|
|
@ -3812,7 +3813,7 @@ bool get_temp_dp_link_res(struct dc_link *link,
|
|||
|
||||
memset(link_res, 0, sizeof(*link_res));
|
||||
|
||||
if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
|
||||
if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
|
||||
link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx,
|
||||
dc->res_pool, link);
|
||||
if (!link_res->hpo_dp_link_enc)
|
||||
|
|
@ -4027,14 +4028,14 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm(
|
|||
else
|
||||
sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp;
|
||||
if (sec_pipe->stream->timing.flags.DSC == 1) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
dcn20_acquire_dsc(dc, &state->res_ctx, &sec_pipe->stream_res.dsc, pipe_idx);
|
||||
#endif
|
||||
ASSERT(sec_pipe->stream_res.dsc);
|
||||
if (sec_pipe->stream_res.dsc == NULL)
|
||||
return false;
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
dcn20_build_mapped_resource(dc, state, sec_pipe->stream);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -4046,7 +4047,7 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
|
|||
struct dc_state *context,
|
||||
struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
if (link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
|
||||
if (dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
|
||||
if (pipe_ctx->stream_res.hpo_dp_stream_enc == NULL) {
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc =
|
||||
find_first_free_match_hpo_dp_stream_enc_for_link(
|
||||
|
|
|
|||
|
|
@ -47,9 +47,7 @@ int dc_setup_system_context(struct dc *dc, struct dc_phy_addr_space_config *pa_c
|
|||
*/
|
||||
memcpy(&dc->vm_pa_config, pa_config, sizeof(struct dc_phy_addr_space_config));
|
||||
dc->vm_pa_config.valid = true;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
dc_z10_save_init(dc);
|
||||
#endif
|
||||
}
|
||||
|
||||
return num_vmids;
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@
|
|||
#include "dc_types.h"
|
||||
#include "grph_object_defs.h"
|
||||
#include "logger_types.h"
|
||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||
#include "hdcp_types.h"
|
||||
#endif
|
||||
#include "hdcp_msg_types.h"
|
||||
#include "gpio_types.h"
|
||||
#include "link_service_types.h"
|
||||
#include "grph_object_ctrl_defs.h"
|
||||
|
|
@ -47,7 +45,7 @@ struct aux_payload;
|
|||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.223"
|
||||
#define DC_VER "3.2.227"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
|
@ -84,8 +82,6 @@ enum det_size {
|
|||
|
||||
struct dc_plane_cap {
|
||||
enum dc_plane_type type;
|
||||
uint32_t blends_with_above : 1;
|
||||
uint32_t blends_with_below : 1;
|
||||
uint32_t per_pixel_alpha : 1;
|
||||
struct {
|
||||
uint32_t argb8888 : 1;
|
||||
|
|
@ -716,6 +712,7 @@ struct dc_bounding_box_overrides {
|
|||
struct dc_state;
|
||||
struct resource_pool;
|
||||
struct dce_hwseq;
|
||||
struct link_service;
|
||||
|
||||
/**
|
||||
* struct dc_debug_options - DC debug struct
|
||||
|
|
@ -795,6 +792,7 @@ struct dc_debug_options {
|
|||
unsigned int force_odm_combine; //bit vector based on otg inst
|
||||
unsigned int seamless_boot_odm_combine;
|
||||
unsigned int force_odm_combine_4to1; //bit vector based on otg inst
|
||||
int minimum_z8_residency_time;
|
||||
bool disable_z9_mpc;
|
||||
unsigned int force_fclk_khz;
|
||||
bool enable_tri_buf;
|
||||
|
|
@ -874,6 +872,7 @@ struct dc_debug_options {
|
|||
bool disable_unbounded_requesting;
|
||||
bool dig_fifo_off_in_blank;
|
||||
bool temp_mst_deallocation_sequence;
|
||||
bool override_dispclk_programming;
|
||||
};
|
||||
|
||||
struct gpu_info_soc_bounding_box_v1_0;
|
||||
|
|
@ -890,6 +889,7 @@ struct dc {
|
|||
|
||||
uint8_t link_count;
|
||||
struct dc_link *links[MAX_PIPES * 2];
|
||||
struct link_service *link_srv;
|
||||
|
||||
struct dc_state *current_state;
|
||||
struct resource_pool *res_pool;
|
||||
|
|
@ -991,11 +991,7 @@ struct dc_init_data {
|
|||
};
|
||||
|
||||
struct dc_callback_init {
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
struct cp_psp cp_psp;
|
||||
#else
|
||||
uint8_t reserved;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dc *dc_create(const struct dc_init_data *init_params);
|
||||
|
|
@ -1362,10 +1358,6 @@ enum dc_status dc_commit_streams(struct dc *dc,
|
|||
struct dc_stream_state *streams[],
|
||||
uint8_t stream_count);
|
||||
|
||||
/* TODO: When the transition to the new commit sequence is done, remove this
|
||||
* function in favor of dc_commit_streams. */
|
||||
bool dc_commit_state(struct dc *dc, struct dc_state *context);
|
||||
|
||||
struct dc_state *dc_create_state(struct dc *dc);
|
||||
struct dc_state *dc_copy_state(struct dc_state *src_ctx);
|
||||
void dc_retain_state(struct dc_state *context);
|
||||
|
|
@ -1378,9 +1370,163 @@ struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc,
|
|||
|
||||
uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Link Interfaces */
|
||||
/* TODO: remove this after resolving external dependencies */
|
||||
#include "dc_link.h"
|
||||
/*
|
||||
* A link contains one or more sinks and their connected status.
|
||||
* The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
|
||||
*/
|
||||
struct dc_link {
|
||||
struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK];
|
||||
unsigned int sink_count;
|
||||
struct dc_sink *local_sink;
|
||||
unsigned int link_index;
|
||||
enum dc_connection_type type;
|
||||
enum signal_type connector_signal;
|
||||
enum dc_irq_source irq_source_hpd;
|
||||
enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */
|
||||
|
||||
bool is_hpd_filter_disabled;
|
||||
bool dp_ss_off;
|
||||
|
||||
/**
|
||||
* @link_state_valid:
|
||||
*
|
||||
* If there is no link and local sink, this variable should be set to
|
||||
* false. Otherwise, it should be set to true; usually, the function
|
||||
* core_link_enable_stream sets this field to true.
|
||||
*/
|
||||
bool link_state_valid;
|
||||
bool aux_access_disabled;
|
||||
bool sync_lt_in_progress;
|
||||
bool skip_stream_reenable;
|
||||
bool is_internal_display;
|
||||
/** @todo Rename. Flag an endpoint as having a programmable mapping to a DIG encoder. */
|
||||
bool is_dig_mapping_flexible;
|
||||
bool hpd_status; /* HPD status of link without physical HPD pin. */
|
||||
bool is_hpd_pending; /* Indicates a new received hpd */
|
||||
bool is_automated; /* Indicates automated testing */
|
||||
|
||||
bool edp_sink_present;
|
||||
|
||||
struct dp_trace dp_trace;
|
||||
|
||||
/* caps is the same as reported_link_cap. link_traing use
|
||||
* reported_link_cap. Will clean up. TODO
|
||||
*/
|
||||
struct dc_link_settings reported_link_cap;
|
||||
struct dc_link_settings verified_link_cap;
|
||||
struct dc_link_settings cur_link_settings;
|
||||
struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX];
|
||||
struct dc_link_settings preferred_link_setting;
|
||||
/* preferred_training_settings are override values that
|
||||
* come from DM. DM is responsible for the memory
|
||||
* management of the override pointers.
|
||||
*/
|
||||
struct dc_link_training_overrides preferred_training_settings;
|
||||
struct dp_audio_test_data audio_test_data;
|
||||
|
||||
uint8_t ddc_hw_inst;
|
||||
|
||||
uint8_t hpd_src;
|
||||
|
||||
uint8_t link_enc_hw_inst;
|
||||
/* DIG link encoder ID. Used as index in link encoder resource pool.
|
||||
* For links with fixed mapping to DIG, this is not changed after dc_link
|
||||
* object creation.
|
||||
*/
|
||||
enum engine_id eng_id;
|
||||
|
||||
bool test_pattern_enabled;
|
||||
union compliance_test_state compliance_test_state;
|
||||
|
||||
void *priv;
|
||||
|
||||
struct ddc_service *ddc;
|
||||
|
||||
bool aux_mode;
|
||||
|
||||
/* Private to DC core */
|
||||
|
||||
const struct dc *dc;
|
||||
|
||||
struct dc_context *ctx;
|
||||
|
||||
struct panel_cntl *panel_cntl;
|
||||
struct link_encoder *link_enc;
|
||||
struct graphics_object_id link_id;
|
||||
/* Endpoint type distinguishes display endpoints which do not have entries
|
||||
* in the BIOS connector table from those that do. Helps when tracking link
|
||||
* encoder to display endpoint assignments.
|
||||
*/
|
||||
enum display_endpoint_type ep_type;
|
||||
union ddi_channel_mapping ddi_channel_mapping;
|
||||
struct connector_device_tag_info device_tag;
|
||||
struct dpcd_caps dpcd_caps;
|
||||
uint32_t dongle_max_pix_clk;
|
||||
unsigned short chip_caps;
|
||||
unsigned int dpcd_sink_count;
|
||||
struct hdcp_caps hdcp_caps;
|
||||
enum edp_revision edp_revision;
|
||||
union dpcd_sink_ext_caps dpcd_sink_ext_caps;
|
||||
|
||||
struct psr_settings psr_settings;
|
||||
|
||||
/* Drive settings read from integrated info table */
|
||||
struct dc_lane_settings bios_forced_drive_settings;
|
||||
|
||||
/* Vendor specific LTTPR workaround variables */
|
||||
uint8_t vendor_specific_lttpr_link_rate_wa;
|
||||
bool apply_vendor_specific_lttpr_link_rate_wa;
|
||||
|
||||
/* MST record stream using this link */
|
||||
struct link_flags {
|
||||
bool dp_keep_receiver_powered;
|
||||
bool dp_skip_DID2;
|
||||
bool dp_skip_reset_segment;
|
||||
bool dp_skip_fs_144hz;
|
||||
bool dp_mot_reset_segment;
|
||||
/* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */
|
||||
bool dpia_mst_dsc_always_on;
|
||||
/* Forced DPIA into TBT3 compatibility mode. */
|
||||
bool dpia_forced_tbt3_mode;
|
||||
bool dongle_mode_timing_override;
|
||||
} wa_flags;
|
||||
struct link_mst_stream_allocation_table mst_stream_alloc_table;
|
||||
|
||||
struct dc_link_status link_status;
|
||||
struct dprx_states dprx_states;
|
||||
|
||||
struct gpio *hpd_gpio;
|
||||
enum dc_link_fec_state fec_state;
|
||||
bool link_powered_externally; // Used to bypass hardware sequencing delays when panel is powered down forcibly
|
||||
|
||||
struct dc_panel_config panel_config;
|
||||
struct phy_state phy_state;
|
||||
// BW ALLOCATON USB4 ONLY
|
||||
struct dc_dpia_bw_alloc dpia_bw_alloc_config;
|
||||
};
|
||||
|
||||
/* Return an enumerated dc_link.
|
||||
* dc_link order is constant and determined at
|
||||
* boot time. They cannot be created or destroyed.
|
||||
* Use dc_get_caps() to get number of links.
|
||||
*/
|
||||
struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index);
|
||||
|
||||
/* Return instance id of the edp link. Inst 0 is primary edp link. */
|
||||
bool dc_get_edp_link_panel_inst(const struct dc *dc,
|
||||
const struct dc_link *link,
|
||||
unsigned int *inst_out);
|
||||
|
||||
/* Return an array of link pointers to edp links. */
|
||||
void dc_get_edp_links(const struct dc *dc,
|
||||
struct dc_link **edp_links,
|
||||
int *edp_num);
|
||||
|
||||
/* The function initiates detection handshake over the given link. It first
|
||||
* determines if there are display connections over the link. If so it initiates
|
||||
|
|
@ -1404,6 +1550,38 @@ uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
|
|||
*/
|
||||
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason);
|
||||
|
||||
struct dc_sink_init_data;
|
||||
|
||||
/* When link connection type is dc_connection_mst_branch, remote sink can be
|
||||
* added to the link. The interface creates a remote sink and associates it with
|
||||
* current link. The sink will be retained by link until remove remote sink is
|
||||
* called.
|
||||
*
|
||||
* @dc_link - link the remote sink will be added to.
|
||||
* @edid - byte array of EDID raw data.
|
||||
* @len - size of the edid in byte
|
||||
* @init_data -
|
||||
*/
|
||||
struct dc_sink *dc_link_add_remote_sink(
|
||||
struct dc_link *dc_link,
|
||||
const uint8_t *edid,
|
||||
int len,
|
||||
struct dc_sink_init_data *init_data);
|
||||
|
||||
/* Remove remote sink from a link with dc_connection_mst_branch connection type.
|
||||
* @link - link the sink should be removed from
|
||||
* @sink - sink to be removed.
|
||||
*/
|
||||
void dc_link_remove_remote_sink(
|
||||
struct dc_link *link,
|
||||
struct dc_sink *sink);
|
||||
|
||||
/* Enable HPD interrupt handler for a given link */
|
||||
void dc_link_enable_hpd(const struct dc_link *link);
|
||||
|
||||
/* Disable HPD interrupt handler for a given link */
|
||||
void dc_link_disable_hpd(const struct dc_link *link);
|
||||
|
||||
/* determine if there is a sink connected to the link
|
||||
*
|
||||
* @type - dc_connection_single if connected, dc_connection_none otherwise.
|
||||
|
|
@ -1417,14 +1595,115 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason);
|
|||
bool dc_link_detect_connection_type(struct dc_link *link,
|
||||
enum dc_connection_type *type);
|
||||
|
||||
/* query current hpd pin value
|
||||
* return - true HPD is asserted (HPD high), false otherwise (HPD low)
|
||||
*
|
||||
*/
|
||||
bool dc_link_get_hpd_state(struct dc_link *link);
|
||||
|
||||
/* 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
|
||||
/* enable/disable hardware HPD filter.
|
||||
*
|
||||
* @link - The link the HPD pin is associated with.
|
||||
* @enable = true - enable hardware HPD filter. HPD event will only queued to irq
|
||||
* handler once after no HPD change has been detected within dc default HPD
|
||||
* filtering interval since last HPD event. i.e if display keeps toggling hpd
|
||||
* pulses within default HPD interval, no HPD event will be received until HPD
|
||||
* toggles have stopped. Then HPD event will be queued to irq handler once after
|
||||
* dc default HPD filtering interval since last HPD event.
|
||||
*
|
||||
* @enable = false - disable hardware HPD filter. HPD event will be queued
|
||||
* immediately to irq handler after no HPD change has been detected within
|
||||
* IRQ_HPD (aka HPD short pulse) interval (i.e 2ms).
|
||||
*/
|
||||
void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
|
||||
|
||||
/* submit i2c read/write payloads through ddc channel
|
||||
* @link_index - index to a link with ddc in i2c mode
|
||||
* @cmd - i2c command structure
|
||||
* return - true if success, false otherwise.
|
||||
*/
|
||||
bool dc_submit_i2c(
|
||||
struct dc *dc,
|
||||
uint32_t link_index,
|
||||
struct i2c_command *cmd);
|
||||
|
||||
/* submit i2c read/write payloads through oem channel
|
||||
* @link_index - index to a link with ddc in i2c mode
|
||||
* @cmd - i2c command structure
|
||||
* return - true if success, false otherwise.
|
||||
*/
|
||||
bool dc_submit_i2c_oem(
|
||||
struct dc *dc,
|
||||
struct i2c_command *cmd);
|
||||
|
||||
enum aux_return_code_type;
|
||||
/* 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
|
||||
* transferred,or -1 on a failure.
|
||||
*/
|
||||
int dc_link_aux_transfer_raw(struct ddc_service *ddc,
|
||||
struct aux_payload *payload,
|
||||
enum aux_return_code_type *operation_result);
|
||||
|
||||
bool dc_is_oem_i2c_device_present(
|
||||
struct dc *dc,
|
||||
size_t slave_address
|
||||
);
|
||||
|
||||
/* 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
|
||||
|
||||
/* Notify DC about DP RX Interrupt (aka DP IRQ_HPD).
|
||||
*
|
||||
* TODO - When defer_handling is true the function will have a different purpose.
|
||||
* It no longer does complete hpd rx irq handling. We should create a separate
|
||||
* interface specifically for this case.
|
||||
*
|
||||
* Return:
|
||||
* true - Downstream port status changed. DM should call DC to do the
|
||||
* detection.
|
||||
* false - no change in Downstream port status. No further action required
|
||||
* from DM.
|
||||
*/
|
||||
bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss,
|
||||
bool defer_handling, bool *has_left_work);
|
||||
/* handle DP specs define test automation sequence*/
|
||||
void dc_link_dp_handle_automated_test(struct dc_link *link);
|
||||
|
||||
/* handle DP Link loss sequence and try to recover RX link loss with best
|
||||
* effort
|
||||
*/
|
||||
void dc_link_dp_handle_link_loss(struct dc_link *link);
|
||||
|
||||
/* Determine if hpd rx irq should be handled or ignored
|
||||
* return true - hpd rx irq should be handled.
|
||||
* return false - it is safe to ignore hpd rx irq event
|
||||
*/
|
||||
bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link);
|
||||
|
||||
/* Determine if link loss is indicated with a given hpd_irq_dpcd_data.
|
||||
* @link - link the hpd irq data associated with
|
||||
* @hpd_irq_dpcd_data - input hpd irq data
|
||||
* return - true if hpd irq data indicates a link lost
|
||||
*/
|
||||
bool dc_link_check_link_loss_status(struct dc_link *link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data);
|
||||
|
||||
/* Read hpd rx irq data from a given link
|
||||
* @link - link where the hpd irq data should be read from
|
||||
* @irq_data - output hpd irq data
|
||||
* return - DC_OK if hpd irq data is read successfully, otherwise hpd irq data
|
||||
* read has failed.
|
||||
*/
|
||||
enum dc_status dc_link_dp_read_hpd_rx_irq_data(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *irq_data);
|
||||
|
||||
/* 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.
|
||||
|
|
@ -1450,12 +1729,6 @@ 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.
|
||||
|
|
@ -1493,6 +1766,269 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
|
|||
* interface i.e stream_update->dsc_config
|
||||
*/
|
||||
bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
/* translate a raw link rate data to bandwidth in kbps */
|
||||
uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(
|
||||
struct dc *dc, uint8_t bw);
|
||||
|
||||
/* determine the optimal bandwidth given link and required bw.
|
||||
* @link - current detected link
|
||||
* @req_bw - requested bandwidth in kbps
|
||||
* @link_settings - returned most optimal link settings that can fit the
|
||||
* requested bandwidth
|
||||
* return - false if link can't support requested bandwidth, true if link
|
||||
* settings is found.
|
||||
*/
|
||||
bool dc_link_decide_edp_link_settings(struct dc_link *link,
|
||||
struct dc_link_settings *link_settings,
|
||||
uint32_t req_bw);
|
||||
|
||||
/* return the max dp link settings can be driven by the link without considering
|
||||
* connected RX device and its capability
|
||||
*/
|
||||
bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link,
|
||||
struct dc_link_settings *max_link_enc_cap);
|
||||
|
||||
/* determine when the link is driving MST mode, what DP link channel coding
|
||||
* format will be used. The decision will remain unchanged until next HPD event.
|
||||
*
|
||||
* @link - a link with DP RX connection
|
||||
* return - if stream is committed to this link with MST signal type, type of
|
||||
* channel coding format dc will choose.
|
||||
*/
|
||||
enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(
|
||||
const struct dc_link *link);
|
||||
|
||||
/* get max dp link settings the link can enable with all things considered. (i.e
|
||||
* TX/RX/Cable capabilities and dp override policies.
|
||||
*
|
||||
* @link - a link with DP RX connection
|
||||
* return - max dp link settings the link can enable.
|
||||
*
|
||||
*/
|
||||
const struct dc_link_settings *dc_link_get_link_cap(const struct dc_link *link);
|
||||
|
||||
/* Check if a RX (ex. DP sink, MST hub, passive or active dongle) is connected
|
||||
* to a link with dp connector signal type.
|
||||
* @link - a link with dp connector signal type
|
||||
* return - true if connected, false otherwise
|
||||
*/
|
||||
bool dc_link_is_dp_sink_present(struct dc_link *link);
|
||||
|
||||
/* Force DP lane settings update to main-link video signal and notify the change
|
||||
* to DP RX via DPCD. This is a debug interface used for video signal integrity
|
||||
* tuning purpose. The interface assumes link has already been enabled with DP
|
||||
* signal.
|
||||
*
|
||||
* @lt_settings - a container structure with desired hw_lane_settings
|
||||
*/
|
||||
void dc_link_set_drive_settings(struct dc *dc,
|
||||
struct link_training_settings *lt_settings,
|
||||
struct dc_link *link);
|
||||
|
||||
/* Enable a test pattern in Link or PHY layer in an active link for compliance
|
||||
* test or debugging purpose. The test pattern will remain until next un-plug.
|
||||
*
|
||||
* @link - active link with DP signal output enabled.
|
||||
* @test_pattern - desired test pattern to output.
|
||||
* NOTE: set to DP_TEST_PATTERN_VIDEO_MODE to disable previous test pattern.
|
||||
* @test_pattern_color_space - for video test pattern choose a desired color
|
||||
* space.
|
||||
* @p_link_settings - For PHY pattern choose a desired link settings
|
||||
* @p_custom_pattern - some test pattern will require a custom input to
|
||||
* customize some pattern details. Otherwise keep it to NULL.
|
||||
* @cust_pattern_size - size of the custom pattern input.
|
||||
*
|
||||
*/
|
||||
bool dc_link_dp_set_test_pattern(
|
||||
struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
enum dp_test_pattern_color_space test_pattern_color_space,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size);
|
||||
|
||||
/* Force DP link settings to always use a specific value until reboot to a
|
||||
* specific link. If link has already been enabled, the interface will also
|
||||
* switch to desired link settings immediately. This is a debug interface to
|
||||
* generic dp issue trouble shooting.
|
||||
*/
|
||||
void dc_link_set_preferred_link_settings(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link *link);
|
||||
|
||||
/* Force DP link to customize a specific link training behavior by overriding to
|
||||
* standard DP specs defined protocol. This is a debug interface to trouble shoot
|
||||
* display specific link training issues or apply some display specific
|
||||
* workaround in link training.
|
||||
*
|
||||
* @link_settings - if not NULL, force preferred link settings to the link.
|
||||
* @lt_override - a set of override pointers. If any pointer is none NULL, dc
|
||||
* will apply this particular override in future link training. If NULL is
|
||||
* passed in, dc resets previous overrides.
|
||||
* NOTE: DM must keep the memory from override pointers until DM resets preferred
|
||||
* training settings.
|
||||
*/
|
||||
void dc_link_set_preferred_training_settings(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link_training_overrides *lt_overrides,
|
||||
struct dc_link *link,
|
||||
bool skip_immediate_retrain);
|
||||
|
||||
/* return - true if FEC is supported with connected DP RX, false otherwise */
|
||||
bool dc_link_is_fec_supported(const struct dc_link *link);
|
||||
|
||||
/* query FEC enablement policy to determine if FEC will be enabled by dc during
|
||||
* link enablement.
|
||||
* return - true if FEC should be enabled, false otherwise.
|
||||
*/
|
||||
bool dc_link_should_enable_fec(const struct dc_link *link);
|
||||
|
||||
/* determine lttpr mode the current link should be enabled with a specific link
|
||||
* settings.
|
||||
*/
|
||||
enum lttpr_mode dc_link_decide_lttpr_mode(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting);
|
||||
|
||||
/* Force DP RX to update its power state.
|
||||
* NOTE: this interface doesn't update dp main-link. Calling this function will
|
||||
* cause DP TX main-link and DP RX power states out of sync. DM has to restore
|
||||
* RX power state back upon finish DM specific execution requiring DP RX in a
|
||||
* specific power state.
|
||||
* @on - true to set DP RX in D0 power state, false to set DP RX in D3 power
|
||||
* state.
|
||||
*/
|
||||
void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on);
|
||||
|
||||
/* Force link to read base dp receiver caps from dpcd 000h - 00Fh and overwrite
|
||||
* current value read from extended receiver cap from 02200h - 0220Fh.
|
||||
* Some DP RX has problems of providing accurate DP receiver caps from extended
|
||||
* field, this interface is a workaround to revert link back to use base caps.
|
||||
*/
|
||||
void dc_link_overwrite_extended_receiver_cap(
|
||||
struct dc_link *link);
|
||||
|
||||
void dc_link_edp_panel_backlight_power_on(struct dc_link *link,
|
||||
bool wait_for_hpd);
|
||||
|
||||
/* Set backlight level of an embedded panel (eDP, LVDS).
|
||||
* backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer
|
||||
* and 16 bit fractional, where 1.0 is max backlight value.
|
||||
*/
|
||||
bool dc_link_set_backlight_level(const struct dc_link *dc_link,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp);
|
||||
|
||||
/* Set/get nits-based backlight level of an embedded panel (eDP, LVDS). */
|
||||
bool dc_link_set_backlight_level_nits(struct dc_link *link,
|
||||
bool isHDR,
|
||||
uint32_t backlight_millinits,
|
||||
uint32_t transition_time_in_ms);
|
||||
|
||||
bool dc_link_get_backlight_level_nits(struct dc_link *link,
|
||||
uint32_t *backlight_millinits,
|
||||
uint32_t *backlight_millinits_peak);
|
||||
|
||||
int dc_link_get_backlight_level(const struct dc_link *dc_link);
|
||||
|
||||
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
|
||||
|
||||
bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable,
|
||||
bool wait, bool force_static, const unsigned int *power_opts);
|
||||
|
||||
bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
|
||||
|
||||
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);
|
||||
|
||||
/* On eDP links this function call will stall until T12 has elapsed.
|
||||
* If the panel is not in power off state, this function will return
|
||||
* immediately.
|
||||
*/
|
||||
bool dc_link_wait_for_t12(struct dc_link *link);
|
||||
|
||||
/* Determine if dp trace has been initialized to reflect upto date result *
|
||||
* return - true if trace is initialized and has valid data. False dp trace
|
||||
* doesn't have valid result.
|
||||
*/
|
||||
bool dc_dp_trace_is_initialized(struct dc_link *link);
|
||||
|
||||
/* Query a dp trace flag to indicate if the current dp trace data has been
|
||||
* logged before
|
||||
*/
|
||||
bool dc_dp_trace_is_logged(struct dc_link *link,
|
||||
bool in_detection);
|
||||
|
||||
/* Set dp trace flag to indicate whether DM has already logged the current dp
|
||||
* trace data. DM can set is_logged to true upon logging and check
|
||||
* dc_dp_trace_is_logged before logging to avoid logging the same result twice.
|
||||
*/
|
||||
void dc_dp_trace_set_is_logged_flag(struct dc_link *link,
|
||||
bool in_detection,
|
||||
bool is_logged);
|
||||
|
||||
/* Obtain driver time stamp for last dp link training end. The time stamp is
|
||||
* formatted based on dm_get_timestamp DM function.
|
||||
* @in_detection - true to get link training end time stamp of last link
|
||||
* training in detection sequence. false to get link training end time stamp
|
||||
* of last link training in commit (dpms) sequence
|
||||
*/
|
||||
unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link,
|
||||
bool in_detection);
|
||||
|
||||
/* Get how many link training attempts dc has done with latest sequence.
|
||||
* @in_detection - true to get link training count of last link
|
||||
* training in detection sequence. false to get link training count of last link
|
||||
* training in commit (dpms) sequence
|
||||
*/
|
||||
const struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link,
|
||||
bool in_detection);
|
||||
|
||||
/* Get how many link loss has happened since last link training attempts */
|
||||
unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link);
|
||||
|
||||
/*
|
||||
* USB4 DPIA BW ALLOCATION PUBLIC FUNCTIONS
|
||||
*/
|
||||
/*
|
||||
* Send a request from DP-Tx requesting to allocate BW remotely after
|
||||
* allocating it locally. This will get processed by CM and a CB function
|
||||
* will be called.
|
||||
*
|
||||
* @link: pointer to the dc_link struct instance
|
||||
* @req_bw: The requested bw in Kbyte to allocated
|
||||
*
|
||||
* return: none
|
||||
*/
|
||||
void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw);
|
||||
|
||||
/*
|
||||
* Handle function for when the status of the Request above is complete.
|
||||
* We will find out the result of allocating on CM and update structs.
|
||||
*
|
||||
* @link: pointer to the dc_link struct instance
|
||||
* @bw: Allocated or Estimated BW depending on the result
|
||||
* @result: Response type
|
||||
*
|
||||
* return: none
|
||||
*/
|
||||
void dc_link_handle_usb4_bw_alloc_response(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);
|
||||
|
||||
/* Sink Interfaces - A sink corresponds to a display output device */
|
||||
|
||||
struct dc_container_id {
|
||||
|
|
@ -1511,7 +2047,7 @@ struct dc_sink_dsc_caps {
|
|||
// 'true' if these are virtual DPCD's DSC caps (immediately upstream of sink in MST topology),
|
||||
// 'false' if they are sink's DSC caps
|
||||
bool is_virtual_dpcd_dsc;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
// 'true' if MST topology supports DSC passthrough for sink
|
||||
// 'false' if MST topology does not support DSC passthrough
|
||||
bool is_dsc_passthrough_supported;
|
||||
|
|
@ -1603,7 +2139,6 @@ void dc_resume(struct dc *dc);
|
|||
|
||||
void dc_power_down_on_boot(struct dc *dc);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||
/*
|
||||
* HDCP Interfaces
|
||||
*/
|
||||
|
|
@ -1611,7 +2146,6 @@ enum hdcp_message_status dc_process_hdcp_msg(
|
|||
enum signal_type signal,
|
||||
struct dc_link *link,
|
||||
struct hdcp_protection_message *message_info);
|
||||
#endif
|
||||
bool dc_is_dmcu_initialized(struct dc *dc);
|
||||
|
||||
enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping);
|
||||
|
|
|
|||
|
|
@ -421,7 +421,6 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
/**
|
||||
* populate_subvp_cmd_drr_info - Helper to populate DRR pipe info for the DMCUB subvp command
|
||||
*
|
||||
|
|
@ -638,7 +637,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
|
|||
pipe_data->pipe_config.subvp_data.main_vblank_end =
|
||||
main_timing->v_total - main_timing->v_front_porch - main_timing->v_addressable;
|
||||
pipe_data->pipe_config.subvp_data.mall_region_lines = phantom_timing->v_addressable;
|
||||
pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->pipe_idx;
|
||||
pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->stream_res.tg->inst;
|
||||
pipe_data->pipe_config.subvp_data.is_drr = subvp_pipe->stream->ignore_msa_timing_param;
|
||||
|
||||
/* Calculate the scaling factor from the src and dst height.
|
||||
|
|
@ -680,11 +679,11 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
|
|||
struct pipe_ctx *phantom_pipe = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (phantom_pipe->stream == subvp_pipe->stream->mall_stream_config.paired_stream) {
|
||||
pipe_data->pipe_config.subvp_data.phantom_pipe_index = phantom_pipe->pipe_idx;
|
||||
pipe_data->pipe_config.subvp_data.phantom_pipe_index = phantom_pipe->stream_res.tg->inst;
|
||||
if (phantom_pipe->bottom_pipe) {
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->bottom_pipe->pipe_idx;
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->bottom_pipe->plane_res.hubp->inst;
|
||||
} else if (phantom_pipe->next_odm_pipe) {
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->next_odm_pipe->pipe_idx;
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->next_odm_pipe->plane_res.hubp->inst;
|
||||
} else {
|
||||
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = 0;
|
||||
}
|
||||
|
|
@ -750,7 +749,8 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
|
|||
!pipe->top_pipe && !pipe->prev_odm_pipe &&
|
||||
pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
|
||||
} else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE) {
|
||||
} else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
// Don't need to check for ActiveDRAMClockChangeMargin < 0, not valid in cases where
|
||||
// we run through DML without calculating "natural" P-state support
|
||||
populate_subvp_cmd_vblank_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
|
||||
|
|
@ -775,7 +775,6 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
|
|||
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmub_diagnostic_data *diag_data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -921,12 +921,6 @@ struct dpcd_usb4_dp_tunneling_info {
|
|||
#ifndef DP_DFP_CAPABILITY_EXTENSION_SUPPORT
|
||||
#define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0A3
|
||||
#endif
|
||||
#ifndef DP_LINK_SQUARE_PATTERN
|
||||
#define DP_LINK_SQUARE_PATTERN 0x10F
|
||||
#endif
|
||||
#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX
|
||||
#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110
|
||||
#endif
|
||||
#ifndef DP_DSC_CONFIGURATION
|
||||
#define DP_DSC_CONFIGURATION 0x161
|
||||
#endif
|
||||
|
|
@ -939,12 +933,6 @@ struct dpcd_usb4_dp_tunneling_info {
|
|||
#ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL
|
||||
#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216
|
||||
#endif
|
||||
#ifndef DP_LINK_SQUARE_PATTERN
|
||||
#define DP_LINK_SQUARE_PATTERN 0x10F
|
||||
#endif
|
||||
#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX
|
||||
#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217
|
||||
#endif
|
||||
#ifndef DP_TEST_264BIT_CUSTOM_PATTERN_7_0
|
||||
#define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0X2230
|
||||
#endif
|
||||
|
|
@ -988,10 +976,6 @@ struct dpcd_usb4_dp_tunneling_info {
|
|||
#define DP_INTRA_HOP_AUX_REPLY_INDICATION (1 << 3)
|
||||
/* TODO - Use DRM header to replace above once available */
|
||||
#endif // DP_INTRA_HOP_AUX_REPLY_INDICATION
|
||||
|
||||
#ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE
|
||||
#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
|
||||
#endif
|
||||
union dp_main_line_channel_coding_cap {
|
||||
struct {
|
||||
uint8_t DP_8b_10b_SUPPORTED :1;
|
||||
|
|
@ -1261,4 +1245,161 @@ union dpcd_sink_ext_caps {
|
|||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
enum dc_link_fec_state {
|
||||
dc_link_fec_not_ready,
|
||||
dc_link_fec_ready,
|
||||
dc_link_fec_enabled
|
||||
};
|
||||
|
||||
union dpcd_psr_configuration {
|
||||
struct {
|
||||
unsigned char ENABLE : 1;
|
||||
unsigned char TRANSMITTER_ACTIVE_IN_PSR : 1;
|
||||
unsigned char CRC_VERIFICATION : 1;
|
||||
unsigned char FRAME_CAPTURE_INDICATION : 1;
|
||||
/* For eDP 1.4, PSR v2*/
|
||||
unsigned char LINE_CAPTURE_INDICATION : 1;
|
||||
/* For eDP 1.4, PSR v2*/
|
||||
unsigned char IRQ_HPD_WITH_CRC_ERROR : 1;
|
||||
unsigned char ENABLE_PSR2 : 1;
|
||||
unsigned char EARLY_TRANSPORT_ENABLE : 1;
|
||||
} bits;
|
||||
unsigned char raw;
|
||||
};
|
||||
|
||||
union dpcd_alpm_configuration {
|
||||
struct {
|
||||
unsigned char ENABLE : 1;
|
||||
unsigned char IRQ_HPD_ENABLE : 1;
|
||||
unsigned char RESERVED : 6;
|
||||
} bits;
|
||||
unsigned char raw;
|
||||
};
|
||||
|
||||
union dpcd_sink_active_vtotal_control_mode {
|
||||
struct {
|
||||
unsigned char ENABLE : 1;
|
||||
unsigned char RESERVED : 7;
|
||||
} bits;
|
||||
unsigned char raw;
|
||||
};
|
||||
|
||||
union psr_error_status {
|
||||
struct {
|
||||
unsigned char LINK_CRC_ERROR :1;
|
||||
unsigned char RFB_STORAGE_ERROR :1;
|
||||
unsigned char VSC_SDP_ERROR :1;
|
||||
unsigned char RESERVED :5;
|
||||
} bits;
|
||||
unsigned char raw;
|
||||
};
|
||||
|
||||
union psr_sink_psr_status {
|
||||
struct {
|
||||
unsigned char SINK_SELF_REFRESH_STATUS :3;
|
||||
unsigned char RESERVED :5;
|
||||
} bits;
|
||||
unsigned char raw;
|
||||
};
|
||||
|
||||
struct edp_trace_power_timestamps {
|
||||
uint64_t poweroff;
|
||||
uint64_t poweron;
|
||||
};
|
||||
|
||||
struct dp_trace_lt_counts {
|
||||
unsigned int total;
|
||||
unsigned int fail;
|
||||
};
|
||||
|
||||
enum link_training_result {
|
||||
LINK_TRAINING_SUCCESS,
|
||||
LINK_TRAINING_CR_FAIL_LANE0,
|
||||
LINK_TRAINING_CR_FAIL_LANE1,
|
||||
LINK_TRAINING_CR_FAIL_LANE23,
|
||||
/* CR DONE bit is cleared during EQ step */
|
||||
LINK_TRAINING_EQ_FAIL_CR,
|
||||
/* CR DONE bit is cleared but LANE0_CR_DONE is set during EQ step */
|
||||
LINK_TRAINING_EQ_FAIL_CR_PARTIAL,
|
||||
/* other failure during EQ step */
|
||||
LINK_TRAINING_EQ_FAIL_EQ,
|
||||
LINK_TRAINING_LQA_FAIL,
|
||||
/* one of the CR,EQ or symbol lock is dropped */
|
||||
LINK_TRAINING_LINK_LOSS,
|
||||
/* Abort link training (because sink unplugged) */
|
||||
LINK_TRAINING_ABORT,
|
||||
DP_128b_132b_LT_FAILED,
|
||||
DP_128b_132b_MAX_LOOP_COUNT_REACHED,
|
||||
DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT,
|
||||
DP_128b_132b_CDS_DONE_TIMEOUT,
|
||||
};
|
||||
|
||||
struct dp_trace_lt {
|
||||
struct dp_trace_lt_counts counts;
|
||||
struct dp_trace_timestamps {
|
||||
unsigned long long start;
|
||||
unsigned long long end;
|
||||
} timestamps;
|
||||
enum link_training_result result;
|
||||
bool is_logged;
|
||||
};
|
||||
|
||||
struct dp_trace {
|
||||
struct dp_trace_lt detect_lt_trace;
|
||||
struct dp_trace_lt commit_lt_trace;
|
||||
unsigned int link_loss_count;
|
||||
bool is_initialized;
|
||||
struct edp_trace_power_timestamps edp_trace_power_timestamps;
|
||||
};
|
||||
|
||||
/* TODO - This is a temporary location for any new DPCD definitions.
|
||||
* We should move these to drm_dp header.
|
||||
*/
|
||||
#ifndef DP_LINK_SQUARE_PATTERN
|
||||
#define DP_LINK_SQUARE_PATTERN 0x10F
|
||||
#endif
|
||||
#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX
|
||||
#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217
|
||||
#endif
|
||||
#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX
|
||||
#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110
|
||||
#endif
|
||||
#ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE
|
||||
#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
|
||||
#endif
|
||||
#ifndef DP_TUNNELING_IRQ
|
||||
#define DP_TUNNELING_IRQ (1 << 5)
|
||||
#endif
|
||||
/** USB4 DPCD BW Allocation Registers Chapter 10.7 **/
|
||||
#ifndef DP_TUNNELING_CAPABILITIES
|
||||
#define DP_TUNNELING_CAPABILITIES 0xE000D /* 1.4a */
|
||||
#endif
|
||||
#ifndef USB4_DRIVER_ID
|
||||
#define USB4_DRIVER_ID 0xE000F /* 1.4a */
|
||||
#endif
|
||||
#ifndef USB4_DRIVER_BW_CAPABILITY
|
||||
#define USB4_DRIVER_BW_CAPABILITY 0xE0020 /* 1.4a */
|
||||
#endif
|
||||
#ifndef DP_IN_ADAPTER_TUNNEL_INFO
|
||||
#define DP_IN_ADAPTER_TUNNEL_INFO 0xE0021 /* 1.4a */
|
||||
#endif
|
||||
#ifndef DP_BW_GRANULALITY
|
||||
#define DP_BW_GRANULALITY 0xE0022 /* 1.4a */
|
||||
#endif
|
||||
#ifndef ESTIMATED_BW
|
||||
#define ESTIMATED_BW 0xE0023 /* 1.4a */
|
||||
#endif
|
||||
#ifndef ALLOCATED_BW
|
||||
#define ALLOCATED_BW 0xE0024 /* 1.4a */
|
||||
#endif
|
||||
#ifndef DP_TUNNELING_STATUS
|
||||
#define DP_TUNNELING_STATUS 0xE0025 /* 1.4a */
|
||||
#endif
|
||||
#ifndef DPTX_BW_ALLOCATION_MODE_CONTROL
|
||||
#define DPTX_BW_ALLOCATION_MODE_CONTROL 0xE0030 /* 1.4a */
|
||||
#endif
|
||||
#ifndef REQUESTED_BW
|
||||
#define REQUESTED_BW 0xE0031 /* 1.4a */
|
||||
#endif
|
||||
#endif /* DC_DP_TYPES_H */
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ struct dc_dsc_policy {
|
|||
bool enable_dsc_when_not_needed;
|
||||
};
|
||||
|
||||
struct dc_dsc_config_options {
|
||||
uint32_t dsc_min_slice_height_override;
|
||||
uint32_t max_target_bpp_limit_override_x16;
|
||||
uint32_t slice_height_granularity;
|
||||
};
|
||||
|
||||
bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
|
||||
const uint8_t *dpcd_dsc_basic_data,
|
||||
const uint8_t *dpcd_dsc_ext_data,
|
||||
|
|
@ -71,8 +77,7 @@ bool dc_dsc_compute_bandwidth_range(
|
|||
bool dc_dsc_compute_config(
|
||||
const struct display_stream_compressor *dsc,
|
||||
const struct dsc_dec_dpcd_caps *dsc_sink_caps,
|
||||
uint32_t dsc_min_slice_height_override,
|
||||
uint32_t max_target_bpp_limit_override,
|
||||
const struct dc_dsc_config_options *options,
|
||||
uint32_t target_bandwidth_kbps,
|
||||
const struct dc_crtc_timing *timing,
|
||||
struct dc_dsc_config *dsc_cfg);
|
||||
|
|
@ -100,4 +105,6 @@ void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable);
|
|||
|
||||
void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable);
|
||||
|
||||
void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -829,7 +829,7 @@ struct dc_dsc_config {
|
|||
uint32_t version_minor; /* DSC minor version. Full version is formed as 1.version_minor. */
|
||||
bool ycbcr422_simple; /* Tell DSC engine to convert YCbCr 4:2:2 to 'YCbCr 4:2:2 simple'. */
|
||||
int32_t rc_buffer_size; /* DSC RC buffer block size in bytes */
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_DC_FP)
|
||||
bool is_frl; /* indicate if DSC is applied based on HDMI FRL sink's capability */
|
||||
#endif
|
||||
bool is_dp; /* indicate if DSC is applied based on DP's capability */
|
||||
|
|
@ -1085,5 +1085,19 @@ struct tg_color {
|
|||
uint16_t color_b_cb;
|
||||
};
|
||||
|
||||
enum symclk_state {
|
||||
SYMCLK_OFF_TX_OFF,
|
||||
SYMCLK_ON_TX_ON,
|
||||
SYMCLK_ON_TX_OFF,
|
||||
};
|
||||
|
||||
struct phy_state {
|
||||
struct {
|
||||
uint8_t otg : 1;
|
||||
uint8_t reserved : 7;
|
||||
} symclk_ref_cnts;
|
||||
enum symclk_state symclk_state;
|
||||
};
|
||||
|
||||
#endif /* DC_HW_TYPES_H */
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user