mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
amd-drm-next-6.9-2024-03-01:
amdgpu: - GC 11.5.1 updates - Misc display cleanups - NBIO 7.9 updates - Backlight fixes - DMUB fixes - MPO fixes - atomfirmware table updates - SR-IOV fixes - VCN 4.x updates - use RMW accessors for pci config registers - PSR fixes - Suspend/resume fixes - RAS fixes - ABM fixes - Misc code cleanups - SI DPM fix - Revert freesync video amdkfd: - Misc cleanups - Error handling fixes radeon: - use RMW accessors for pci config registers -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZeI9fgAKCRC93/aFa7yZ 2DmCAQCVUsteinfHeJiyd7+pWnZdJVKzy5fRayvfOV8InHapawD/RAMlJhxy08IO B8tw7HY+YqRqW12T3klwRiBTk3Iw9Ac= =vBW4 -----END PGP SIGNATURE----- Merge tag 'amd-drm-next-6.9-2024-03-01' of https://gitlab.freedesktop.org/agd5f/linux into drm-next amd-drm-next-6.9-2024-03-01: amdgpu: - GC 11.5.1 updates - Misc display cleanups - NBIO 7.9 updates - Backlight fixes - DMUB fixes - MPO fixes - atomfirmware table updates - SR-IOV fixes - VCN 4.x updates - use RMW accessors for pci config registers - PSR fixes - Suspend/resume fixes - RAS fixes - ABM fixes - Misc code cleanups - SI DPM fix - Revert freesync video amdkfd: - Misc cleanups - Error handling fixes radeon: - use RMW accessors for pci config registers From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240301204857.13960-1-alexander.deucher@amd.com Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
commit
af165fb00a
@ -194,6 +194,7 @@ extern int amdgpu_emu_mode;
|
||||
extern uint amdgpu_smu_memory_pool_size;
|
||||
extern int amdgpu_smu_pptable_id;
|
||||
extern uint amdgpu_dc_feature_mask;
|
||||
extern uint amdgpu_freesync_vid_mode;
|
||||
extern uint amdgpu_dc_debug_mask;
|
||||
extern uint amdgpu_dc_visual_confirm;
|
||||
extern int amdgpu_dm_abm_level;
|
||||
|
@ -742,6 +742,11 @@ void amdgpu_amdkfd_debug_mem_fence(struct amdgpu_device *adev)
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_is_fed(struct amdgpu_device *adev)
|
||||
{
|
||||
return amdgpu_ras_get_fed_status(adev);
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, bool reset)
|
||||
{
|
||||
|
@ -320,7 +320,7 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
|
||||
void **kptr, uint64_t *size);
|
||||
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem);
|
||||
|
||||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo);
|
||||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_bo *bo);
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
|
||||
struct dma_fence __rcu **ef);
|
||||
@ -337,6 +337,7 @@ 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,
|
||||
enum amdgpu_ras_block block, bool reset);
|
||||
bool amdgpu_amdkfd_is_fed(struct amdgpu_device *adev);
|
||||
bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *mem);
|
||||
void amdgpu_amdkfd_block_mmu_notifications(void *p);
|
||||
int amdgpu_amdkfd_criu_resume(void *p);
|
||||
|
@ -2189,13 +2189,12 @@ int amdgpu_amdkfd_gpuvm_sync_memory(
|
||||
|
||||
/**
|
||||
* amdgpu_amdkfd_map_gtt_bo_to_gart - Map BO to GART and increment reference count
|
||||
* @adev: Device to which allocated BO belongs
|
||||
* @bo: Buffer object to be mapped
|
||||
*
|
||||
* Before return, bo reference count is incremented. To release the reference and unpin/
|
||||
* unmap the BO, call amdgpu_amdkfd_free_gtt_mem.
|
||||
*/
|
||||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo)
|
||||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_bo *bo)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -4040,8 +4040,10 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
* early on during init and before calling to RREG32.
|
||||
*/
|
||||
adev->reset_domain = amdgpu_reset_create_reset_domain(SINGLE_DEVICE, "amdgpu-reset-dev");
|
||||
if (!adev->reset_domain)
|
||||
return -ENOMEM;
|
||||
if (!adev->reset_domain) {
|
||||
r = -ENOMEM;
|
||||
goto unmap_memory;
|
||||
}
|
||||
|
||||
/* detect hw virtualization here */
|
||||
amdgpu_detect_virtualization(adev);
|
||||
@ -4051,20 +4053,20 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
r = amdgpu_device_get_job_timeout_settings(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "invalid lockup_timeout parameter syntax\n");
|
||||
return r;
|
||||
goto unmap_memory;
|
||||
}
|
||||
|
||||
/* early init functions */
|
||||
r = amdgpu_device_ip_early_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
goto unmap_memory;
|
||||
|
||||
amdgpu_device_set_mcbp(adev);
|
||||
|
||||
/* Get rid of things like offb */
|
||||
r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, &amdgpu_kms_driver);
|
||||
if (r)
|
||||
return r;
|
||||
goto unmap_memory;
|
||||
|
||||
/* Enable TMZ based on IP_VERSION */
|
||||
amdgpu_gmc_tmz_set(adev);
|
||||
@ -4074,7 +4076,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
if (adev->gmc.xgmi.supported) {
|
||||
r = adev->gfxhub.funcs->get_xgmi_info(adev);
|
||||
if (r)
|
||||
return r;
|
||||
goto unmap_memory;
|
||||
}
|
||||
|
||||
/* enable PCIE atomic ops */
|
||||
@ -4343,6 +4345,8 @@ release_ras_con:
|
||||
failed:
|
||||
amdgpu_vf_error_trans_all(adev);
|
||||
|
||||
unmap_memory:
|
||||
iounmap(adev->rmmio);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -5321,6 +5325,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
if (need_full_reset) {
|
||||
/* post card */
|
||||
amdgpu_ras_set_fed(tmp_adev, false);
|
||||
r = amdgpu_device_asic_init(tmp_adev);
|
||||
if (r) {
|
||||
dev_warn(tmp_adev->dev, "asic atom init failed!");
|
||||
|
@ -1683,6 +1683,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
|
||||
break;
|
||||
default:
|
||||
@ -1730,6 +1731,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@ -2003,6 +2005,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@ -2137,6 +2140,7 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_3_ip_block);
|
||||
break;
|
||||
case IP_VERSION(4, 0, 5):
|
||||
case IP_VERSION(4, 0, 6):
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v4_0_5_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_5_ip_block);
|
||||
break;
|
||||
@ -2182,6 +2186,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
|
||||
adev->enable_mes = true;
|
||||
adev->enable_mes_kiq = true;
|
||||
@ -2460,6 +2465,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
adev->family = AMDGPU_FAMILY_GC_11_0_1;
|
||||
break;
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
adev->family = AMDGPU_FAMILY_GC_11_5_0;
|
||||
break;
|
||||
default:
|
||||
@ -2479,6 +2485,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
adev->flags |= AMD_IS_APU;
|
||||
break;
|
||||
default:
|
||||
|
@ -1350,14 +1350,6 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
|
||||
"dither",
|
||||
amdgpu_dither_enum_list, sz);
|
||||
|
||||
if (adev->dc_enabled) {
|
||||
adev->mode_info.abm_level_property =
|
||||
drm_property_create_range(adev_to_drm(adev), 0,
|
||||
"abm level", 0, 4);
|
||||
if (!adev->mode_info.abm_level_property)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -199,6 +199,7 @@ int amdgpu_mes_kiq;
|
||||
int amdgpu_noretry = -1;
|
||||
int amdgpu_force_asic_type = -1;
|
||||
int amdgpu_tmz = -1; /* auto */
|
||||
uint amdgpu_freesync_vid_mode;
|
||||
int amdgpu_reset_method = -1; /* auto */
|
||||
int amdgpu_num_kcq = -1;
|
||||
int amdgpu_smartshift_bias;
|
||||
@ -883,6 +884,32 @@ module_param_named(damageclips, amdgpu_damage_clips, int, 0444);
|
||||
MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)");
|
||||
module_param_named(tmz, amdgpu_tmz, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: freesync_video (uint)
|
||||
* Enable the optimization to adjust front porch timing to achieve seamless
|
||||
* mode change experience when setting a freesync supported mode for which full
|
||||
* modeset is not needed.
|
||||
*
|
||||
* The Display Core will add a set of modes derived from the base FreeSync
|
||||
* video mode into the corresponding connector's mode list based on commonly
|
||||
* used refresh rates and VRR range of the connected display, when users enable
|
||||
* this feature. From the userspace perspective, they can see a seamless mode
|
||||
* change experience when the change between different refresh rates under the
|
||||
* same resolution. Additionally, userspace applications such as Video playback
|
||||
* can read this modeset list and change the refresh rate based on the video
|
||||
* frame rate. Finally, the userspace can also derive an appropriate mode for a
|
||||
* particular refresh rate based on the FreeSync Mode and add it to the
|
||||
* connector's mode list.
|
||||
*
|
||||
* Note: This is an experimental feature.
|
||||
*
|
||||
* The default value: 0 (off).
|
||||
*/
|
||||
MODULE_PARM_DESC(
|
||||
freesync_video,
|
||||
"Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
|
||||
module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
|
||||
|
||||
/**
|
||||
* DOC: reset_method (int)
|
||||
* GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
|
||||
@ -2764,8 +2791,7 @@ static int amdgpu_pmops_runtime_idle(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
/* we don't want the main rpm_idle to call suspend - we want to autosuspend */
|
||||
int ret = 1;
|
||||
int ret;
|
||||
|
||||
if (adev->pm.rpm_mode == AMDGPU_RUNPM_NONE) {
|
||||
pm_runtime_forbid(dev);
|
||||
|
@ -61,9 +61,7 @@ static struct kmem_cache *amdgpu_fence_slab;
|
||||
|
||||
int amdgpu_fence_slab_init(void)
|
||||
{
|
||||
amdgpu_fence_slab = kmem_cache_create(
|
||||
"amdgpu_fence", sizeof(struct amdgpu_fence), 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL);
|
||||
amdgpu_fence_slab = KMEM_CACHE(amdgpu_fence, SLAB_HWCACHE_ALIGN);
|
||||
if (!amdgpu_fence_slab)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
|
@ -304,11 +304,11 @@ static int amdgpu_gfx_kiq_acquire(struct amdgpu_device *adev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring,
|
||||
struct amdgpu_irq_src *irq, int xcc_id)
|
||||
int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, int xcc_id)
|
||||
{
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
|
||||
struct amdgpu_irq_src *irq = &kiq->irq;
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
int r = 0;
|
||||
|
||||
spin_lock_init(&kiq->ring_lock);
|
||||
|
@ -471,9 +471,7 @@ static inline u32 amdgpu_gfx_create_bitmask(u32 bit_width)
|
||||
void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se,
|
||||
unsigned max_sh);
|
||||
|
||||
int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring,
|
||||
struct amdgpu_irq_src *irq, int xcc_id);
|
||||
int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, int xcc_id);
|
||||
|
||||
void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring);
|
||||
|
||||
|
@ -843,6 +843,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
||||
case IP_VERSION(10, 3, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
/* Don't enable it by default yet.
|
||||
*/
|
||||
if (amdgpu_tmz < 1) {
|
||||
|
@ -324,8 +324,6 @@ struct amdgpu_mode_info {
|
||||
struct drm_property *audio_property;
|
||||
/* FMT dithering */
|
||||
struct drm_property *dither_property;
|
||||
/* Adaptive Backlight Modulation (power feature) */
|
||||
struct drm_property *abm_level_property;
|
||||
/* hardcoded DFP edid from BIOS */
|
||||
struct edid *bios_hardcoded_edid;
|
||||
int bios_hardcoded_edid_size;
|
||||
|
@ -53,14 +53,6 @@ u64 amdgpu_nbio_get_pcie_replay_count(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_nbio_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0,
|
||||
uint64_t *count1)
|
||||
{
|
||||
if (adev->nbio.funcs->get_pcie_usage)
|
||||
adev->nbio.funcs->get_pcie_usage(adev, count0, count1);
|
||||
|
||||
}
|
||||
|
||||
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
|
||||
{
|
||||
int r;
|
||||
|
@ -102,8 +102,6 @@ struct amdgpu_nbio_funcs {
|
||||
u32 (*get_memory_partition_mode)(struct amdgpu_device *adev,
|
||||
u32 *supp_modes);
|
||||
u64 (*get_pcie_replay_count)(struct amdgpu_device *adev);
|
||||
void (*get_pcie_usage)(struct amdgpu_device *adev, uint64_t *count0,
|
||||
uint64_t *count1);
|
||||
};
|
||||
|
||||
struct amdgpu_nbio {
|
||||
@ -116,7 +114,6 @@ struct amdgpu_nbio {
|
||||
};
|
||||
|
||||
int amdgpu_nbio_ras_sw_init(struct amdgpu_device *adev);
|
||||
void amdgpu_nbio_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0, uint64_t *count1);
|
||||
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
u64 amdgpu_nbio_get_pcie_replay_count(struct amdgpu_device *adev);
|
||||
|
||||
|
@ -2439,6 +2439,18 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
|
||||
ras->gpu_reset_flags &= ~AMDGPU_RAS_GPU_RESET_MODE1_RESET;
|
||||
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
|
||||
/* For any RAS error that needs a full reset to
|
||||
* recover, set the fatal error status
|
||||
*/
|
||||
if (hive) {
|
||||
list_for_each_entry(remote_adev,
|
||||
&hive->device_list,
|
||||
gmc.xgmi.head)
|
||||
amdgpu_ras_set_fed(remote_adev,
|
||||
true);
|
||||
} else {
|
||||
amdgpu_ras_set_fed(adev, true);
|
||||
}
|
||||
psp_fatal_error_recovery_quirk(&adev->psp);
|
||||
}
|
||||
}
|
||||
@ -3440,6 +3452,26 @@ int amdgpu_ras_fini(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool amdgpu_ras_get_fed_status(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *ras;
|
||||
|
||||
ras = amdgpu_ras_get_context(adev);
|
||||
if (!ras)
|
||||
return false;
|
||||
|
||||
return atomic_read(&ras->fed);
|
||||
}
|
||||
|
||||
void amdgpu_ras_set_fed(struct amdgpu_device *adev, bool status)
|
||||
{
|
||||
struct amdgpu_ras *ras;
|
||||
|
||||
ras = amdgpu_ras_get_context(adev);
|
||||
if (ras)
|
||||
atomic_set(&ras->fed, !!status);
|
||||
}
|
||||
|
||||
void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev)
|
||||
{
|
||||
if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) {
|
||||
@ -3620,6 +3652,7 @@ int amdgpu_ras_is_supported(struct amdgpu_device *adev,
|
||||
block == AMDGPU_RAS_BLOCK__SDMA ||
|
||||
block == AMDGPU_RAS_BLOCK__VCN ||
|
||||
block == AMDGPU_RAS_BLOCK__JPEG) &&
|
||||
(amdgpu_ras_mask & (1 << block)) &&
|
||||
amdgpu_ras_is_poison_mode_supported(adev) &&
|
||||
amdgpu_ras_get_ras_block(adev, block, 0))
|
||||
ret = 1;
|
||||
|
@ -477,6 +477,8 @@ struct amdgpu_ras {
|
||||
wait_queue_head_t page_retirement_wq;
|
||||
struct mutex page_retirement_lock;
|
||||
atomic_t page_retirement_req_cnt;
|
||||
/* Fatal error detected flag */
|
||||
atomic_t fed;
|
||||
};
|
||||
|
||||
struct ras_fs_data {
|
||||
@ -873,4 +875,8 @@ void amdgpu_ras_add_mca_err_addr(struct ras_err_info *err_info,
|
||||
|
||||
void amdgpu_ras_del_mca_err_addr(struct ras_err_info *err_info,
|
||||
struct ras_err_addr *mca_err_addr);
|
||||
|
||||
void amdgpu_ras_set_fed(struct amdgpu_device *adev, bool status);
|
||||
bool amdgpu_ras_get_fed_status(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
@ -159,9 +159,7 @@ int amdgpu_ring_mux_init(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring,
|
||||
mux->ring_entry_size = entry_size;
|
||||
mux->s_resubmit = false;
|
||||
|
||||
amdgpu_mux_chunk_slab = kmem_cache_create("amdgpu_mux_chunk",
|
||||
sizeof(struct amdgpu_mux_chunk), 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL);
|
||||
amdgpu_mux_chunk_slab = KMEM_CACHE(amdgpu_mux_chunk, SLAB_HWCACHE_ALIGN);
|
||||
if (!amdgpu_mux_chunk_slab) {
|
||||
DRM_ERROR("create amdgpu_mux_chunk cache failed\n");
|
||||
return -ENOMEM;
|
||||
|
@ -441,9 +441,7 @@ void amdgpu_sync_free(struct amdgpu_sync *sync)
|
||||
*/
|
||||
int amdgpu_sync_init(void)
|
||||
{
|
||||
amdgpu_sync_slab = kmem_cache_create(
|
||||
"amdgpu_sync", sizeof(struct amdgpu_sync_entry), 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL);
|
||||
amdgpu_sync_slab = KMEM_CACHE(amdgpu_sync_entry, SLAB_HWCACHE_ALIGN);
|
||||
if (!amdgpu_sync_slab)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
#define FIRMWARE_VCN4_0_3 "amdgpu/vcn_4_0_3.bin"
|
||||
#define FIRMWARE_VCN4_0_4 "amdgpu/vcn_4_0_4.bin"
|
||||
#define FIRMWARE_VCN4_0_5 "amdgpu/vcn_4_0_5.bin"
|
||||
#define FIRMWARE_VCN4_0_6 "amdgpu/vcn_4_0_6.bin"
|
||||
#define FIRMWARE_VCN5_0_0 "amdgpu/vcn_5_0_0.bin"
|
||||
|
||||
MODULE_FIRMWARE(FIRMWARE_RAVEN);
|
||||
@ -83,6 +84,7 @@ MODULE_FIRMWARE(FIRMWARE_VCN4_0_2);
|
||||
MODULE_FIRMWARE(FIRMWARE_VCN4_0_3);
|
||||
MODULE_FIRMWARE(FIRMWARE_VCN4_0_4);
|
||||
MODULE_FIRMWARE(FIRMWARE_VCN4_0_5);
|
||||
MODULE_FIRMWARE(FIRMWARE_VCN4_0_6);
|
||||
MODULE_FIRMWARE(FIRMWARE_VCN5_0_0);
|
||||
|
||||
static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
|
||||
|
@ -979,7 +979,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
|
||||
* SCRATCH_REG0 = read/write value
|
||||
* SCRATCH_REG1[30:28] = command
|
||||
* SCRATCH_REG1[19:0] = address in dword
|
||||
* SCRATCH_REG1[26:24] = Error reporting
|
||||
* SCRATCH_REG1[27:24] = Error reporting
|
||||
*/
|
||||
writel(v, scratch_reg0);
|
||||
writel((offset | flag), scratch_reg1);
|
||||
@ -993,7 +993,8 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
if (i >= timeout) {
|
||||
tmp = readl(scratch_reg1);
|
||||
if (i >= timeout || (tmp & AMDGPU_RLCG_SCRATCH1_ERROR_MASK) != 0) {
|
||||
if (amdgpu_sriov_rlcg_error_report_enabled(adev)) {
|
||||
if (tmp & AMDGPU_RLCG_VFGATE_DISABLED) {
|
||||
dev_err(adev->dev,
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define AMDGPU_RLCG_REG_NOT_IN_RANGE 0x1000000
|
||||
|
||||
#define AMDGPU_RLCG_SCRATCH1_ADDRESS_MASK 0xFFFFF
|
||||
#define AMDGPU_RLCG_SCRATCH1_ERROR_MASK 0xF000000
|
||||
|
||||
/* all asic after AI use this offset */
|
||||
#define mmRCC_IOV_FUNC_IDENTIFIER 0xDE5
|
||||
|
@ -320,7 +320,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
|
||||
DEBUG("IMM 0x%02X\n", val);
|
||||
return val;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
case ATOM_ARG_PLL:
|
||||
idx = U8(*ptr);
|
||||
(*ptr)++;
|
||||
|
@ -1638,28 +1638,18 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
PCI_EXP_LNKCTL_HAWD);
|
||||
|
||||
/* linkctl2 */
|
||||
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (bridge_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(root,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
|
||||
pcie_capability_read_word(adev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (gpu_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(adev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
bridge_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
gpu_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
|
||||
tmp = RREG32_PCIE(ixPCIE_LC_CNTL4);
|
||||
tmp &= ~PCIE_LC_CNTL4__LC_SET_QUIESCE_MASK;
|
||||
@ -1674,16 +1664,15 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
speed_cntl &= ~PCIE_LC_SPEED_CNTL__LC_FORCE_DIS_SW_SPEED_CHANGE_MASK;
|
||||
WREG32_PCIE(ixPCIE_LC_SPEED_CNTL, speed_cntl);
|
||||
|
||||
pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL2, &tmp16);
|
||||
tmp16 &= ~PCI_EXP_LNKCTL2_TLS;
|
||||
|
||||
tmp16 = 0;
|
||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */
|
||||
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */
|
||||
else
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */
|
||||
pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL2, tmp16);
|
||||
pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_TLS, tmp16);
|
||||
|
||||
speed_cntl = RREG32_PCIE(ixPCIE_LC_SPEED_CNTL);
|
||||
speed_cntl |= PCIE_LC_SPEED_CNTL__LC_INITIATE_LINK_SPEED_CHANGE_MASK;
|
||||
|
@ -4490,7 +4490,7 @@ static int gfx_v10_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
||||
static int gfx_v10_0_sw_init(void *handle)
|
||||
{
|
||||
int i, j, k, r, ring_id = 0;
|
||||
struct amdgpu_kiq *kiq;
|
||||
int xcc_id = 0;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
@ -4619,8 +4619,7 @@ static int gfx_v10_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
kiq = &adev->gfx.kiq[0];
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, &kiq->ring, &kiq->irq, 0);
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, xcc_id);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -89,6 +89,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_5_0_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_0_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_0_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_0_rlc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_rlc.bin");
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_11_0[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL, 0x20000000, 0x20000000)
|
||||
@ -907,6 +911,7 @@ static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
|
||||
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
|
||||
@ -1329,7 +1334,7 @@ static int gfx_v11_0_rlc_backdoor_autoload_enable(struct amdgpu_device *adev)
|
||||
static int gfx_v11_0_sw_init(void *handle)
|
||||
{
|
||||
int i, j, k, r, ring_id = 0;
|
||||
struct amdgpu_kiq *kiq;
|
||||
int xcc_id = 0;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
@ -1346,6 +1351,7 @@ static int gfx_v11_0_sw_init(void *handle)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
adev->gfx.me.num_me = 1;
|
||||
adev->gfx.me.num_pipe_per_me = 1;
|
||||
adev->gfx.me.num_queue_per_pipe = 1;
|
||||
@ -1454,8 +1460,7 @@ static int gfx_v11_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
kiq = &adev->gfx.kiq[0];
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, &kiq->ring, &kiq->irq, 0);
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, xcc_id);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
@ -2588,7 +2593,8 @@ static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
|
||||
IP_VERSION(11, 0, 1) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) ==
|
||||
IP_VERSION(11, 0, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 0))
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 0) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 1))
|
||||
bootload_status = RREG32_SOC15(GC, 0,
|
||||
regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1);
|
||||
else
|
||||
@ -5082,6 +5088,7 @@ static void gfx_v11_cntl_power_gating(struct amdgpu_device *adev, bool enable)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
WREG32_SOC15(GC, 0, regRLC_PG_DELAY_3, RLC_PG_DELAY_3_DEFAULT_GC_11_0_1);
|
||||
break;
|
||||
default:
|
||||
@ -5117,6 +5124,7 @@ static int gfx_v11_0_set_powergating_state(void *handle,
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
if (!enable)
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
|
||||
@ -5148,6 +5156,7 @@ static int gfx_v11_0_set_clockgating_state(void *handle,
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
gfx_v11_0_update_gfx_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE);
|
||||
break;
|
||||
|
@ -1900,8 +1900,8 @@ static void gfx_v8_0_sq_irq_work_func(struct work_struct *work);
|
||||
static int gfx_v8_0_sw_init(void *handle)
|
||||
{
|
||||
int i, j, k, r, ring_id;
|
||||
int xcc_id = 0;
|
||||
struct amdgpu_ring *ring;
|
||||
struct amdgpu_kiq *kiq;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
@ -2022,8 +2022,7 @@ static int gfx_v8_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
kiq = &adev->gfx.kiq[0];
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, &kiq->ring, &kiq->irq, 0);
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, xcc_id);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -1997,8 +1997,8 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
||||
static int gfx_v9_0_sw_init(void *handle)
|
||||
{
|
||||
int i, j, k, r, ring_id;
|
||||
int xcc_id = 0;
|
||||
struct amdgpu_ring *ring;
|
||||
struct amdgpu_kiq *kiq;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
unsigned int hw_prio;
|
||||
|
||||
@ -2151,8 +2151,7 @@ static int gfx_v9_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
kiq = &adev->gfx.kiq[0];
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, &kiq->ring, &kiq->irq, 0);
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, xcc_id);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -843,7 +843,6 @@ static int gfx_v9_4_3_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
||||
static int gfx_v9_4_3_sw_init(void *handle)
|
||||
{
|
||||
int i, j, k, r, ring_id, xcc_id, num_xcc;
|
||||
struct amdgpu_kiq *kiq;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.mec.num_mec = 2;
|
||||
@ -912,8 +911,7 @@ static int gfx_v9_4_3_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
kiq = &adev->gfx.kiq[xcc_id];
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, &kiq->ring, &kiq->irq, xcc_id);
|
||||
r = amdgpu_gfx_kiq_init_ring(adev, xcc_id);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -3953,6 +3951,9 @@ static void gfx_v9_4_3_inst_enable_watchdog_timer(struct amdgpu_device *adev,
|
||||
uint32_t i;
|
||||
uint32_t data;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
data = RREG32_SOC15(GC, GET_INST(GC, 0), regSQ_TIMEOUT_CONFIG);
|
||||
data = REG_SET_FIELD(data, SQ_TIMEOUT_CONFIG, TIMEOUT_FATAL_DISABLE,
|
||||
amdgpu_watchdog_timer.timeout_fatal_disable ? 1 : 0);
|
||||
|
@ -587,6 +587,7 @@ static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
||||
adev->gfxhub.funcs = &gfxhub_v3_0_3_funcs;
|
||||
break;
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
adev->gfxhub.funcs = &gfxhub_v11_5_0_funcs;
|
||||
break;
|
||||
default:
|
||||
@ -748,6 +749,7 @@ static int gmc_v11_0_sw_init(void *handle)
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
set_bit(AMDGPU_GFXHUB(0), adev->vmhubs_mask);
|
||||
set_bit(AMDGPU_MMHUB0(0), adev->vmhubs_mask);
|
||||
/*
|
||||
|
@ -496,14 +496,14 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
||||
if (j >= AMDGPU_MMHUB0(0))
|
||||
tmp = RREG32_SOC15_IP(MMHUB, reg);
|
||||
else
|
||||
tmp = RREG32_SOC15_IP(GC, reg);
|
||||
tmp = RREG32_XCC(reg, j);
|
||||
|
||||
tmp &= ~bits;
|
||||
|
||||
if (j >= AMDGPU_MMHUB0(0))
|
||||
WREG32_SOC15_IP(MMHUB, reg, tmp);
|
||||
else
|
||||
WREG32_SOC15_IP(GC, reg, tmp);
|
||||
WREG32_XCC(reg, tmp, j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -524,14 +524,14 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
||||
if (j >= AMDGPU_MMHUB0(0))
|
||||
tmp = RREG32_SOC15_IP(MMHUB, reg);
|
||||
else
|
||||
tmp = RREG32_SOC15_IP(GC, reg);
|
||||
tmp = RREG32_XCC(reg, j);
|
||||
|
||||
tmp |= bits;
|
||||
|
||||
if (j >= AMDGPU_MMHUB0(0))
|
||||
WREG32_SOC15_IP(MMHUB, reg, tmp);
|
||||
else
|
||||
WREG32_SOC15_IP(GC, reg, tmp);
|
||||
WREG32_XCC(reg, tmp, j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -37,6 +37,7 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_4_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_0_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_imu.bin");
|
||||
|
||||
static int imu_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
|
@ -53,6 +53,11 @@ static int jpeg_v4_0_5_set_powergating_state(void *handle,
|
||||
|
||||
static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring);
|
||||
|
||||
static int amdgpu_ih_clientid_jpeg[] = {
|
||||
SOC15_IH_CLIENTID_VCN,
|
||||
SOC15_IH_CLIENTID_VCN1
|
||||
};
|
||||
|
||||
/**
|
||||
* jpeg_v4_0_5_early_init - set function pointers
|
||||
*
|
||||
@ -64,8 +69,20 @@ static int jpeg_v4_0_5_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
switch (amdgpu_ip_version(adev, UVD_HWIP, 0)) {
|
||||
case IP_VERSION(4, 0, 5):
|
||||
adev->jpeg.num_jpeg_inst = 1;
|
||||
break;
|
||||
case IP_VERSION(4, 0, 6):
|
||||
adev->jpeg.num_jpeg_inst = 2;
|
||||
break;
|
||||
default:
|
||||
DRM_DEV_ERROR(adev->dev,
|
||||
"Failed to init vcn ip block(UVD_HWIP:0x%x)\n",
|
||||
amdgpu_ip_version(adev, UVD_HWIP, 0));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
adev->jpeg.num_jpeg_inst = 1;
|
||||
adev->jpeg.num_jpeg_rings = 1;
|
||||
|
||||
jpeg_v4_0_5_set_dec_ring_funcs(adev);
|
||||
@ -85,25 +102,30 @@ static int jpeg_v4_0_5_sw_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring;
|
||||
int r;
|
||||
int r, i;
|
||||
|
||||
/* JPEG TRAP */
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
|
||||
VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
|
||||
if (r)
|
||||
return r;
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
/* JPEG DJPEG POISON EVENT */
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
|
||||
VCN_4_0__SRCID_DJPEG0_POISON, &adev->jpeg.inst->irq);
|
||||
if (r)
|
||||
return r;
|
||||
/* JPEG TRAP */
|
||||
r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
|
||||
VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* JPEG EJPEG POISON EVENT */
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
|
||||
VCN_4_0__SRCID_EJPEG0_POISON, &adev->jpeg.inst->irq);
|
||||
if (r)
|
||||
return r;
|
||||
/* JPEG DJPEG POISON EVENT */
|
||||
r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
|
||||
VCN_4_0__SRCID_DJPEG0_POISON, &adev->jpeg.inst[i].irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* JPEG EJPEG POISON EVENT */
|
||||
r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
|
||||
VCN_4_0__SRCID_EJPEG0_POISON, &adev->jpeg.inst[i].irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_jpeg_sw_init(adev);
|
||||
if (r)
|
||||
@ -113,21 +135,23 @@ static int jpeg_v4_0_5_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ring = adev->jpeg.inst->ring_dec;
|
||||
ring->use_doorbell = true;
|
||||
ring->doorbell_index = amdgpu_sriov_vf(adev) ?
|
||||
(((adev->doorbell_index.vcn.vcn_ring0_1) << 1) + 4) :
|
||||
((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1);
|
||||
ring->vm_hub = AMDGPU_MMHUB0(0);
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
sprintf(ring->name, "jpeg_dec");
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
ring = adev->jpeg.inst[i].ring_dec;
|
||||
ring->use_doorbell = true;
|
||||
ring->vm_hub = AMDGPU_MMHUB0(0);
|
||||
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
|
||||
sprintf(ring->name, "jpeg_dec_%d", i);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
|
||||
0, AMDGPU_RING_PRIO_DEFAULT, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
|
||||
adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH);
|
||||
adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
|
||||
adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, regUVD_JPEG_PITCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -162,8 +186,8 @@ static int jpeg_v4_0_5_sw_fini(void *handle)
|
||||
static int jpeg_v4_0_5_hw_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
|
||||
int r;
|
||||
struct amdgpu_ring *ring;
|
||||
int r, i;
|
||||
|
||||
// TODO: Enable ring test with DPG support
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
|
||||
@ -171,9 +195,15 @@ static int jpeg_v4_0_5_hw_init(void *handle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = amdgpu_ring_test_helper(ring);
|
||||
if (r)
|
||||
return r;
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
ring = adev->jpeg.inst[i].ring_dec;
|
||||
r = amdgpu_ring_test_helper(ring);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!r)
|
||||
DRM_INFO("JPEG decode initialized successfully under SPG Mode\n");
|
||||
@ -191,14 +221,20 @@ static int jpeg_v4_0_5_hw_init(void *handle)
|
||||
static int jpeg_v4_0_5_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i;
|
||||
|
||||
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
|
||||
RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS))
|
||||
jpeg_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
|
||||
RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS))
|
||||
jpeg_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -440,13 +476,17 @@ static void jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
|
||||
*/
|
||||
static int jpeg_v4_0_5_start(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
|
||||
struct amdgpu_ring *ring;
|
||||
int r, i;
|
||||
|
||||
if (adev->pm.dpm_enabled)
|
||||
amdgpu_dpm_enable_jpeg(adev, true);
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
ring = adev->jpeg.inst[i].ring_dec;
|
||||
/* doorbell programming is done for every playback */
|
||||
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
|
||||
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);
|
||||
@ -509,11 +549,14 @@ static int jpeg_v4_0_5_stop(struct amdgpu_device *adev)
|
||||
int r, i;
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
|
||||
jpeg_v4_0_5_stop_dpg_mode(adev, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* reset JMI */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL),
|
||||
UVD_JMI_CNTL__SOFT_RESET_MASK,
|
||||
@ -526,7 +569,6 @@ static int jpeg_v4_0_5_stop(struct amdgpu_device *adev)
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (adev->pm.dpm_enabled)
|
||||
amdgpu_dpm_enable_jpeg(adev, false);
|
||||
|
||||
@ -544,7 +586,7 @@ static uint64_t jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR);
|
||||
return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_RPTR);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -561,7 +603,7 @@ static uint64_t jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
|
||||
if (ring->use_doorbell)
|
||||
return *ring->wptr_cpu_addr;
|
||||
else
|
||||
return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR);
|
||||
return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -579,29 +621,41 @@ static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
|
||||
WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
|
||||
} else {
|
||||
WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
|
||||
WREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
|
||||
}
|
||||
}
|
||||
|
||||
static bool jpeg_v4_0_5_is_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret = 1;
|
||||
int i, ret = 1;
|
||||
|
||||
ret &= (((RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS) &
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
ret &= (((RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS) &
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_5_wait_for_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i;
|
||||
|
||||
return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC_STATUS,
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
return SOC15_WAIT_ON_RREG(JPEG, i, regUVD_JRBC_STATUS,
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
|
||||
UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_5_set_clockgating_state(void *handle,
|
||||
@ -657,11 +711,25 @@ static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
uint32_t ip_instance;
|
||||
|
||||
DRM_DEBUG("IH: JPEG TRAP\n");
|
||||
|
||||
switch (entry->client_id) {
|
||||
case SOC15_IH_CLIENTID_VCN:
|
||||
ip_instance = 0;
|
||||
break;
|
||||
case SOC15_IH_CLIENTID_VCN1:
|
||||
ip_instance = 1;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (entry->src_id) {
|
||||
case VCN_4_0__SRCID__JPEG_DECODE:
|
||||
amdgpu_fence_process(adev->jpeg.inst->ring_dec);
|
||||
amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);
|
||||
break;
|
||||
case VCN_4_0__SRCID_DJPEG0_POISON:
|
||||
case VCN_4_0__SRCID_EJPEG0_POISON:
|
||||
@ -734,6 +802,7 @@ static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
continue;
|
||||
|
||||
adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v4_0_5_dec_ring_vm_funcs;
|
||||
adev->jpeg.inst[i].ring_dec->me = i;
|
||||
DRM_DEV_INFO(adev->dev, "JPEG%d decode is enabled in VM mode\n", i);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_0_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_0_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_mes1.bin");
|
||||
|
||||
|
||||
static int mes_v11_0_hw_fini(void *handle);
|
||||
@ -56,6 +58,7 @@ static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev);
|
||||
static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev);
|
||||
|
||||
#define MES_EOP_SIZE 2048
|
||||
#define GFX_MES_DRAM_SIZE 0x80000
|
||||
|
||||
static void mes_v11_0_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
@ -475,7 +478,13 @@ static int mes_v11_0_allocate_ucode_data_buffer(struct amdgpu_device *adev,
|
||||
le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes));
|
||||
fw_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes);
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, fw_size,
|
||||
if (fw_size > GFX_MES_DRAM_SIZE) {
|
||||
dev_err(adev->dev, "PIPE%d ucode data fw size (%d) is greater than dram size (%d)\n",
|
||||
pipe, fw_size, GFX_MES_DRAM_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, GFX_MES_DRAM_SIZE,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
@ -611,8 +620,8 @@ static int mes_v11_0_load_microcode(struct amdgpu_device *adev,
|
||||
WREG32_SOC15(GC, 0, regCP_MES_MDBASE_HI,
|
||||
upper_32_bits(adev->mes.data_fw_gpu_addr[pipe]));
|
||||
|
||||
/* Set 0x3FFFF (256K-1) to CP_MES_MDBOUND_LO */
|
||||
WREG32_SOC15(GC, 0, regCP_MES_MDBOUND_LO, 0x3FFFF);
|
||||
/* Set 0x7FFFF (512K-1) to CP_MES_MDBOUND_LO */
|
||||
WREG32_SOC15(GC, 0, regCP_MES_MDBOUND_LO, 0x7FFFF);
|
||||
|
||||
if (prime_icache) {
|
||||
/* invalidate ICACHE */
|
||||
|
@ -35,15 +35,6 @@
|
||||
/* Core 0 Port 0 counter */
|
||||
#define smnPCIEP_NAK_COUNTER 0x1A340218
|
||||
|
||||
#define smnPCIE_PERF_CNTL_TXCLK3 0x1A38021c
|
||||
#define smnPCIE_PERF_CNTL_TXCLK7 0x1A380888
|
||||
#define smnPCIE_PERF_COUNT_CNTL 0x1A380200
|
||||
#define smnPCIE_PERF_COUNT0_TXCLK3 0x1A380220
|
||||
#define smnPCIE_PERF_COUNT0_TXCLK7 0x1A38088C
|
||||
#define smnPCIE_PERF_COUNT0_UPVAL_TXCLK3 0x1A3808F8
|
||||
#define smnPCIE_PERF_COUNT0_UPVAL_TXCLK7 0x1A380918
|
||||
|
||||
|
||||
static void nbio_v7_9_remap_hdp_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL,
|
||||
@ -484,59 +475,6 @@ static u64 nbio_v7_9_get_pcie_replay_count(struct amdgpu_device *adev)
|
||||
return (nak_r + nak_g);
|
||||
}
|
||||
|
||||
static void nbio_v7_9_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0,
|
||||
uint64_t *count1)
|
||||
{
|
||||
uint32_t perfctrrx = 0;
|
||||
uint32_t perfctrtx = 0;
|
||||
|
||||
/* This reports 0 on APUs, so return to avoid writing/reading registers
|
||||
* that may or may not be different from their GPU counterparts
|
||||
*/
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return;
|
||||
|
||||
/* Use TXCLK3 counter group for rx event */
|
||||
/* Use TXCLK7 counter group for tx event */
|
||||
/* Set the 2 events that we wish to watch, defined above */
|
||||
/* 40 is event# for received msgs */
|
||||
/* 2 is event# of posted requests sent */
|
||||
perfctrrx = REG_SET_FIELD(perfctrrx, PCIE_PERF_CNTL_TXCLK3, EVENT0_SEL, 40);
|
||||
perfctrtx = REG_SET_FIELD(perfctrtx, PCIE_PERF_CNTL_TXCLK7, EVENT0_SEL, 2);
|
||||
|
||||
/* Write to enable desired perf counters */
|
||||
WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3, perfctrrx);
|
||||
WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK7, perfctrtx);
|
||||
|
||||
/* Zero out and enable SHADOW_WR
|
||||
* Write 0x6:
|
||||
* Bit 1 = Global Shadow wr(1)
|
||||
* Bit 2 = Global counter reset enable(1)
|
||||
*/
|
||||
WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000006);
|
||||
|
||||
/* Enable Gloabl Counter
|
||||
* Write 0x1:
|
||||
* Bit 0 = Global Counter Enable(1)
|
||||
*/
|
||||
WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000001);
|
||||
|
||||
msleep(1000);
|
||||
|
||||
/* Disable Global Counter, Reset and enable SHADOW_WR
|
||||
* Write 0x6:
|
||||
* Bit 1 = Global Shadow wr(1)
|
||||
* Bit 2 = Global counter reset enable(1)
|
||||
*/
|
||||
WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000006);
|
||||
|
||||
/* Get the upper and lower count */
|
||||
*count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK3) |
|
||||
((uint64_t)RREG32_PCIE(smnPCIE_PERF_COUNT0_UPVAL_TXCLK3) << 32);
|
||||
*count1 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK7) |
|
||||
((uint64_t)RREG32_PCIE(smnPCIE_PERF_COUNT0_UPVAL_TXCLK7) << 32);
|
||||
}
|
||||
|
||||
const struct amdgpu_nbio_funcs nbio_v7_9_funcs = {
|
||||
.get_hdp_flush_req_offset = nbio_v7_9_get_hdp_flush_req_offset,
|
||||
.get_hdp_flush_done_offset = nbio_v7_9_get_hdp_flush_done_offset,
|
||||
@ -561,7 +499,6 @@ const struct amdgpu_nbio_funcs nbio_v7_9_funcs = {
|
||||
.get_memory_partition_mode = nbio_v7_9_get_memory_partition_mode,
|
||||
.init_registers = nbio_v7_9_init_registers,
|
||||
.get_pcie_replay_count = nbio_v7_9_get_pcie_replay_count,
|
||||
.get_pcie_usage = nbio_v7_9_get_pcie_usage,
|
||||
};
|
||||
|
||||
static void nbio_v7_9_query_ras_error_count(struct amdgpu_device *adev,
|
||||
|
@ -2331,28 +2331,18 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
gpu_cfg &
|
||||
PCI_EXP_LNKCTL_HAWD);
|
||||
|
||||
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (bridge_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(root,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
|
||||
pcie_capability_read_word(adev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (gpu_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(adev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
bridge_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
gpu_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
|
||||
tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
|
||||
tmp &= ~LC_SET_QUIESCE;
|
||||
@ -2365,16 +2355,15 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
|
||||
speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
|
||||
WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
|
||||
|
||||
pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL2, &tmp16);
|
||||
tmp16 &= ~PCI_EXP_LNKCTL2_TLS;
|
||||
|
||||
tmp16 = 0;
|
||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */
|
||||
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */
|
||||
else
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */
|
||||
pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL2, tmp16);
|
||||
pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_TLS, tmp16);
|
||||
|
||||
speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
|
||||
speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
|
||||
|
@ -574,11 +574,34 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
|
||||
return AMD_RESET_METHOD_MODE1;
|
||||
}
|
||||
|
||||
static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 sol_reg;
|
||||
|
||||
sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
|
||||
/* Will reset for the following suspend abort cases.
|
||||
* 1) Only reset limit on APU side, dGPU hasn't checked yet.
|
||||
* 2) S3 suspend abort and TOS already launched.
|
||||
*/
|
||||
if (adev->flags & AMD_IS_APU && adev->in_s3 &&
|
||||
!adev->suspend_complete &&
|
||||
sol_reg)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int soc15_asic_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
/* original raven doesn't have full asic reset */
|
||||
if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
|
||||
(adev->apu_flags & AMD_APU_IS_RAVEN2))
|
||||
/* On the latest Raven, the GPU reset can be performed
|
||||
* successfully. So now, temporarily enable it for the
|
||||
* S3 suspend abort case.
|
||||
*/
|
||||
if (((adev->apu_flags & AMD_APU_IS_RAVEN) ||
|
||||
(adev->apu_flags & AMD_APU_IS_RAVEN2)) &&
|
||||
!soc15_need_reset_on_resume(adev))
|
||||
return 0;
|
||||
|
||||
switch (soc15_asic_reset_method(adev)) {
|
||||
@ -895,7 +918,6 @@ static const struct amdgpu_asic_funcs aqua_vanjaram_asic_funcs =
|
||||
.get_config_memsize = &soc15_get_config_memsize,
|
||||
.need_full_reset = &soc15_need_full_reset,
|
||||
.init_doorbell_index = &aqua_vanjaram_doorbell_index_init,
|
||||
.get_pcie_usage = &amdgpu_nbio_get_pcie_usage,
|
||||
.need_reset_on_init = &soc15_need_reset_on_init,
|
||||
.get_pcie_replay_count = &amdgpu_nbio_get_pcie_replay_count,
|
||||
.supports_baco = &soc15_supports_baco,
|
||||
@ -1278,7 +1300,8 @@ static int soc15_common_hw_fini(void *handle)
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
xgpu_ai_mailbox_put_irq(adev);
|
||||
|
||||
if (adev->nbio.ras_if &&
|
||||
if ((!amdgpu_sriov_vf(adev)) &&
|
||||
adev->nbio.ras_if &&
|
||||
amdgpu_ras_is_supported(adev, adev->nbio.ras_if->block)) {
|
||||
if (adev->nbio.ras &&
|
||||
adev->nbio.ras->init_ras_controller_interrupt)
|
||||
@ -1298,24 +1321,6 @@ static int soc15_common_suspend(void *handle)
|
||||
return soc15_common_hw_fini(adev);
|
||||
}
|
||||
|
||||
static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 sol_reg;
|
||||
|
||||
sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
|
||||
/* Will reset for the following suspend abort cases.
|
||||
* 1) Only reset limit on APU side, dGPU hasn't checked yet.
|
||||
* 2) S3 suspend abort and TOS already launched.
|
||||
*/
|
||||
if (adev->flags & AMD_IS_APU && adev->in_s3 &&
|
||||
!adev->suspend_complete &&
|
||||
sol_reg)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int soc15_common_resume(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
@ -185,6 +185,12 @@ static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case IP_VERSION(4, 0, 6):
|
||||
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;
|
||||
}
|
||||
@ -717,6 +723,35 @@ static int soc21_common_early_init(void *handle)
|
||||
AMD_PG_SUPPORT_GFX_PG;
|
||||
adev->external_rev_id = adev->rev_id + 0x1;
|
||||
break;
|
||||
case IP_VERSION(11, 5, 1):
|
||||
adev->cg_flags =
|
||||
AMD_CG_SUPPORT_GFX_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_CGLS |
|
||||
AMD_CG_SUPPORT_GFX_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_FGCG |
|
||||
AMD_CG_SUPPORT_REPEATER_FGCG |
|
||||
AMD_CG_SUPPORT_GFX_PERF_CLK |
|
||||
AMD_CG_SUPPORT_GFX_3D_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_3D_CGLS |
|
||||
AMD_CG_SUPPORT_MC_MGCG |
|
||||
AMD_CG_SUPPORT_MC_LS |
|
||||
AMD_CG_SUPPORT_HDP_LS |
|
||||
AMD_CG_SUPPORT_HDP_DS |
|
||||
AMD_CG_SUPPORT_HDP_SD |
|
||||
AMD_CG_SUPPORT_ATHUB_MGCG |
|
||||
AMD_CG_SUPPORT_ATHUB_LS |
|
||||
AMD_CG_SUPPORT_IH_CG |
|
||||
AMD_CG_SUPPORT_BIF_MGCG |
|
||||
AMD_CG_SUPPORT_BIF_LS |
|
||||
AMD_CG_SUPPORT_VCN_MGCG |
|
||||
AMD_CG_SUPPORT_JPEG_MGCG;
|
||||
adev->pg_flags =
|
||||
AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
adev->external_rev_id = adev->rev_id + 0xc1;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
return -EINVAL;
|
||||
|
@ -348,7 +348,8 @@ static int umc_v12_0_query_error_address(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
/* calculate error address if ue error is detected */
|
||||
if (umc_v12_0_is_uncorrectable_error(adev, mc_umc_status)) {
|
||||
if (umc_v12_0_is_uncorrectable_error(adev, mc_umc_status) ||
|
||||
umc_v12_0_is_deferred_error(adev, mc_umc_status)) {
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
|
||||
|
@ -1684,6 +1684,9 @@ static int vcn_v4_0_5_process_interrupt(struct amdgpu_device *adev, struct amdgp
|
||||
case SOC15_IH_CLIENTID_VCN:
|
||||
ip_instance = 0;
|
||||
break;
|
||||
case SOC15_IH_CLIENTID_VCN1:
|
||||
ip_instance = 1;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
|
||||
return 0;
|
||||
|
@ -291,27 +291,29 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
|
||||
|
||||
adev->nbio.funcs->ih_control(adev);
|
||||
|
||||
if ((amdgpu_ip_version(adev, OSSSYS_HWIP, 0) == IP_VERSION(4, 2, 1)) &&
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
|
||||
MC_SPACE_GPA_ENABLE, 1);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if ((amdgpu_ip_version(adev, OSSSYS_HWIP, 0) == IP_VERSION(4, 2, 1)) &&
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
|
||||
MC_SPACE_GPA_ENABLE, 1);
|
||||
}
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken);
|
||||
}
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken);
|
||||
}
|
||||
|
||||
/* 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 ((amdgpu_ip_version(adev, OSSSYS_HWIP, 0) == IP_VERSION(4, 4, 0)) ||
|
||||
(amdgpu_ip_version(adev, 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,
|
||||
MC_SPACE_GPA_ENABLE, 1);
|
||||
/* 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 ((amdgpu_ip_version(adev, OSSSYS_HWIP, 0) == IP_VERSION(4, 4, 0)) ||
|
||||
(amdgpu_ip_version(adev, 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,
|
||||
MC_SPACE_GPA_ENABLE, 1);
|
||||
}
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_ALDEBARAN, ih_chicken);
|
||||
}
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_ALDEBARAN, ih_chicken);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ih); i++) {
|
||||
|
@ -371,7 +371,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
||||
goto err_wptr_map_gart;
|
||||
}
|
||||
|
||||
err = amdgpu_amdkfd_map_gtt_bo_to_gart(dev->adev, wptr_bo);
|
||||
err = amdgpu_amdkfd_map_gtt_bo_to_gart(wptr_bo);
|
||||
if (err) {
|
||||
pr_err("Failed to map wptr bo to GART\n");
|
||||
goto err_wptr_map_gart;
|
||||
@ -2935,6 +2935,7 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v
|
||||
if (IS_ERR_OR_NULL(target)) {
|
||||
pr_debug("Cannot find process PID %i to debug\n", args->pid);
|
||||
r = target ? PTR_ERR(target) : -ESRCH;
|
||||
target = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1676,6 +1676,7 @@ int kfd_get_gpu_cache_info(struct kfd_node *kdev, struct kfd_gpu_cache_info **pc
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
num_of_cache_types =
|
||||
kfd_fill_gpu_cache_info_from_gfx_config(kdev->kfd, *pcache_info);
|
||||
break;
|
||||
|
@ -96,6 +96,7 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
|
||||
case IP_VERSION(6, 0, 2):
|
||||
case IP_VERSION(6, 0, 3):
|
||||
case IP_VERSION(6, 1, 0):
|
||||
case IP_VERSION(6, 1, 1):
|
||||
kfd->device_info.num_sdma_queues_per_engine = 8;
|
||||
break;
|
||||
default:
|
||||
@ -113,6 +114,7 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
|
||||
case IP_VERSION(6, 0, 2):
|
||||
case IP_VERSION(6, 0, 3):
|
||||
case IP_VERSION(6, 1, 0):
|
||||
case IP_VERSION(6, 1, 1):
|
||||
/* Reserve 1 for paging and 1 for gfx */
|
||||
kfd->device_info.num_reserved_sdma_queues_per_engine = 2;
|
||||
/* BIT(0)=engine-0 queue-0; BIT(1)=engine-1 queue-0; BIT(2)=engine-0 queue-1; ... */
|
||||
@ -165,6 +167,7 @@ static void kfd_device_info_set_event_interrupt_class(struct kfd_dev *kfd)
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
kfd->device_info.event_interrupt_class = &event_interrupt_class_v11;
|
||||
break;
|
||||
default:
|
||||
@ -420,6 +423,10 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
|
||||
gfx_target_version = 110500;
|
||||
f2g = &gfx_v11_kfd2kgd;
|
||||
break;
|
||||
case IP_VERSION(11, 5, 1):
|
||||
gfx_target_version = 110501;
|
||||
f2g = &gfx_v11_kfd2kgd;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1903,6 +1903,10 @@ int amdkfd_fence_wait_timeout(struct device_queue_manager *dqm,
|
||||
uint64_t *fence_addr = dqm->fence_addr;
|
||||
|
||||
while (*fence_addr != fence_value) {
|
||||
/* Fatal err detected, this response won't come */
|
||||
if (amdgpu_amdkfd_is_fed(dqm->dev->adev))
|
||||
return -EIO;
|
||||
|
||||
if (time_after(jiffies, end_jiffies)) {
|
||||
dev_err(dev, "qcm fence wait loop timeout expired\n");
|
||||
/* In HWS case, this is used to halt the driver thread
|
||||
|
@ -286,7 +286,7 @@ err_no_space:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void kq_submit_packet(struct kernel_queue *kq)
|
||||
int kq_submit_packet(struct kernel_queue *kq)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
@ -298,6 +298,10 @@ void kq_submit_packet(struct kernel_queue *kq)
|
||||
}
|
||||
pr_debug("\n");
|
||||
#endif
|
||||
/* Fatal err detected, packet submission won't go through */
|
||||
if (amdgpu_amdkfd_is_fed(kq->dev->adev))
|
||||
return -EIO;
|
||||
|
||||
if (kq->dev->kfd->device_info.doorbell_size == 8) {
|
||||
*kq->wptr64_kernel = kq->pending_wptr64;
|
||||
write_kernel_doorbell64(kq->queue->properties.doorbell_ptr,
|
||||
@ -307,6 +311,8 @@ void kq_submit_packet(struct kernel_queue *kq)
|
||||
write_kernel_doorbell(kq->queue->properties.doorbell_ptr,
|
||||
kq->pending_wptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kq_rollback_packet(struct kernel_queue *kq)
|
||||
|
@ -47,7 +47,7 @@
|
||||
int kq_acquire_packet_buffer(struct kernel_queue *kq,
|
||||
size_t packet_size_in_dwords,
|
||||
unsigned int **buffer_ptr);
|
||||
void kq_submit_packet(struct kernel_queue *kq);
|
||||
int kq_submit_packet(struct kernel_queue *kq);
|
||||
void kq_rollback_packet(struct kernel_queue *kq);
|
||||
|
||||
|
||||
|
@ -288,7 +288,7 @@ int pm_send_set_resources(struct packet_manager *pm,
|
||||
|
||||
retval = pm->pmf->set_resources(pm, buffer, res);
|
||||
if (!retval)
|
||||
kq_submit_packet(pm->priv_queue);
|
||||
retval = kq_submit_packet(pm->priv_queue);
|
||||
else
|
||||
kq_rollback_packet(pm->priv_queue);
|
||||
|
||||
@ -325,7 +325,7 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
|
||||
if (retval)
|
||||
goto fail_create_runlist;
|
||||
|
||||
kq_submit_packet(pm->priv_queue);
|
||||
retval = kq_submit_packet(pm->priv_queue);
|
||||
|
||||
mutex_unlock(&pm->lock);
|
||||
|
||||
@ -361,7 +361,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
|
||||
|
||||
retval = pm->pmf->query_status(pm, buffer, fence_address, fence_value);
|
||||
if (!retval)
|
||||
kq_submit_packet(pm->priv_queue);
|
||||
retval = kq_submit_packet(pm->priv_queue);
|
||||
else
|
||||
kq_rollback_packet(pm->priv_queue);
|
||||
|
||||
@ -392,7 +392,7 @@ int pm_update_grace_period(struct packet_manager *pm, uint32_t grace_period)
|
||||
|
||||
retval = pm->pmf->set_grace_period(pm, buffer, grace_period);
|
||||
if (!retval)
|
||||
kq_submit_packet(pm->priv_queue);
|
||||
retval = kq_submit_packet(pm->priv_queue);
|
||||
else
|
||||
kq_rollback_packet(pm->priv_queue);
|
||||
}
|
||||
@ -421,7 +421,7 @@ int pm_send_unmap_queue(struct packet_manager *pm,
|
||||
|
||||
retval = pm->pmf->unmap_queues(pm, buffer, filter, filter_param, reset);
|
||||
if (!retval)
|
||||
kq_submit_packet(pm->priv_queue);
|
||||
retval = kq_submit_packet(pm->priv_queue);
|
||||
else
|
||||
kq_rollback_packet(pm->priv_queue);
|
||||
|
||||
|
@ -1997,8 +1997,9 @@ int kfd_topology_add_device(struct kfd_node *gpu)
|
||||
HSA_CAP_ASIC_REVISION_MASK);
|
||||
|
||||
dev->node_props.location_id = pci_dev_id(gpu->adev->pdev);
|
||||
if (KFD_GC_VERSION(dev->gpu->kfd) == IP_VERSION(9, 4, 3))
|
||||
dev->node_props.location_id |= dev->gpu->node_id;
|
||||
/* On multi-partition nodes, node id = location_id[31:28] */
|
||||
if (gpu->kfd->num_nodes > 1)
|
||||
dev->node_props.location_id |= (dev->gpu->node_id << 28);
|
||||
|
||||
dev->node_props.domain = pci_domain_nr(gpu->adev->pdev->bus);
|
||||
dev->node_props.max_engine_clk_fcompute =
|
||||
|
@ -5235,6 +5235,10 @@ static inline void fill_dc_dirty_rect(struct drm_plane *plane,
|
||||
* @new_plane_state: New state of @plane
|
||||
* @crtc_state: New state of CRTC connected to the @plane
|
||||
* @flip_addrs: DC flip tracking struct, which also tracts dirty rects
|
||||
* @is_psr_su: Flag indicating whether Panel Self Refresh Selective Update (PSR SU) is enabled.
|
||||
* If PSR SU is enabled and damage clips are available, only the regions of the screen
|
||||
* that have changed will be updated. If PSR SU is not enabled,
|
||||
* or if damage clips are not available, the entire screen will be updated.
|
||||
* @dirty_regions_changed: dirty regions changed
|
||||
*
|
||||
* For PSR SU, DC informs the DMUB uController of dirty rectangle regions
|
||||
@ -6229,7 +6233,8 @@ create_stream_for_sink(struct drm_connector *connector,
|
||||
*/
|
||||
DRM_DEBUG_DRIVER("No preferred mode found\n");
|
||||
} else if (aconnector) {
|
||||
recalculate_timing = is_freesync_video_mode(&mode, aconnector);
|
||||
recalculate_timing = amdgpu_freesync_vid_mode &&
|
||||
is_freesync_video_mode(&mode, aconnector);
|
||||
if (recalculate_timing) {
|
||||
freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
|
||||
drm_mode_copy(&saved_mode, &mode);
|
||||
@ -6389,9 +6394,6 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector,
|
||||
} else if (property == adev->mode_info.underscan_property) {
|
||||
dm_new_state->underscan_enable = val;
|
||||
ret = 0;
|
||||
} else if (property == adev->mode_info.abm_level_property) {
|
||||
dm_new_state->abm_level = val ?: ABM_LEVEL_IMMEDIATE_DISABLE;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -6434,10 +6436,6 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector,
|
||||
} else if (property == adev->mode_info.underscan_property) {
|
||||
*val = dm_state->underscan_enable;
|
||||
ret = 0;
|
||||
} else if (property == adev->mode_info.abm_level_property) {
|
||||
*val = (dm_state->abm_level != ABM_LEVEL_IMMEDIATE_DISABLE) ?
|
||||
dm_state->abm_level : 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -6656,7 +6654,7 @@ static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector)
|
||||
struct edid *edid;
|
||||
struct i2c_adapter *ddc;
|
||||
|
||||
if (dc_link->aux_mode)
|
||||
if (dc_link && dc_link->aux_mode)
|
||||
ddc = &aconnector->dm_dp_aux.aux.ddc;
|
||||
else
|
||||
ddc = &aconnector->i2c->base;
|
||||
@ -7547,7 +7545,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect
|
||||
struct amdgpu_dm_connector *amdgpu_dm_connector =
|
||||
to_amdgpu_dm_connector(connector);
|
||||
|
||||
if (!edid)
|
||||
if (!(amdgpu_freesync_vid_mode && edid))
|
||||
return;
|
||||
|
||||
if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
|
||||
@ -7664,13 +7662,6 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
|
||||
aconnector->base.state->max_bpc = 16;
|
||||
aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc;
|
||||
|
||||
if (connector_type == DRM_MODE_CONNECTOR_eDP &&
|
||||
(dc_is_dmcu_initialized(adev->dm.dc) ||
|
||||
adev->dm.dc->ctx->dmub_srv) && amdgpu_dm_abm_level < 0) {
|
||||
drm_object_attach_property(&aconnector->base.base,
|
||||
adev->mode_info.abm_level_property, 0);
|
||||
}
|
||||
|
||||
if (connector_type == DRM_MODE_CONNECTOR_HDMIA) {
|
||||
/* Content Type is currently only implemented for HDMI. */
|
||||
drm_connector_attach_content_type_property(&aconnector->base);
|
||||
@ -9847,7 +9838,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
||||
* TODO: Refactor this function to allow this check to work
|
||||
* in all conditions.
|
||||
*/
|
||||
if (dm_new_crtc_state->stream &&
|
||||
if (amdgpu_freesync_vid_mode &&
|
||||
dm_new_crtc_state->stream &&
|
||||
is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state))
|
||||
goto skip_modeset;
|
||||
|
||||
@ -9887,7 +9879,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
||||
}
|
||||
|
||||
/* Now check if we should set freesync video mode */
|
||||
if (dm_new_crtc_state->stream &&
|
||||
if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream &&
|
||||
dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
|
||||
dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream) &&
|
||||
is_timing_unchanged_for_freesync(new_crtc_state,
|
||||
@ -9900,7 +9892,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
||||
set_freesync_fixed_config(dm_new_crtc_state);
|
||||
|
||||
goto skip_modeset;
|
||||
} else if (aconnector &&
|
||||
} else if (amdgpu_freesync_vid_mode && aconnector &&
|
||||
is_freesync_video_mode(&new_crtc_state->mode,
|
||||
aconnector)) {
|
||||
struct drm_display_mode *high_mode;
|
||||
|
@ -23,8 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "resource.h"
|
||||
#include "dm_services.h"
|
||||
#include "dce_calcs.h"
|
||||
|
@ -23,8 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dal_asic_id.h"
|
||||
#include "dc_types.h"
|
||||
#include "dccg.h"
|
||||
|
@ -132,7 +132,7 @@ int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
|
||||
int dprefclk_wdivider;
|
||||
int dprefclk_src_sel;
|
||||
int dp_ref_clk_khz;
|
||||
int target_div;
|
||||
int target_div = 600000;
|
||||
|
||||
/* ASSERT DP Reference Clock source is from DFS*/
|
||||
REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel);
|
||||
|
@ -23,8 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "core_types.h"
|
||||
#include "clk_mgr_internal.h"
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-16 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "clk_mgr_internal.h"
|
||||
#include "rv1_clk_mgr_clk.h"
|
||||
|
||||
#include "ip/Discovery/hwid.h"
|
||||
#include "ip/Discovery/v1/ip_offset_1.h"
|
||||
#include "ip/CLK/clk_10_0_default.h"
|
||||
#include "ip/CLK/clk_10_0_offset.h"
|
||||
#include "ip/CLK/clk_10_0_reg.h"
|
||||
#include "ip/CLK/clk_10_0_sh_mask.h"
|
||||
|
||||
#include "dce100/dce_clk_mgr.h"
|
||||
|
||||
#define CLK_BASE_INNER(inst) \
|
||||
CLK_BASE__INST ## inst ## _SEG0
|
||||
|
||||
|
||||
#define CLK_REG(reg_name, block, inst)\
|
||||
CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## _ ## inst ## _ ## reg_name
|
||||
|
||||
#define REG(reg_name) \
|
||||
CLK_REG(reg_name, CLK0, 0)
|
||||
|
||||
|
||||
/* Only used by testing framework*/
|
||||
void rv1_dump_clk_registers(struct clk_state_registers *regs, struct clk_bypass *bypass, struct clk_mgr *clk_mgr_base)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
|
||||
regs->CLK0_CLK8_CURRENT_CNT = REG_READ(CLK0_CLK8_CURRENT_CNT) / 10; //dcf clk
|
||||
|
||||
bypass->dcfclk_bypass = REG_READ(CLK0_CLK8_BYPASS_CNTL) & 0x0007;
|
||||
if (bypass->dcfclk_bypass < 0 || bypass->dcfclk_bypass > 4)
|
||||
bypass->dcfclk_bypass = 0;
|
||||
|
||||
|
||||
regs->CLK0_CLK8_DS_CNTL = REG_READ(CLK0_CLK8_DS_CNTL) / 10; //dcf deep sleep divider
|
||||
|
||||
regs->CLK0_CLK8_ALLOW_DS = REG_READ(CLK0_CLK8_ALLOW_DS); //dcf deep sleep allow
|
||||
|
||||
regs->CLK0_CLK10_CURRENT_CNT = REG_READ(CLK0_CLK10_CURRENT_CNT) / 10; //dpref clk
|
||||
|
||||
bypass->dispclk_pypass = REG_READ(CLK0_CLK10_BYPASS_CNTL) & 0x0007;
|
||||
if (bypass->dispclk_pypass < 0 || bypass->dispclk_pypass > 4)
|
||||
bypass->dispclk_pypass = 0;
|
||||
|
||||
regs->CLK0_CLK11_CURRENT_CNT = REG_READ(CLK0_CLK11_CURRENT_CNT) / 10; //disp clk
|
||||
|
||||
bypass->dprefclk_bypass = REG_READ(CLK0_CLK11_BYPASS_CNTL) & 0x0007;
|
||||
if (bypass->dprefclk_bypass < 0 || bypass->dprefclk_bypass > 4)
|
||||
bypass->dprefclk_bypass = 0;
|
||||
|
||||
}
|
@ -26,6 +26,10 @@
|
||||
#include "core_types.h"
|
||||
#include "clk_mgr_internal.h"
|
||||
#include "reg_helper.h"
|
||||
#include "dm_helpers.h"
|
||||
|
||||
#include "rn_clk_mgr_vbios_smu.h"
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "renoir_ip_offset.h"
|
||||
@ -33,8 +37,6 @@
|
||||
#include "mp/mp_12_0_0_offset.h"
|
||||
#include "mp/mp_12_0_0_sh_mask.h"
|
||||
|
||||
#include "rn_clk_mgr_vbios_smu.h"
|
||||
|
||||
#define REG(reg_name) \
|
||||
(MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
|
||||
|
||||
@ -120,7 +122,10 @@ static int rn_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr,
|
||||
|
||||
result = rn_smu_wait_for_response(clk_mgr, 10, 200000);
|
||||
|
||||
ASSERT(result == VBIOSSMC_Result_OK || result == VBIOSSMC_Result_UnknownCmd);
|
||||
if (IS_SMU_TIMEOUT(result)) {
|
||||
ASSERT(0);
|
||||
dm_helpers_smu_timeout(CTX, msg_id, param, 10 * 200000);
|
||||
}
|
||||
|
||||
/* Actual dispclk set is returned in the parameter register */
|
||||
return REG_READ(MP1_SMN_C2PMSG_83);
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "dcn301_smu.h"
|
||||
#include "dm_helpers.h"
|
||||
|
||||
#include "vangogh_ip_offset.h"
|
||||
|
||||
@ -120,7 +121,10 @@ static int dcn301_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr,
|
||||
|
||||
result = dcn301_smu_wait_for_response(clk_mgr, 10, 200000);
|
||||
|
||||
ASSERT(result == VBIOSSMC_Result_OK);
|
||||
if (IS_SMU_TIMEOUT(result)) {
|
||||
ASSERT(0);
|
||||
dm_helpers_smu_timeout(CTX, msg_id, param, 10 * 200000);
|
||||
}
|
||||
|
||||
/* Actual dispclk set is returned in the parameter register */
|
||||
return REG_READ(MP1_SMN_C2PMSG_83);
|
||||
|
@ -243,10 +243,8 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
|
||||
/* Get UCLK, update bounding box */
|
||||
clk_mgr_base->funcs->get_memclk_states_from_smu(clk_mgr_base);
|
||||
|
||||
DC_FP_START();
|
||||
/* WM range table */
|
||||
dcn32_build_wm_range_table(clk_mgr);
|
||||
DC_FP_END();
|
||||
}
|
||||
|
||||
static void dcn32_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr,
|
||||
@ -817,7 +815,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
dmcu->funcs->set_psr_wait_loop(dmcu,
|
||||
clk_mgr_base->clks.dispclk_khz / 1000 / 7);
|
||||
|
||||
if (dc->config.enable_auto_dpm_test_logs) {
|
||||
if (dc->config.enable_auto_dpm_test_logs && safe_to_lower) {
|
||||
dcn32_auto_dpm_test_log(new_clocks, clk_mgr, context);
|
||||
}
|
||||
}
|
||||
|
@ -2032,7 +2032,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool commit_minimal_transition_state(struct dc *dc,
|
||||
static bool commit_minimal_transition_state_legacy(struct dc *dc,
|
||||
struct dc_state *transition_base_context);
|
||||
|
||||
/**
|
||||
@ -2098,7 +2098,7 @@ enum dc_status dc_commit_streams(struct dc *dc,
|
||||
}
|
||||
|
||||
if (handle_exit_odm2to1)
|
||||
res = commit_minimal_transition_state(dc, dc->current_state);
|
||||
res = commit_minimal_transition_state_legacy(dc, dc->current_state);
|
||||
|
||||
context = dc_state_create_current_copy(dc);
|
||||
if (!context)
|
||||
@ -2952,8 +2952,8 @@ static void copy_stream_update_to_stream(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
static void backup_plane_states_for_stream(
|
||||
struct dc_plane_state plane_states[MAX_SURFACE_NUM],
|
||||
static void backup_planes_and_stream_state(
|
||||
struct dc_scratch_space *scratch,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
int i;
|
||||
@ -2962,12 +2962,20 @@ static void backup_plane_states_for_stream(
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
for (i = 0; i < status->plane_count; i++)
|
||||
plane_states[i] = *status->plane_states[i];
|
||||
for (i = 0; i < status->plane_count; i++) {
|
||||
scratch->plane_states[i] = *status->plane_states[i];
|
||||
scratch->gamma_correction[i] = *status->plane_states[i]->gamma_correction;
|
||||
scratch->in_transfer_func[i] = *status->plane_states[i]->in_transfer_func;
|
||||
scratch->lut3d_func[i] = *status->plane_states[i]->lut3d_func;
|
||||
scratch->in_shaper_func[i] = *status->plane_states[i]->in_shaper_func;
|
||||
scratch->blend_tf[i] = *status->plane_states[i]->blend_tf;
|
||||
}
|
||||
scratch->stream_state = *stream;
|
||||
scratch->out_transfer_func = *stream->out_transfer_func;
|
||||
}
|
||||
|
||||
static void restore_plane_states_for_stream(
|
||||
struct dc_plane_state plane_states[MAX_SURFACE_NUM],
|
||||
static void restore_planes_and_stream_state(
|
||||
struct dc_scratch_space *scratch,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
int i;
|
||||
@ -2976,8 +2984,16 @@ static void restore_plane_states_for_stream(
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
for (i = 0; i < status->plane_count; i++)
|
||||
*status->plane_states[i] = plane_states[i];
|
||||
for (i = 0; i < status->plane_count; i++) {
|
||||
*status->plane_states[i] = scratch->plane_states[i];
|
||||
*status->plane_states[i]->gamma_correction = scratch->gamma_correction[i];
|
||||
*status->plane_states[i]->in_transfer_func = scratch->in_transfer_func[i];
|
||||
*status->plane_states[i]->lut3d_func = scratch->lut3d_func[i];
|
||||
*status->plane_states[i]->in_shaper_func = scratch->in_shaper_func[i];
|
||||
*status->plane_states[i]->blend_tf = scratch->blend_tf[i];
|
||||
}
|
||||
*stream = scratch->stream_state;
|
||||
*stream->out_transfer_func = scratch->out_transfer_func;
|
||||
}
|
||||
|
||||
static bool update_planes_and_stream_state(struct dc *dc,
|
||||
@ -3003,7 +3019,7 @@ static bool update_planes_and_stream_state(struct dc *dc,
|
||||
}
|
||||
|
||||
context = dc->current_state;
|
||||
backup_plane_states_for_stream(dc->current_state->scratch.plane_states, stream);
|
||||
backup_planes_and_stream_state(&dc->current_state->scratch, stream);
|
||||
update_type = dc_check_update_surfaces_for_stream(
|
||||
dc, srf_updates, surface_count, stream_update, stream_status);
|
||||
|
||||
@ -3103,7 +3119,7 @@ static bool update_planes_and_stream_state(struct dc *dc,
|
||||
|
||||
*new_context = context;
|
||||
*new_update_type = update_type;
|
||||
backup_plane_states_for_stream(context->scratch.plane_states, stream);
|
||||
backup_planes_and_stream_state(&context->scratch, stream);
|
||||
|
||||
return true;
|
||||
|
||||
@ -4047,7 +4063,23 @@ static struct dc_state *create_minimal_transition_state(struct dc *dc,
|
||||
return minimal_transition_context;
|
||||
}
|
||||
|
||||
static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
|
||||
/**
|
||||
* commit_minimal_transition_state - Commit a minimal state based on current or new context
|
||||
*
|
||||
* @dc: DC structure, used to get the current state
|
||||
* @context: New context
|
||||
* @stream: Stream getting the update for the flip
|
||||
*
|
||||
* The function takes in current state and new state and determine a minimal transition state
|
||||
* as the intermediate step which could make the transition between current and new states
|
||||
* seamless. If found, it will commit the minimal transition state and update current state to
|
||||
* this minimal transition state and return true, if not, it will return false.
|
||||
*
|
||||
* Return:
|
||||
* Return True if the minimal transition succeeded, false otherwise
|
||||
*/
|
||||
static bool commit_minimal_transition_state(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
@ -4056,12 +4088,6 @@ static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
struct pipe_split_policy_backup policy;
|
||||
|
||||
/* commit based on new context */
|
||||
/* Since all phantom pipes are removed in full validation,
|
||||
* we have to save and restore the subvp/mall config when
|
||||
* we do a minimal transition since the flags marking the
|
||||
* pipe as subvp/phantom will be cleared (dc copy constructor
|
||||
* creates a shallow copy).
|
||||
*/
|
||||
minimal_transition_context = create_minimal_transition_state(dc,
|
||||
context, &policy);
|
||||
if (minimal_transition_context) {
|
||||
@ -4078,7 +4104,7 @@ static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
|
||||
if (!success) {
|
||||
/* commit based on current context */
|
||||
restore_plane_states_for_stream(dc->current_state->scratch.plane_states, stream);
|
||||
restore_planes_and_stream_state(&dc->current_state->scratch, stream);
|
||||
minimal_transition_context = create_minimal_transition_state(dc,
|
||||
dc->current_state, &policy);
|
||||
if (minimal_transition_context) {
|
||||
@ -4091,7 +4117,7 @@ static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
}
|
||||
release_minimal_transition_state(dc, minimal_transition_context, &policy);
|
||||
}
|
||||
restore_plane_states_for_stream(context->scratch.plane_states, stream);
|
||||
restore_planes_and_stream_state(&context->scratch, stream);
|
||||
}
|
||||
|
||||
ASSERT(success);
|
||||
@ -4099,7 +4125,7 @@ static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
}
|
||||
|
||||
/**
|
||||
* commit_minimal_transition_state - Create a transition pipe split state
|
||||
* commit_minimal_transition_state_legacy - Create a transition pipe split state
|
||||
*
|
||||
* @dc: Used to get the current state status
|
||||
* @transition_base_context: New transition state
|
||||
@ -4116,7 +4142,7 @@ static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
* Return:
|
||||
* Return false if something is wrong in the transition state.
|
||||
*/
|
||||
static bool commit_minimal_transition_state(struct dc *dc,
|
||||
static bool commit_minimal_transition_state_legacy(struct dc *dc,
|
||||
struct dc_state *transition_base_context)
|
||||
{
|
||||
struct dc_state *transition_context;
|
||||
@ -4354,53 +4380,6 @@ static bool fast_update_only(struct dc *dc,
|
||||
&& !full_update_required(dc, srf_updates, surface_count, stream_update, stream);
|
||||
}
|
||||
|
||||
static bool should_commit_minimal_transition_for_windowed_mpo_odm(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_state *context)
|
||||
{
|
||||
struct pipe_ctx *cur_pipe, *new_pipe;
|
||||
bool cur_is_odm_in_use, new_is_odm_in_use;
|
||||
struct dc_stream_status *cur_stream_status = stream_get_status(dc->current_state, stream);
|
||||
struct dc_stream_status *new_stream_status = stream_get_status(context, stream);
|
||||
|
||||
if (!dc->debug.enable_single_display_2to1_odm_policy ||
|
||||
!dc->config.enable_windowed_mpo_odm)
|
||||
/* skip the check if windowed MPO ODM or dynamic ODM is turned
|
||||
* off.
|
||||
*/
|
||||
return false;
|
||||
|
||||
if (context == dc->current_state)
|
||||
/* skip the check for fast update */
|
||||
return false;
|
||||
|
||||
if (new_stream_status->plane_count != cur_stream_status->plane_count)
|
||||
/* plane count changed, not a plane scaling update so not the
|
||||
* case we are looking for
|
||||
*/
|
||||
return false;
|
||||
|
||||
cur_pipe = resource_get_otg_master_for_stream(&dc->current_state->res_ctx, stream);
|
||||
new_pipe = resource_get_otg_master_for_stream(&context->res_ctx, stream);
|
||||
if (!cur_pipe || !new_pipe)
|
||||
return false;
|
||||
cur_is_odm_in_use = resource_get_odm_slice_count(cur_pipe) > 1;
|
||||
new_is_odm_in_use = resource_get_odm_slice_count(new_pipe) > 1;
|
||||
if (cur_is_odm_in_use == new_is_odm_in_use)
|
||||
/* ODM state isn't changed, not the case we are looking for */
|
||||
return false;
|
||||
|
||||
if (dc->hwss.is_pipe_topology_transition_seamless &&
|
||||
dc->hwss.is_pipe_topology_transition_seamless(
|
||||
dc, dc->current_state, context))
|
||||
/* transition can be achieved without the need for committing
|
||||
* minimal transition state first
|
||||
*/
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dc_update_planes_and_stream(struct dc *dc,
|
||||
struct dc_surface_update *srf_updates, int surface_count,
|
||||
struct dc_stream_state *stream,
|
||||
@ -4433,7 +4412,7 @@ bool dc_update_planes_and_stream(struct dc *dc,
|
||||
|
||||
/* on plane addition, minimal state is the current one */
|
||||
if (force_minimal_pipe_splitting && is_plane_addition &&
|
||||
!commit_minimal_transition_state(dc, dc->current_state))
|
||||
!commit_minimal_transition_state_legacy(dc, dc->current_state))
|
||||
return false;
|
||||
|
||||
if (!update_planes_and_stream_state(
|
||||
@ -4448,32 +4427,19 @@ bool dc_update_planes_and_stream(struct dc *dc,
|
||||
|
||||
/* on plane removal, minimal state is the new one */
|
||||
if (force_minimal_pipe_splitting && !is_plane_addition) {
|
||||
/* Since all phantom pipes are removed in full validation,
|
||||
* we have to save and restore the subvp/mall config when
|
||||
* we do a minimal transition since the flags marking the
|
||||
* pipe as subvp/phantom will be cleared (dc copy constructor
|
||||
* creates a shallow copy).
|
||||
*/
|
||||
if (!commit_minimal_transition_state(dc, context)) {
|
||||
if (!commit_minimal_transition_state_legacy(dc, context)) {
|
||||
dc_state_release(context);
|
||||
return false;
|
||||
}
|
||||
update_type = UPDATE_TYPE_FULL;
|
||||
}
|
||||
|
||||
/* when windowed MPO ODM is supported, we need to handle a special case
|
||||
* where we can transition between ODM combine and MPC combine due to
|
||||
* plane scaling update. This transition will require us to commit
|
||||
* minimal transition state. The condition to trigger this update can't
|
||||
* be predicted by could_mpcc_tree_change_for_active_pipes because we
|
||||
* can only determine it after DML validation. Therefore we can't rely
|
||||
* on the existing commit minimal transition state sequence. Instead
|
||||
* we have to add additional handling here to handle this transition
|
||||
* with its own special sequence.
|
||||
*/
|
||||
if (should_commit_minimal_transition_for_windowed_mpo_odm(dc, stream, context))
|
||||
commit_minimal_transition_state_for_windowed_mpo_odm(dc,
|
||||
if (dc->hwss.is_pipe_topology_transition_seamless &&
|
||||
!dc->hwss.is_pipe_topology_transition_seamless(
|
||||
dc, dc->current_state, context)) {
|
||||
commit_minimal_transition_state(dc,
|
||||
context, stream);
|
||||
}
|
||||
update_seamless_boot_flags(dc, context, surface_count, stream);
|
||||
if (is_fast_update_only && !dc->debug.enable_legacy_fast_update) {
|
||||
commit_planes_for_stream_fast(dc,
|
||||
|
@ -51,7 +51,7 @@ struct aux_payload;
|
||||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.272"
|
||||
#define DC_VER "3.2.273"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "dc_bios_types.h"
|
||||
#include "link_enc_cfg.h"
|
||||
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "gpio_service_interface.h"
|
||||
|
||||
#ifndef MIN
|
||||
@ -61,6 +62,38 @@
|
||||
#define AUX_REG_WRITE(reg_name, val) \
|
||||
dm_write_reg(CTX, AUX_REG(reg_name), val)
|
||||
|
||||
static uint8_t phy_id_from_transmitter(enum transmitter t)
|
||||
{
|
||||
uint8_t phy_id;
|
||||
|
||||
switch (t) {
|
||||
case TRANSMITTER_UNIPHY_A:
|
||||
phy_id = 0;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_B:
|
||||
phy_id = 1;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_C:
|
||||
phy_id = 2;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_D:
|
||||
phy_id = 3;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_E:
|
||||
phy_id = 4;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_F:
|
||||
phy_id = 5;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_G:
|
||||
phy_id = 6;
|
||||
break;
|
||||
default:
|
||||
phy_id = 0;
|
||||
break;
|
||||
}
|
||||
return phy_id;
|
||||
}
|
||||
|
||||
void enc32_hw_init(struct link_encoder *enc)
|
||||
{
|
||||
@ -117,38 +150,50 @@ void dcn32_link_encoder_enable_dp_output(
|
||||
}
|
||||
}
|
||||
|
||||
static bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
|
||||
static bool query_dp_alt_from_dmub(struct link_encoder *enc,
|
||||
union dmub_rb_cmd *cmd)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t dp_alt_mode_disable = 0;
|
||||
bool is_usb_c_alt_mode = false;
|
||||
|
||||
if (enc->features.flags.bits.DP_IS_USB_C) {
|
||||
/* if value == 1 alt mode is disabled, otherwise it is enabled */
|
||||
REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
|
||||
is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
|
||||
}
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
cmd->query_dp_alt.header.type = DMUB_CMD__VBIOS;
|
||||
cmd->query_dp_alt.header.sub_type =
|
||||
DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT;
|
||||
cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data);
|
||||
cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter);
|
||||
|
||||
return is_usb_c_alt_mode;
|
||||
if (!dc_wake_and_execute_dmub_cmd(enc->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
if (!query_dp_alt_from_dmub(enc, &cmd))
|
||||
return false;
|
||||
|
||||
return (cmd.query_dp_alt.data.is_dp_alt_disable == 0);
|
||||
}
|
||||
|
||||
void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t is_in_usb_c_dp4_mode = 0;
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
dcn10_link_encoder_get_max_link_cap(enc, link_settings);
|
||||
|
||||
/* in usb c dp2 mode, max lane count is 2 */
|
||||
if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
|
||||
REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
|
||||
if (!is_in_usb_c_dp4_mode)
|
||||
link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
|
||||
}
|
||||
if (!query_dp_alt_from_dmub(enc, &cmd))
|
||||
return;
|
||||
|
||||
if (cmd.query_dp_alt.data.is_usb &&
|
||||
cmd.query_dp_alt.data.is_dp4 == 0)
|
||||
link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
|
||||
}
|
||||
|
||||
|
||||
static const struct link_encoder_funcs dcn32_link_enc_funcs = {
|
||||
.read_state = link_enc2_read_state,
|
||||
.validate_output_with_stream =
|
||||
@ -203,13 +248,15 @@ void dcn32_link_encoder_construct(
|
||||
enc10->base.hpd_source = init_data->hpd_source;
|
||||
enc10->base.connector = init_data->connector;
|
||||
|
||||
|
||||
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
|
||||
|
||||
enc10->base.features = *enc_features;
|
||||
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
|
||||
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
|
||||
|
||||
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
|
||||
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
|
||||
|
||||
enc10->base.transmitter = init_data->transmitter;
|
||||
|
||||
/* set the flag to indicate whether driver poll the I2C data pin
|
||||
|
@ -53,4 +53,9 @@ void dcn32_link_encoder_enable_dp_output(
|
||||
const struct dc_link_settings *link_settings,
|
||||
enum clock_source_id clock_source);
|
||||
|
||||
bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc);
|
||||
|
||||
void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings);
|
||||
|
||||
#endif /* __DC_LINK_ENCODER__DCN32_H__ */
|
||||
|
@ -623,7 +623,6 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc,
|
||||
* - Not TMZ surface
|
||||
*/
|
||||
if (pipe->plane_state && !pipe->top_pipe && !dcn32_is_center_timing(pipe) &&
|
||||
!(pipe->stream->timing.pix_clk_100hz / 10000 > DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ) &&
|
||||
(!dcn32_is_psr_capable(pipe) || (context->stream_count == 1 && dc->caps.dmub_caps.subvp_psr)) &&
|
||||
dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_NONE &&
|
||||
(refresh_rate < 120 || dcn32_allow_subvp_high_refresh_rate(dc, context, pipe)) &&
|
||||
|
@ -76,6 +76,11 @@ static void map_hw_resources(struct dml2_context *dml2,
|
||||
in_out_display_cfg->hw.DLGRefClkFreqMHz = 50;
|
||||
}
|
||||
for (j = 0; j < mode_support_info->DPPPerSurface[i]; j++) {
|
||||
if (i >= __DML2_WRAPPER_MAX_STREAMS_PLANES__) {
|
||||
dml_print("DML::%s: Index out of bounds: i=%d, __DML2_WRAPPER_MAX_STREAMS_PLANES__=%d\n",
|
||||
__func__, i, __DML2_WRAPPER_MAX_STREAMS_PLANES__);
|
||||
break;
|
||||
}
|
||||
dml2->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id[num_pipes] = dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[i];
|
||||
dml2->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id_valid[num_pipes] = true;
|
||||
dml2->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id[num_pipes] = dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[i];
|
||||
|
@ -23,8 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "include/hdcp_msg_types.h"
|
||||
|
@ -522,6 +522,25 @@ struct dc_dmub_cmd {
|
||||
enum dm_dmub_wait_type wait_type;
|
||||
};
|
||||
|
||||
struct dc_scratch_space {
|
||||
/* used to temporarily backup plane states of a stream during
|
||||
* dc update. The reason is that plane states are overwritten
|
||||
* with surface updates in dc update. Once they are overwritten
|
||||
* current state is no longer valid. We want to temporarily
|
||||
* store current value in plane states so we can still recover
|
||||
* a valid current state during dc update.
|
||||
*/
|
||||
struct dc_plane_state plane_states[MAX_SURFACE_NUM];
|
||||
struct dc_gamma gamma_correction[MAX_SURFACE_NUM];
|
||||
struct dc_transfer_func in_transfer_func[MAX_SURFACE_NUM];
|
||||
struct dc_3dlut lut3d_func[MAX_SURFACE_NUM];
|
||||
struct dc_transfer_func in_shaper_func[MAX_SURFACE_NUM];
|
||||
struct dc_transfer_func blend_tf[MAX_SURFACE_NUM];
|
||||
|
||||
struct dc_stream_state stream_state;
|
||||
struct dc_transfer_func out_transfer_func;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dc_state - The full description of a state requested by users
|
||||
*/
|
||||
@ -604,16 +623,8 @@ struct dc_state {
|
||||
unsigned int stutter_period_us;
|
||||
} perf_params;
|
||||
|
||||
struct {
|
||||
/* used to temporarily backup plane states of a stream during
|
||||
* dc update. The reason is that plane states are overwritten
|
||||
* with surface updates in dc update. Once they are overwritten
|
||||
* current state is no longer valid. We want to temporarily
|
||||
* store current value in plane states so we can still recover
|
||||
* a valid current state during dc update.
|
||||
*/
|
||||
struct dc_plane_state plane_states[MAX_SURFACE_NUM];
|
||||
} scratch;
|
||||
|
||||
struct dc_scratch_space scratch;
|
||||
};
|
||||
|
||||
struct replay_context {
|
||||
|
@ -23,8 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
#include "include/logger_interface.h"
|
||||
|
@ -23,8 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
#include "include/logger_interface.h"
|
||||
|
@ -164,7 +164,7 @@ static void dpcd_extend_address_range(
|
||||
if (new_addr_range.start != in_address || new_addr_range.end != end_address) {
|
||||
*out_address = new_addr_range.start;
|
||||
*out_size = ADDRESS_RANGE_SIZE(new_addr_range.start, new_addr_range.end);
|
||||
*out_data = kzalloc(*out_size * sizeof(**out_data), GFP_KERNEL);
|
||||
*out_data = kcalloc(*out_size, sizeof(**out_data), GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dc.h"
|
||||
|
||||
|
@ -2118,6 +2118,7 @@ static bool dcn32_resource_construct(
|
||||
dc->config.use_pipe_ctx_sync_logic = true;
|
||||
|
||||
dc->config.dc_mode_clk_limit_support = true;
|
||||
dc->config.enable_windowed_mpo_odm = true;
|
||||
/* read VBIOS LTTPR caps */
|
||||
{
|
||||
if (ctx->dc_bios->funcs->get_lttpr_caps) {
|
||||
|
@ -1760,7 +1760,7 @@ static bool dcn321_resource_construct(
|
||||
dc->caps.color.mpc.ocsc = 1;
|
||||
|
||||
dc->config.dc_mode_clk_limit_support = true;
|
||||
dc->config.enable_windowed_mpo_odm = false;
|
||||
dc->config.enable_windowed_mpo_odm = true;
|
||||
/* read VBIOS LTTPR caps */
|
||||
{
|
||||
if (ctx->dc_bios->funcs->get_lttpr_caps) {
|
||||
|
@ -555,8 +555,14 @@ uint32_t dmub_dcn35_read_inbox0_ack_register(struct dmub_srv *dmub)
|
||||
bool dmub_dcn35_is_hw_powered_up(struct dmub_srv *dmub)
|
||||
{
|
||||
union dmub_fw_boot_status status;
|
||||
uint32_t is_enable;
|
||||
|
||||
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enable);
|
||||
if (is_enable == 0)
|
||||
return false;
|
||||
|
||||
status.all = REG_READ(DMCUB_SCRATCH0);
|
||||
|
||||
return status.bits.hw_power_init_done;
|
||||
return (status.bits.dal_fw && status.bits.hw_power_init_done && status.bits.mailbox_rdy) ||
|
||||
(!status.bits.dal_fw && status.bits.mailbox_rdy);
|
||||
}
|
||||
|
@ -800,20 +800,13 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
|
||||
|
||||
bool dmub_srv_is_hw_pwr_up(struct dmub_srv *dmub)
|
||||
{
|
||||
union dmub_fw_boot_status status;
|
||||
|
||||
if (!dmub->hw_funcs.is_hw_powered_up)
|
||||
return true;
|
||||
|
||||
if (!dmub->hw_funcs.is_hw_powered_up(dmub))
|
||||
return false;
|
||||
|
||||
if (!dmub->hw_funcs.is_hw_init(dmub))
|
||||
return false;
|
||||
|
||||
status = dmub->hw_funcs.get_fw_status(dmub);
|
||||
|
||||
return status.bits.dal_fw && status.bits.mailbox_rdy;
|
||||
return true;
|
||||
}
|
||||
|
||||
enum dmub_status dmub_srv_wait_for_hw_pwr_up(struct dmub_srv *dmub,
|
||||
|
@ -57,10 +57,10 @@ void mod_stats_update_event(struct mod_stats *mod_stats,
|
||||
unsigned int length);
|
||||
|
||||
void mod_stats_update_flip(struct mod_stats *mod_stats,
|
||||
unsigned long timestamp_in_ns);
|
||||
unsigned long long timestamp_in_ns);
|
||||
|
||||
void mod_stats_update_vupdate(struct mod_stats *mod_stats,
|
||||
unsigned long timestamp_in_ns);
|
||||
unsigned long long timestamp_in_ns);
|
||||
|
||||
void mod_stats_update_freesync(struct mod_stats *mod_stats,
|
||||
unsigned int v_total_min,
|
||||
|
@ -38896,13 +38896,5 @@
|
||||
#define RCC_DEV0_EPF0_VF7_GFXMSIX_PBA__MSIX_PENDING_BITS_0_MASK 0x00000001L
|
||||
#define RCC_DEV0_EPF0_VF7_GFXMSIX_PBA__MSIX_PENDING_BITS_1_MASK 0x00000002L
|
||||
|
||||
//PCIE_PERF_CNTL_TXCLK3
|
||||
#define PCIE_PERF_CNTL_TXCLK3__EVENT0_SEL__SHIFT 0x0
|
||||
#define PCIE_PERF_CNTL_TXCLK3__EVENT0_SEL_MASK 0x000000FFL
|
||||
|
||||
//PCIE_PERF_CNTL_TXCLK7
|
||||
#define PCIE_PERF_CNTL_TXCLK7__EVENT0_SEL__SHIFT 0x0
|
||||
#define PCIE_PERF_CNTL_TXCLK7__EVENT0_SEL_MASK 0x000000FFL
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -610,6 +610,38 @@ struct atom_firmware_info_v3_4 {
|
||||
uint32_t reserved[2];
|
||||
};
|
||||
|
||||
struct atom_firmware_info_v3_5 {
|
||||
struct atom_common_table_header table_header;
|
||||
uint32_t firmware_revision;
|
||||
uint32_t bootup_clk_reserved[2];
|
||||
uint32_t firmware_capability; // enum atombios_firmware_capability
|
||||
uint32_t fw_protect_region_size_in_kb; /* FW allocate a write protect region at top of FB. */
|
||||
uint32_t bios_scratch_reg_startaddr; // 1st bios scratch register dword address
|
||||
uint32_t bootup_voltage_reserved[2];
|
||||
uint8_t mem_module_id;
|
||||
uint8_t coolingsolution_id; /*0: Air cooling; 1: Liquid cooling ... */
|
||||
uint8_t hw_blt_mode; //0:HW_BLT_DMA_PIO_MODE; 1:HW_BLT_LITE_SDMA_MODE; 2:HW_BLT_PCI_IO_MODE
|
||||
uint8_t reserved1;
|
||||
uint32_t mc_baseaddr_high;
|
||||
uint32_t mc_baseaddr_low;
|
||||
uint8_t board_i2c_feature_id; // enum of atom_board_i2c_feature_id_def
|
||||
uint8_t board_i2c_feature_gpio_id; // i2c id find in gpio_lut data table gpio_id
|
||||
uint8_t board_i2c_feature_slave_addr;
|
||||
uint8_t ras_rom_i2c_slave_addr;
|
||||
uint32_t bootup_voltage_reserved1;
|
||||
uint32_t zfb_reserved;
|
||||
// if pplib_pptable_id!=0, pplib get powerplay table inside driver instead of from VBIOS
|
||||
uint32_t pplib_pptable_id;
|
||||
uint32_t hw_voltage_reserved[3];
|
||||
uint32_t maco_pwrlimit_mw; // bomaco mode power limit in unit of m-watt
|
||||
uint32_t usb_pwrlimit_mw; // power limit when USB is enable in unit of m-watt
|
||||
uint32_t fw_reserved_size_in_kb; // VBIOS reserved extra fw size in unit of kb.
|
||||
uint32_t pspbl_init_reserved[3];
|
||||
uint32_t spi_rom_size; // GPU spi rom size
|
||||
uint16_t support_dev_in_objinfo;
|
||||
uint16_t disp_phy_tunning_size;
|
||||
uint32_t reserved[16];
|
||||
};
|
||||
/*
|
||||
***************************************************************************
|
||||
Data Table lcd_info structure
|
||||
|
@ -2034,6 +2034,31 @@ static int ss_bias_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pp_od_clk_voltage_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
|
||||
uint32_t mask, enum amdgpu_device_attr_states *states)
|
||||
{
|
||||
uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0);
|
||||
|
||||
*states = ATTR_STATE_SUPPORTED;
|
||||
|
||||
if (!amdgpu_dpm_is_overdrive_supported(adev)) {
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Enable pp_od_clk_voltage node for gc 9.4.3 SRIOV/BM support */
|
||||
if (gc_ver == IP_VERSION(9, 4, 3)) {
|
||||
if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(attr->flags & mask))
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Following items will be read out to indicate current plpd policy:
|
||||
* - -1: none
|
||||
* - 0: disallow
|
||||
@ -2118,7 +2143,8 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = {
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_sclk_od, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_mclk_od, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_power_profile_mode, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_od_clk_voltage, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_od_clk_voltage, ATTR_FLAG_BASIC,
|
||||
.attr_update = pp_od_clk_voltage_attr_update),
|
||||
AMDGPU_DEVICE_ATTR_RO(gpu_busy_percent, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RO(mem_busy_percent, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RO(pcie_bw, ATTR_FLAG_BASIC),
|
||||
@ -2163,10 +2189,6 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
|
||||
} else if (DEVICE_ATTR_IS(pp_dpm_fclk)) {
|
||||
if (mp1_ver < IP_VERSION(10, 0, 0))
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
} else if (DEVICE_ATTR_IS(pp_od_clk_voltage)) {
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
if (amdgpu_dpm_is_overdrive_supported(adev))
|
||||
*states = ATTR_STATE_SUPPORTED;
|
||||
} else if (DEVICE_ATTR_IS(mem_busy_percent)) {
|
||||
if ((adev->flags & AMD_IS_APU &&
|
||||
gc_ver != IP_VERSION(9, 4, 3)) ||
|
||||
@ -2174,7 +2196,8 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
} else if (DEVICE_ATTR_IS(pcie_bw)) {
|
||||
/* PCIe Perf counters won't work on APU nodes */
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
if (adev->flags & AMD_IS_APU ||
|
||||
!adev->asic_funcs->get_pcie_usage)
|
||||
*states = ATTR_STATE_UNSUPPORTED;
|
||||
} else if (DEVICE_ATTR_IS(unique_id)) {
|
||||
switch (gc_ver) {
|
||||
|
@ -6925,6 +6925,23 @@ static int si_dpm_enable(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int si_set_temperature_range(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = si_thermal_enable_alert(adev, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = si_thermal_enable_alert(adev, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void si_dpm_disable(struct amdgpu_device *adev)
|
||||
{
|
||||
struct rv7xx_power_info *pi = rv770_get_pi(adev);
|
||||
@ -7608,6 +7625,18 @@ static int si_dpm_process_interrupt(struct amdgpu_device *adev,
|
||||
|
||||
static int si_dpm_late_init(void *handle)
|
||||
{
|
||||
int ret;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (!adev->pm.dpm_enabled)
|
||||
return 0;
|
||||
|
||||
ret = si_set_temperature_range(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#if 0 //TODO ?
|
||||
si_dpm_powergate_uvd(adev, true);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1303,13 +1303,12 @@ static int arcturus_get_power_limit(struct smu_context *smu,
|
||||
if (default_power_limit)
|
||||
*default_power_limit = power_limit;
|
||||
|
||||
if (smu->od_enabled) {
|
||||
if (smu->od_enabled)
|
||||
od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
|
||||
} else {
|
||||
else
|
||||
od_percent_upper = 0;
|
||||
od_percent_lower = 100;
|
||||
}
|
||||
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
|
||||
|
||||
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
|
||||
od_percent_upper, od_percent_lower, power_limit);
|
||||
@ -2273,8 +2272,8 @@ static uint16_t arcturus_get_current_pcie_link_speed(struct smu_context *smu)
|
||||
|
||||
/* TODO: confirm this on real target */
|
||||
esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
|
||||
if ((esm_ctrl >> 15) & 0x1FFFF)
|
||||
return (uint16_t)(((esm_ctrl >> 8) & 0x3F) + 128);
|
||||
if ((esm_ctrl >> 15) & 0x1)
|
||||
return (uint16_t)(((esm_ctrl >> 8) & 0x7F) + 128);
|
||||
|
||||
return smu_v11_0_get_current_pcie_link_speed(smu);
|
||||
}
|
||||
|
@ -2357,13 +2357,12 @@ static int navi10_get_power_limit(struct smu_context *smu,
|
||||
*default_power_limit = power_limit;
|
||||
|
||||
if (smu->od_enabled &&
|
||||
navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
|
||||
navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT))
|
||||
od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
|
||||
} else {
|
||||
else
|
||||
od_percent_upper = 0;
|
||||
od_percent_lower = 100;
|
||||
}
|
||||
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
|
||||
|
||||
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
|
||||
od_percent_upper, od_percent_lower, power_limit);
|
||||
|
@ -640,13 +640,12 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu,
|
||||
if (default_power_limit)
|
||||
*default_power_limit = power_limit;
|
||||
|
||||
if (smu->od_enabled) {
|
||||
if (smu->od_enabled)
|
||||
od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
|
||||
} else {
|
||||
else
|
||||
od_percent_upper = 0;
|
||||
od_percent_lower = 100;
|
||||
}
|
||||
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
|
||||
|
||||
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
|
||||
od_percent_upper, od_percent_lower, power_limit);
|
||||
|
@ -1682,8 +1682,8 @@ static int aldebaran_get_current_pcie_link_speed(struct smu_context *smu)
|
||||
|
||||
/* TODO: confirm this on real target */
|
||||
esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
|
||||
if ((esm_ctrl >> 15) & 0x1FFFF)
|
||||
return (((esm_ctrl >> 8) & 0x3F) + 128);
|
||||
if ((esm_ctrl >> 15) & 0x1)
|
||||
return (((esm_ctrl >> 8) & 0x7F) + 128);
|
||||
|
||||
return smu_v13_0_get_current_pcie_link_speed(smu);
|
||||
}
|
||||
@ -1746,10 +1746,12 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
|
||||
|
||||
gpu_metrics->current_fan_speed = 0;
|
||||
|
||||
gpu_metrics->pcie_link_width =
|
||||
smu_v13_0_get_current_pcie_link_width(smu);
|
||||
gpu_metrics->pcie_link_speed =
|
||||
aldebaran_get_current_pcie_link_speed(smu);
|
||||
if (!amdgpu_sriov_vf(smu->adev)) {
|
||||
gpu_metrics->pcie_link_width =
|
||||
smu_v13_0_get_current_pcie_link_width(smu);
|
||||
gpu_metrics->pcie_link_speed =
|
||||
aldebaran_get_current_pcie_link_speed(smu);
|
||||
}
|
||||
|
||||
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
|
||||
|
||||
|
@ -2369,13 +2369,12 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
|
||||
if (default_power_limit)
|
||||
*default_power_limit = power_limit;
|
||||
|
||||
if (smu->od_enabled) {
|
||||
if (smu->od_enabled)
|
||||
od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
|
||||
} else {
|
||||
else
|
||||
od_percent_upper = 0;
|
||||
od_percent_lower = 100;
|
||||
}
|
||||
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
|
||||
|
||||
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
|
||||
od_percent_upper, od_percent_lower, power_limit);
|
||||
|
@ -2147,8 +2147,8 @@ static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu)
|
||||
|
||||
/* TODO: confirm this on real target */
|
||||
esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
|
||||
if ((esm_ctrl >> 15) & 0x1FFFF)
|
||||
return (((esm_ctrl >> 8) & 0x3F) + 128);
|
||||
if ((esm_ctrl >> 15) & 0x1)
|
||||
return (((esm_ctrl >> 8) & 0x7F) + 128);
|
||||
|
||||
speed_level = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &
|
||||
PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)
|
||||
@ -2228,14 +2228,16 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table
|
||||
gpu_metrics->gfxclk_lock_status = GET_METRIC_FIELD(GfxLockXCDMak) >> GET_INST(GC, 0);
|
||||
|
||||
if (!(adev->flags & AMD_IS_APU)) {
|
||||
link_width_level = smu_v13_0_6_get_current_pcie_link_width_level(smu);
|
||||
if (link_width_level > MAX_LINK_WIDTH)
|
||||
link_width_level = 0;
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
link_width_level = smu_v13_0_6_get_current_pcie_link_width_level(smu);
|
||||
if (link_width_level > MAX_LINK_WIDTH)
|
||||
link_width_level = 0;
|
||||
|
||||
gpu_metrics->pcie_link_width =
|
||||
DECODE_LANE_WIDTH(link_width_level);
|
||||
gpu_metrics->pcie_link_speed =
|
||||
smu_v13_0_6_get_current_pcie_link_speed(smu);
|
||||
gpu_metrics->pcie_link_width =
|
||||
DECODE_LANE_WIDTH(link_width_level);
|
||||
gpu_metrics->pcie_link_speed =
|
||||
smu_v13_0_6_get_current_pcie_link_speed(smu);
|
||||
}
|
||||
gpu_metrics->pcie_bandwidth_acc =
|
||||
SMUQ10_ROUND(metrics_x->PcieBandwidthAcc[0]);
|
||||
gpu_metrics->pcie_bandwidth_inst =
|
||||
@ -2306,8 +2308,8 @@ static int smu_v13_0_6_mode2_reset(struct smu_context *smu)
|
||||
ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index,
|
||||
SMU_RESET_MODE_2);
|
||||
|
||||
/* This is similar to FLR, wait till max FLR timeout */
|
||||
msleep(100);
|
||||
/* Reset takes a bit longer, wait for 200ms. */
|
||||
msleep(200);
|
||||
|
||||
dev_dbg(smu->adev->dev, "restore config space...\n");
|
||||
/* Restore the config space saved during init */
|
||||
|
@ -2333,13 +2333,12 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
|
||||
if (default_power_limit)
|
||||
*default_power_limit = power_limit;
|
||||
|
||||
if (smu->od_enabled) {
|
||||
if (smu->od_enabled)
|
||||
od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
|
||||
} else {
|
||||
else
|
||||
od_percent_upper = 0;
|
||||
od_percent_lower = 100;
|
||||
}
|
||||
|
||||
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
|
||||
|
||||
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
|
||||
od_percent_upper, od_percent_lower, power_limit);
|
||||
|
@ -229,8 +229,6 @@ int smu_v14_0_check_fw_version(struct smu_context *smu)
|
||||
smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_2;
|
||||
break;
|
||||
case IP_VERSION(14, 0, 0):
|
||||
if ((smu->smc_fw_version < 0x5d3a00))
|
||||
dev_warn(smu->adev->dev, "The PMFW version(%x) is behind in this BIOS!\n", smu->smc_fw_version);
|
||||
smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_0;
|
||||
break;
|
||||
default:
|
||||
|
@ -261,7 +261,10 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
|
||||
*value = metrics->MpipuclkFrequency;
|
||||
break;
|
||||
case METRICS_AVERAGE_GFXACTIVITY:
|
||||
*value = metrics->GfxActivity / 100;
|
||||
if ((smu->smc_fw_version > 0x5d4600))
|
||||
*value = metrics->GfxActivity;
|
||||
else
|
||||
*value = metrics->GfxActivity / 100;
|
||||
break;
|
||||
case METRICS_AVERAGE_VCNACTIVITY:
|
||||
*value = metrics->VcnActivity / 100;
|
||||
|
@ -9592,28 +9592,18 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev)
|
||||
PCI_EXP_LNKCTL_HAWD);
|
||||
|
||||
/* linkctl2 */
|
||||
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (bridge_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(root,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
|
||||
pcie_capability_read_word(rdev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (gpu_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(rdev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
bridge_cfg2 |
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
gpu_cfg2 |
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
|
||||
tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
|
||||
tmp &= ~LC_SET_QUIESCE;
|
||||
@ -9627,15 +9617,15 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev)
|
||||
speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
|
||||
WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
|
||||
|
||||
pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16);
|
||||
tmp16 &= ~PCI_EXP_LNKCTL2_TLS;
|
||||
tmp16 = 0;
|
||||
if (speed_cap == PCIE_SPEED_8_0GT)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */
|
||||
else if (speed_cap == PCIE_SPEED_5_0GT)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */
|
||||
else
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */
|
||||
pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16);
|
||||
pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_TLS, tmp16);
|
||||
|
||||
speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
|
||||
speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
|
||||
|
@ -7174,28 +7174,18 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev)
|
||||
PCI_EXP_LNKCTL_HAWD);
|
||||
|
||||
/* linkctl2 */
|
||||
pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (bridge_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(root,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
|
||||
pcie_capability_read_word(rdev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
&tmp16);
|
||||
tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN);
|
||||
tmp16 |= (gpu_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_write_word(rdev->pdev,
|
||||
PCI_EXP_LNKCTL2,
|
||||
tmp16);
|
||||
pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
bridge_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN,
|
||||
gpu_cfg2 &
|
||||
(PCI_EXP_LNKCTL2_ENTER_COMP |
|
||||
PCI_EXP_LNKCTL2_TX_MARGIN));
|
||||
|
||||
tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
|
||||
tmp &= ~LC_SET_QUIESCE;
|
||||
@ -7209,15 +7199,15 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev)
|
||||
speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
|
||||
WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
|
||||
|
||||
pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16);
|
||||
tmp16 &= ~PCI_EXP_LNKCTL2_TLS;
|
||||
tmp16 = 0;
|
||||
if (speed_cap == PCIE_SPEED_8_0GT)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */
|
||||
else if (speed_cap == PCIE_SPEED_5_0GT)
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */
|
||||
else
|
||||
tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */
|
||||
pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16);
|
||||
pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2,
|
||||
PCI_EXP_LNKCTL2_TLS, tmp16);
|
||||
|
||||
speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
|
||||
speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
|
||||
|
Loading…
Reference in New Issue
Block a user