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:
Dave Airlie 2024-03-08 11:21:13 +10:00
commit af165fb00a
90 changed files with 782 additions and 659 deletions

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -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!");

View File

@ -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:

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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)++;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);
/*

View File

@ -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;

View File

@ -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)
{

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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++) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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 =

View File

@ -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;

View File

@ -23,8 +23,6 @@
*
*/
#include <linux/slab.h>
#include "resource.h"
#include "dm_services.h"
#include "dce_calcs.h"

View File

@ -23,8 +23,6 @@
*
*/
#include <linux/slab.h>
#include "dal_asic_id.h"
#include "dc_types.h"
#include "dccg.h"

View File

@ -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);

View File

@ -23,8 +23,6 @@
*
*/
#include <linux/slab.h>
#include "reg_helper.h"
#include "core_types.h"
#include "clk_mgr_internal.h"

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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)) &&

View File

@ -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];

View File

@ -23,8 +23,6 @@
*
*/
#include <linux/slab.h>
#include "dm_services.h"
#include "dm_helpers.h"
#include "include/hdcp_msg_types.h"

View File

@ -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 {

View File

@ -23,8 +23,6 @@
*
*/
#include <linux/slab.h>
#include "dm_services.h"
#include "include/logger_interface.h"

View File

@ -23,8 +23,6 @@
*
*/
#include <linux/slab.h>
#include "dm_services.h"
#include "include/logger_interface.h"

View File

@ -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);
}
}

View File

@ -24,8 +24,6 @@
*
*/
#include <linux/slab.h>
#include "dm_services.h"
#include "dc.h"

View File

@ -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) {

View File

@ -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) {

View File

@ -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);
}

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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;