diff options
| author | Dave Airlie <airlied@redhat.com> | 2026-07-10 11:43:08 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2026-07-10 11:43:22 +1000 |
| commit | e3cdab67efa8b1981620c792a845da91f75aaa63 (patch) | |
| tree | 3b2d6f59a33f233be1f56de3f1b0356f64620a0f | |
| parent | 9efb67c613b04794aa4777ee97ca6250d98df1a2 (diff) | |
| parent | 5c6c247992d4d9200e073b83f4ec6c703c096845 (diff) | |
Merge tag 'amd-drm-next-7.3-2026-07-09' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-7.3-2026-07-09:
amdgpu:
- RAS updates
- PSP 15.0.9 update
- SMU 15.0.9 update
- VCN 5.3 fix
- VI ASPM fix
- Userq fix
- lifetime fix for amdgpu_vm_get_task_info_pasid()
- Gfx10 fix
- SMU 14 fix
- JPEG cleanups
- MES fixes and cleanups
- Header cleanups
- Misc gfx fixes
- Gfx pipe1 support on gfx11 APUs
- BUG() and BUG_ON() removals
amdkfd:
- Merge fix
- CRIU bounds checking fixes
- secondary context id fix
- Event bounds checking fix
- Fix CWSR buffer mapping when in VRAM
- Secondary context fixes
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260709213953.16494-1-alexander.deucher@amd.com
94 files changed, 969 insertions, 1643 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 5100e35027ec..105b9dcc19a2 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -71,7 +71,8 @@ amdgpu-y += amdgpu_device.o amdgpu_reg_access.o amdgpu_doorbell_mgr.o amdgpu_kms amdgpu_fw_attestation.o amdgpu_securedisplay.o \ amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o amdgpu_lockdep.o \ amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o amdgpu_dev_coredump.o \ - amdgpu_cper.o amdgpu_userq_fence.o amdgpu_eviction_fence.o amdgpu_ip.o + amdgpu_cper.o amdgpu_userq_fence.o amdgpu_eviction_fence.o amdgpu_ip.o \ + amdgpu_wb.o amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index dd8ea71077af..8339ab6f5d32 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -96,7 +96,6 @@ #include "amdgpu_doorbell.h" #include "amdgpu_amdkfd.h" #include "amdgpu_discovery.h" -#include "amdgpu_mes.h" #include "amdgpu_umc.h" #include "amdgpu_mmhub.h" #include "amdgpu_gfxhub.h" @@ -112,8 +111,11 @@ #include "amdgpu_reg_state.h" #include "amdgpu_userq.h" #include "amdgpu_eviction_fence.h" +#include "amdgpu_wb.h" #include "amdgpu_ip.h" +#include "amdgpu_mes.h" #include "amdgpu_sa.h" +#include "amdgpu_acpi.h" #if defined(CONFIG_DRM_AMD_ISP) #include "amdgpu_isp.h" #endif @@ -135,13 +137,6 @@ struct amdgpu_mgpu_info { uint32_t num_apu; }; -enum amdgpu_ss { - AMDGPU_SS_DRV_LOAD, - AMDGPU_SS_DEV_D0, - AMDGPU_SS_DEV_D3, - AMDGPU_SS_DRV_UNLOAD -}; - struct amdgpu_hwip_reg_entry { u32 hwip; u32 inst; @@ -331,6 +326,7 @@ struct amdgpu_hive_info; struct amdgpu_reset_context; struct amdgpu_reset_control; struct amdgpu_coredump_info; +struct amdgpu_video_codecs; enum amdgpu_cp_irq { AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP = 0, @@ -430,106 +426,11 @@ struct amdgpu_fpriv { int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv); /* - * Writeback - */ -#define AMDGPU_MAX_WB 1024 /* Reserve at most 1024 WB slots for amdgpu-owned rings. */ - -/** - * struct amdgpu_wb - This struct is used for small GPU memory allocation. - * - * This struct is used to allocate a small amount of GPU memory that can be - * used to shadow certain states into the memory. This is especially useful for - * providing easy CPU access to some states without requiring register access - * (e.g., if some block is power gated, reading register may be problematic). - * - * Note: the term writeback was initially used because many of the amdgpu - * components had some level of writeback memory, and this struct initially - * described those components. - */ -struct amdgpu_wb { - - /** - * @wb_obj: - * - * Buffer Object used for the writeback memory. - */ - struct amdgpu_bo *wb_obj; - - /** - * @wb: - * - * Pointer to the first writeback slot. In terms of CPU address - * this value can be accessed directly by using the offset as an index. - * For the GPU address, it is necessary to use gpu_addr and the offset. - */ - uint32_t *wb; - - /** - * @gpu_addr: - * - * Writeback base address in the GPU. - */ - uint64_t gpu_addr; - - /** - * @num_wb: - * - * Number of writeback slots reserved for amdgpu. - */ - u32 num_wb; - - /** - * @used: - * - * Track the writeback slot already used. - */ - unsigned long used[DIV_ROUND_UP(AMDGPU_MAX_WB, BITS_PER_LONG)]; - - /** - * @lock: - * - * Protects read and write of the used field array. - */ - spinlock_t lock; -}; - -int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb); -void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb); - -/* * Benchmarking */ int amdgpu_benchmark(struct amdgpu_device *adev, int test_number); /* - * ASIC specific register table accessible by UMD - */ -struct amdgpu_allowed_register_entry { - uint32_t reg_offset; - bool grbm_indexed; -}; - -struct amdgpu_video_codec_info { - u32 codec_type; - u32 max_width; - u32 max_height; - u32 max_pixels_per_frame; - u32 max_level; -}; - -#define codec_info_build(type, width, height, level) \ - .codec_type = type,\ - .max_width = width,\ - .max_height = height,\ - .max_pixels_per_frame = height * width,\ - .max_level = level, - -struct amdgpu_video_codecs { - const u32 codec_count; - const struct amdgpu_video_codec_info *codec_array; -}; - -/* * ASIC specific functions. */ struct amdgpu_asic_funcs { @@ -632,38 +533,6 @@ struct amdgpu_uid { struct amdgpu_device *adev; }; -#define MAX_UMA_OPTION_NAME 28 -#define MAX_UMA_OPTION_ENTRIES 19 - -#define AMDGPU_UMA_FLAG_AUTO BIT(1) -#define AMDGPU_UMA_FLAG_CUSTOM BIT(0) - -/** - * struct amdgpu_uma_carveout_option - single UMA carveout option - * @name: Name of the carveout option - * @memory_carved_mb: Amount of memory carved in MB - * @flags: ATCS flags supported by this option - */ -struct amdgpu_uma_carveout_option { - char name[MAX_UMA_OPTION_NAME]; - uint32_t memory_carved_mb; - uint8_t flags; -}; - -/** - * struct amdgpu_uma_carveout_info - table of available UMA carveout options - * @num_entries: Number of available options - * @uma_option_index: The index of the option currently applied - * @update_lock: Lock to serialize changes to the option - * @entries: The array of carveout options - */ -struct amdgpu_uma_carveout_info { - uint8_t num_entries; - uint8_t uma_option_index; - struct mutex update_lock; - struct amdgpu_uma_carveout_option entries[MAX_UMA_OPTION_ENTRIES]; -}; - struct amd_powerplay { void *pp_handle; const struct amd_pm_funcs *pp_funcs; @@ -708,44 +577,6 @@ struct amd_powerplay { (rid == 0x01) || \ (rid == 0x10)))) -enum amdgpu_mqd_update_flag { - AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE = 1, - AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE = 2, - AMDGPU_UPDATE_FLAG_IS_GWS = 4, /* quirk for gfx9 IP */ -}; - -struct amdgpu_mqd_prop { - uint64_t mqd_gpu_addr; - uint64_t hqd_base_gpu_addr; - uint64_t rptr_gpu_addr; - uint64_t wptr_gpu_addr; - uint32_t queue_size; - bool use_doorbell; - uint32_t doorbell_index; - uint64_t eop_gpu_addr; - uint32_t hqd_pipe_priority; - uint32_t hqd_queue_priority; - uint32_t mqd_stride_size; - bool allow_tunneling; - bool hqd_active; - uint64_t shadow_addr; - uint64_t gds_bkup_addr; - uint64_t csa_addr; - uint64_t fence_address; - bool tmz_queue; - bool kernel_queue; - uint32_t *cu_mask; - uint32_t cu_mask_count; - uint32_t cu_flags; - bool is_user_cu_masked; -}; - -struct amdgpu_mqd { - unsigned mqd_size; - int (*init_mqd)(struct amdgpu_device *adev, void *mqd, - struct amdgpu_mqd_prop *p); -}; - struct amdgpu_pcie_reset_ctx { bool in_link_reset; bool occurs_dpc; @@ -1132,14 +963,6 @@ struct amdgpu_device { struct amdgpu_kfd_dev kfd; }; -/* - * MES FW uses address(mqd_addr + sizeof(struct mqd) + 3*sizeof(uint32_t)) - * as fence address and writes a 32 bit fence value to this address. - * Driver needs to allocate at least 4 DWs extra memory in addition to - * sizeof(struct mqd). Add 8 DWs and align to AMDGPU_GPU_PAGE_SIZE for safety. - */ -#define AMDGPU_MQD_SIZE_ALIGN(mqd_size) AMDGPU_GPU_PAGE_ALIGN(((mqd_size) + 32)) - static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev, uint8_t ip, uint8_t inst) { @@ -1456,88 +1279,6 @@ struct amdgpu_afmt_acr { struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock); -/* amdgpu_acpi.c */ - -struct amdgpu_numa_info { - uint64_t size; - int pxm; - int nid; -}; - -/* ATCS Device/Driver State */ -#define AMDGPU_ATCS_PSC_DEV_STATE_D0 0 -#define AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT 3 -#define AMDGPU_ATCS_PSC_DRV_STATE_OPR 0 -#define AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR 1 - -#if defined(CONFIG_ACPI) -int amdgpu_acpi_init(struct amdgpu_device *adev); -void amdgpu_acpi_fini(struct amdgpu_device *adev); -bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev); -bool amdgpu_acpi_is_power_shift_control_supported(void); -bool amdgpu_acpi_is_set_uma_allocation_size_supported(void); -int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, - u8 perf_req, bool advertise); -int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, - u8 dev_state, bool drv_state); -int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev, - enum amdgpu_ss ss_state); -int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type); -int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev); -int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset, - u64 *tmr_size); -int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id, - struct amdgpu_numa_info *numa_info); - -void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps); -bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev); -void amdgpu_acpi_detect(void); -void amdgpu_acpi_release(void); -#else -static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; } -static inline int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, - u64 *tmr_offset, u64 *tmr_size) -{ - return -EINVAL; -} -static inline int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, - int xcc_id, - struct amdgpu_numa_info *numa_info) -{ - return -EINVAL; -} -static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } -static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { return false; } -static inline void amdgpu_acpi_detect(void) { } -static inline void amdgpu_acpi_release(void) { } -static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; } -static inline bool amdgpu_acpi_is_set_uma_allocation_size_supported(void) { return false; } -static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, - u8 dev_state, bool drv_state) { return 0; } -static inline int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev, - enum amdgpu_ss ss_state) -{ - return 0; -} -static inline int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type) -{ - return -EINVAL; -} -static inline void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps) { } -#endif - -#if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) -bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); -bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); -#else -static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } -static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; } -#endif - -#if defined(CONFIG_DRM_AMD_ISP) -int amdgpu_acpi_get_isp4_dev(struct acpi_device **dev); -#endif - void amdgpu_register_gpu_instance(struct amdgpu_device *adev); void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h new file mode 100644 index 000000000000..6569a4db5dae --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT + * + * Copyright 2026 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __AMDGPU_ACPI_H__ +#define __AMDGPU_ACPI_H__ + +#include <linux/types.h> +#include <linux/mutex_types.h> + +struct amdgpu_device; +struct acpi_device; +struct amdgpu_dm_backlight_caps; + +#define MAX_UMA_OPTION_NAME 28 +#define MAX_UMA_OPTION_ENTRIES 19 + +#define AMDGPU_UMA_FLAG_AUTO BIT(1) +#define AMDGPU_UMA_FLAG_CUSTOM BIT(0) + +/* ATCS Device/Driver State */ +#define AMDGPU_ATCS_PSC_DEV_STATE_D0 0 +#define AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT 3 +#define AMDGPU_ATCS_PSC_DRV_STATE_OPR 0 +#define AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR 1 + +enum amdgpu_ss { + AMDGPU_SS_DRV_LOAD, + AMDGPU_SS_DEV_D0, + AMDGPU_SS_DEV_D3, + AMDGPU_SS_DRV_UNLOAD +}; + +/** + * struct amdgpu_uma_carveout_option - single UMA carveout option + * @name: Name of the carveout option + * @memory_carved_mb: Amount of memory carved in MB + * @flags: ATCS flags supported by this option + */ +struct amdgpu_uma_carveout_option { + char name[MAX_UMA_OPTION_NAME]; + uint32_t memory_carved_mb; + uint8_t flags; +}; + +/** + * struct amdgpu_uma_carveout_info - table of available UMA carveout options + * @num_entries: Number of available options + * @uma_option_index: The index of the option currently applied + * @update_lock: Lock to serialize changes to the option + * @entries: The array of carveout options + */ +struct amdgpu_uma_carveout_info { + uint8_t num_entries; + uint8_t uma_option_index; + struct mutex update_lock; + struct amdgpu_uma_carveout_option entries[MAX_UMA_OPTION_ENTRIES]; +}; + +struct amdgpu_numa_info { + uint64_t size; + int pxm; + int nid; +}; + +#if defined(CONFIG_ACPI) +int amdgpu_acpi_init(struct amdgpu_device *adev); +void amdgpu_acpi_fini(struct amdgpu_device *adev); +bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev); +bool amdgpu_acpi_is_power_shift_control_supported(void); +bool amdgpu_acpi_is_set_uma_allocation_size_supported(void); +int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, + u8 perf_req, bool advertise); +int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, + u8 dev_state, bool drv_state); +int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev, + enum amdgpu_ss ss_state); +int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type); +int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev); +int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset, + u64 *tmr_size); +int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id, + struct amdgpu_numa_info *numa_info); + +void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps); +bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev); +void amdgpu_acpi_detect(void); +void amdgpu_acpi_release(void); +#else +static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; } +static inline int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, + u64 *tmr_offset, u64 *tmr_size) +{ + return -EINVAL; +} +static inline int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, + int xcc_id, + struct amdgpu_numa_info *numa_info) +{ + return -EINVAL; +} +static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } +static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { return false; } +static inline void amdgpu_acpi_detect(void) { } +static inline void amdgpu_acpi_release(void) { } +static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; } +static inline bool amdgpu_acpi_is_set_uma_allocation_size_supported(void) { return false; } +static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, + u8 dev_state, bool drv_state) { return 0; } +static inline int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev, + enum amdgpu_ss ss_state) +{ + return 0; +} +static inline int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type) +{ + return -EINVAL; +} +static inline void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps) { } +#endif + +#if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND) +bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev); +bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev); +#else +static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; } +static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; } +#endif + +#if defined(CONFIG_DRM_AMD_ISP) +int amdgpu_acpi_get_isp4_dev(struct acpi_device **dev); +#endif +#endif /* __AMDGPU_ACPI_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c index 8aa068a4d3e3..724beb96ed1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c @@ -139,7 +139,8 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev, regSDMA1_QUEUE0_RB_CNTL) - regSDMA0_QUEUE0_RB_CNTL; break; default: - BUG(); + WARN(1, "Invalid SDMA engine id %d\n", engine_id); + break; } sdma_rlc_reg_offset = sdma_engine_reg_base diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c index bf0bd7688ee4..e11ba3e91841 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c @@ -90,7 +90,8 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev, regSDMA1_QUEUE0_RB_CNTL) - regSDMA0_QUEUE0_RB_CNTL; break; default: - BUG(); + WARN(1, "Invalid SDMA engine id %d\n", engine_id); + break; } sdma_rlc_reg_offset = sdma_engine_reg_base diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12_1.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12_1.c index bcb180f9d3ff..38ca1aea33b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12_1.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12_1.c @@ -93,7 +93,8 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev, regSDMA1_SDMA_QUEUE0_RB_CNTL) - regSDMA0_SDMA_QUEUE0_RB_CNTL; break; default: - BUG(); + WARN(1, "Invalid SDMA engine id %d\n", engine_id); + break; } sdma_rlc_reg_offset = sdma_engine_reg_base diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index 6860a3a4d466..1e21e3444802 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -917,8 +917,6 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) (crev != 6)) { spll->reference_freq = le32_to_cpu(gfx_info->v22.rlc_gpu_timer_refclk); ret = 0; - } else { - BUG(); } } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index babd23e5a27e..9bbe60968352 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -76,10 +76,9 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device, DRM_ERROR("audio endpt register access not implemented.\n"); return 0; default: - BUG(); + WARN(1, "Invalid indirect register space"); + return 0; } - WARN(1, "Invalid indirect register space"); - return 0; } static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device, @@ -104,9 +103,8 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device, DRM_ERROR("audio endpt register access not implemented.\n"); return; default: - BUG(); + WARN(1, "Invalid indirect register space"); } - WARN(1, "Invalid indirect register space"); } static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d777375e5350..d58701908158 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1118,7 +1118,8 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p) if (fpriv->csa_va) { bo_va = fpriv->csa_va; - BUG_ON(!bo_va); + if (!bo_va) + return -ENOMEM; r = amdgpu_vm_bo_update(adev, bo_va, false); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 78c96c7102e4..b39ec5ed6242 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -72,6 +72,7 @@ #include "amdgpu_xgmi.h" #include "amdgpu_ras.h" +#include "amdgpu_wb.h" #include "amdgpu_ras_mgr.h" #include "amdgpu_pmu.h" #include "amdgpu_smu.h" @@ -1006,109 +1007,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev) return pci_reset_function(adev->pdev); } -/* - * amdgpu_device_wb_*() - * Writeback is the method by which the GPU updates special pages in memory - * with the status of certain GPU events (fences, ring pointers,etc.). - */ - -/** - * amdgpu_device_wb_fini - Disable Writeback and free memory - * - * @adev: amdgpu_device pointer - * - * Disables Writeback and frees the Writeback memory (all asics). - * Used at driver shutdown. - */ -static void amdgpu_device_wb_fini(struct amdgpu_device *adev) -{ - if (adev->wb.wb_obj) { - amdgpu_bo_free_kernel(&adev->wb.wb_obj, - &adev->wb.gpu_addr, - (void **)&adev->wb.wb); - adev->wb.wb_obj = NULL; - } -} - -/** - * amdgpu_device_wb_init - Init Writeback driver info and allocate memory - * - * @adev: amdgpu_device pointer - * - * Initializes writeback and allocates writeback memory (all asics). - * Used at driver startup. - * Returns 0 on success or an -error on failure. - */ -static int amdgpu_device_wb_init(struct amdgpu_device *adev) -{ - int r; - - if (adev->wb.wb_obj == NULL) { - /* AMDGPU_MAX_WB * sizeof(uint32_t) * 8 = AMDGPU_MAX_WB 256bit slots */ - r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * sizeof(uint32_t) * 8, - PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, - &adev->wb.wb_obj, &adev->wb.gpu_addr, - (void **)&adev->wb.wb); - if (r) { - dev_warn(adev->dev, "(%d) create WB bo failed\n", r); - return r; - } - - adev->wb.num_wb = AMDGPU_MAX_WB; - memset(&adev->wb.used, 0, sizeof(adev->wb.used)); - - /* clear wb memory */ - memset((char *)adev->wb.wb, 0, AMDGPU_MAX_WB * sizeof(uint32_t) * 8); - } - - return 0; -} - -/** - * amdgpu_device_wb_get - Allocate a wb entry - * - * @adev: amdgpu_device pointer - * @wb: wb index - * - * Allocate a wb slot for use by the driver (all asics). - * Returns 0 on success or -EINVAL on failure. - */ -int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb) -{ - unsigned long flags, offset; - - spin_lock_irqsave(&adev->wb.lock, flags); - offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb); - if (offset < adev->wb.num_wb) { - __set_bit(offset, adev->wb.used); - spin_unlock_irqrestore(&adev->wb.lock, flags); - *wb = offset << 3; /* convert to dw offset */ - return 0; - } else { - spin_unlock_irqrestore(&adev->wb.lock, flags); - return -EINVAL; - } -} - -/** - * amdgpu_device_wb_free - Free a wb entry - * - * @adev: amdgpu_device pointer - * @wb: wb index - * - * Free a wb slot allocated for use by the driver (all asics) - */ -void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb) -{ - unsigned long flags; - - wb >>= 3; - spin_lock_irqsave(&adev->wb.lock, flags); - if (wb < adev->wb.num_wb) - __clear_bit(wb, adev->wb.used); - spin_unlock_irqrestore(&adev->wb.lock, flags); -} - /** * amdgpu_device_resize_fb_bar - try to resize FB BAR * @@ -1334,7 +1232,8 @@ static bool amdgpu_device_aspm_support_quirk(struct amdgpu_device *adev) * It's unclear if this is a platform-specific or GPU-specific issue. * Disable ASPM on SI for the time being. */ - if (adev->family == AMDGPU_FAMILY_SI) + if (adev->family == AMDGPU_FAMILY_SI || + (!(adev->pm.pp_feature & PP_PCIE_DPM_MASK) && adev->family == AMDGPU_FAMILY_VI)) return true; #if IS_ENABLED(CONFIG_X86) @@ -2373,10 +2272,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) r); goto init_failed; } - r = amdgpu_device_wb_init(adev); + r = amdgpu_wb_init(adev); if (r) { dev_err(adev->dev, - "amdgpu_device_wb_init failed %d\n", r); + "amdgpu_wb_init failed %d\n", r); goto init_failed; } adev->ip_blocks[i].status.hw = true; @@ -2908,7 +2807,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { amdgpu_ucode_free_bo(adev); amdgpu_free_static_csa(&adev->virt.csa_obj); - amdgpu_device_wb_fini(adev); + amdgpu_wb_fini(adev); amdgpu_device_mem_scratch_fini(adev); amdgpu_ib_pool_fini(adev); amdgpu_seq64_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index a015d55aa158..d9edac5f321d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -2529,6 +2529,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev) amdgpu_device_ip_block_add(adev, &psp_v14_0_ip_block); break; case IP_VERSION(15, 0, 0): + case IP_VERSION(15, 0, 9): amdgpu_device_ip_block_add(adev, &psp_v15_0_ip_block); break; case IP_VERSION(15, 0, 8): @@ -2600,6 +2601,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev) case IP_VERSION(15, 0, 0): case IP_VERSION(15, 0, 5): case IP_VERSION(15, 0, 8): + case IP_VERSION(15, 0, 9): amdgpu_device_ip_block_add(adev, &smu_v15_0_ip_block); break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 96c9d4f00b27..1e275c2e7dd3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -1170,7 +1170,7 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_ BUG_ON(!ring->funcs->emit_rreg); spin_lock_irqsave(&kiq->ring_lock, flags); - if (amdgpu_device_wb_get(adev, ®_val_offs)) { + if (amdgpu_wb_get(adev, ®_val_offs)) { pr_err("critical bug! too many kiq readers\n"); goto failed_unlock; } @@ -1213,7 +1213,7 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_ mb(); value = adev->wb.wb[reg_val_offs]; - amdgpu_device_wb_free(adev, reg_val_offs); + amdgpu_wb_free(adev, reg_val_offs); return value; failed_undo: @@ -1222,7 +1222,7 @@ failed_unlock: spin_unlock_irqrestore(&kiq->ring_lock, flags); failed_kiq_read: if (reg_val_offs) - amdgpu_device_wb_free(adev, reg_val_offs); + amdgpu_wb_free(adev, reg_val_offs); dev_err(adev->dev, "failed to read reg:%x\n", reg); return ~0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index a6419246e9c2..c2a10b41804a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -75,13 +75,13 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, } else { unsigned wptr_offs, rptr_offs; - r = amdgpu_device_wb_get(adev, &wptr_offs); + r = amdgpu_wb_get(adev, &wptr_offs); if (r) return r; - r = amdgpu_device_wb_get(adev, &rptr_offs); + r = amdgpu_wb_get(adev, &rptr_offs); if (r) { - amdgpu_device_wb_free(adev, wptr_offs); + amdgpu_wb_free(adev, wptr_offs); return r; } @@ -90,8 +90,8 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, &ih->ring_obj, &ih->gpu_addr, (void **)&ih->ring); if (r) { - amdgpu_device_wb_free(adev, rptr_offs); - amdgpu_device_wb_free(adev, wptr_offs); + amdgpu_wb_free(adev, rptr_offs); + amdgpu_wb_free(adev, wptr_offs); return r; } @@ -131,8 +131,8 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) } else { amdgpu_bo_free_kernel(&ih->ring_obj, &ih->gpu_addr, (void **)&ih->ring); - amdgpu_device_wb_free(adev, (ih->wptr_addr - ih->gpu_addr) / 4); - amdgpu_device_wb_free(adev, (ih->rptr_addr - ih->gpu_addr) / 4); + amdgpu_wb_free(adev, (ih->wptr_addr - ih->gpu_addr) / 4); + amdgpu_wb_free(adev, (ih->rptr_addr - ih->gpu_addr) / 4); } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 215aa678d1d0..287ede40cd91 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -46,6 +46,7 @@ #include "amdgpu_reset.h" #include "amd_pcie.h" #include "amdgpu_userq.h" +#include "amdgpu_video_codecs.h" void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h index 6d12f8a516d5..8ad47c5ab022 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h @@ -26,7 +26,6 @@ enum amdgpu_mca_error_type { AMDGPU_MCA_ERROR_TYPE_UE = 0, AMDGPU_MCA_ERROR_TYPE_CE, - AMDGPU_MCA_ERROR_TYPE_DE, }; struct amdgpu_mca_ras_block { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 6c0dde3786e3..c66e69b62361 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -183,7 +183,7 @@ int amdgpu_mes_init(struct amdgpu_device *adev) adev->mes.sdma_hqd_mask[0]); for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++) { - r = amdgpu_device_wb_get(adev, &adev->mes.sch_ctx_offs[i]); + r = amdgpu_wb_get(adev, &adev->mes.sch_ctx_offs[i]); if (r) { dev_err(adev->dev, "(%d) ring trail_fence_offs wb alloc failed\n", @@ -195,7 +195,7 @@ int amdgpu_mes_init(struct amdgpu_device *adev) adev->mes.sch_ctx_ptr[i] = (uint64_t *)&adev->wb.wb[adev->mes.sch_ctx_offs[i]]; - r = amdgpu_device_wb_get(adev, + r = amdgpu_wb_get(adev, &adev->mes.query_status_fence_offs[i]); if (r) { dev_err(adev->dev, @@ -237,7 +237,7 @@ int amdgpu_mes_init(struct amdgpu_device *adev) } if (adev->mes.hung_queue_db_array_size) { - for (i = 0; i < AMDGPU_MAX_MES_PIPES; i++) { + for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++) { r = amdgpu_bo_create_kernel(adev, adev->mes.hung_queue_db_array_size * sizeof(u32), PAGE_SIZE, @@ -250,11 +250,16 @@ int amdgpu_mes_init(struct amdgpu_device *adev) goto error_doorbell; } } - } - adev->gfx.mec.mes_hung_db_array = - kcalloc(amdgpu_mes_get_hung_queue_db_array_size(adev), - sizeof(u32), GFP_KERNEL); + adev->gfx.mec.mes_hung_db_array = + kcalloc(amdgpu_mes_get_hung_queue_db_array_size(adev), + sizeof(u32), GFP_KERNEL); + + if (!adev->gfx.mec.mes_hung_db_array) { + r = -ENOMEM; + goto error_doorbell; + } + } return 0; @@ -263,9 +268,9 @@ error_doorbell: error: for (i = 0; i < AMDGPU_MAX_MES_PIPES * num_xcc; i++) { if (adev->mes.sch_ctx_ptr[i]) - amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs[i]); + amdgpu_wb_free(adev, adev->mes.sch_ctx_offs[i]); if (adev->mes.query_status_fence_ptr[i]) - amdgpu_device_wb_free(adev, + amdgpu_wb_free(adev, adev->mes.query_status_fence_offs[i]); if (adev->mes.hung_queue_db_array_gpu_obj[i]) amdgpu_bo_free_kernel(&adev->mes.hung_queue_db_array_gpu_obj[i], @@ -295,9 +300,9 @@ void amdgpu_mes_fini(struct amdgpu_device *adev) &adev->mes.hung_queue_db_array_gpu_addr[i], &adev->mes.hung_queue_db_array_cpu_addr[i]); if (adev->mes.sch_ctx_ptr[i]) - amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs[i]); + amdgpu_wb_free(adev, adev->mes.sch_ctx_offs[i]); if (adev->mes.query_status_fence_ptr[i]) - amdgpu_device_wb_free(adev, + amdgpu_wb_free(adev, adev->mes.query_status_fence_offs[i]); } @@ -567,7 +572,7 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg, uint64_t read_val_gpu_addr; uint32_t *read_val_ptr; - if (amdgpu_device_wb_get(adev, &addr_offset)) { + if (amdgpu_wb_get(adev, &addr_offset)) { dev_err(adev->dev, "critical bug! too many mes readers\n"); goto error; } @@ -593,7 +598,7 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg, error: if (addr_offset) - amdgpu_device_wb_free(adev, addr_offset); + amdgpu_wb_free(adev, addr_offset); return val; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h index f25cffad8efe..389e3324caea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -441,6 +441,52 @@ struct amdgpu_mes_funcs { struct mes_inv_tlbs_pasid_input *input); }; +enum amdgpu_mqd_update_flag { + AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE = 1, + AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE = 2, + AMDGPU_UPDATE_FLAG_IS_GWS = 4, /* quirk for gfx9 IP */ +}; + +struct amdgpu_mqd_prop { + uint64_t mqd_gpu_addr; + uint64_t hqd_base_gpu_addr; + uint64_t rptr_gpu_addr; + uint64_t wptr_gpu_addr; + uint32_t queue_size; + bool use_doorbell; + uint32_t doorbell_index; + uint64_t eop_gpu_addr; + uint32_t hqd_pipe_priority; + uint32_t hqd_queue_priority; + uint32_t mqd_stride_size; + bool allow_tunneling; + bool hqd_active; + uint64_t shadow_addr; + uint64_t gds_bkup_addr; + uint64_t csa_addr; + uint64_t fence_address; + bool tmz_queue; + bool kernel_queue; + uint32_t *cu_mask; + uint32_t cu_mask_count; + uint32_t cu_flags; + bool is_user_cu_masked; +}; + +struct amdgpu_mqd { + unsigned mqd_size; + int (*init_mqd)(struct amdgpu_device *adev, void *mqd, + struct amdgpu_mqd_prop *p); +}; + +/* + * MES FW uses address(mqd_addr + sizeof(struct mqd) + 3*sizeof(uint32_t)) + * as fence address and writes a 32 bit fence value to this address. + * Driver needs to allocate at least 4 DWs extra memory in addition to + * sizeof(struct mqd). Add 8 DWs and align to AMDGPU_GPU_PAGE_SIZE for safety. + */ +#define AMDGPU_MQD_SIZE_ALIGN(mqd_size) AMDGPU_GPU_PAGE_ALIGN(((mqd_size) + 32)) + #define amdgpu_mes_kiq_hw_init(adev, xcc_id) \ (adev)->mes.kiq_hw_init((adev), (xcc_id)) #define amdgpu_mes_kiq_hw_fini(adev, xcc_id) \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 96e1b72b9e1c..e0c0d7872e45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -275,6 +275,7 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block) psp->boot_time_tmr = false; break; case IP_VERSION(15, 0, 0): + case IP_VERSION(15, 0, 9): psp_v15_0_0_set_psp_funcs(psp); psp->boot_time_tmr = false; break; @@ -3475,7 +3476,9 @@ static int psp_load_non_psp_fw(struct psp_context *psp) amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 0) || amdgpu_ip_version(adev, MP0_HWIP, 0) == - IP_VERSION(15, 0, 8)) && + IP_VERSION(15, 0, 8) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == + IP_VERSION(15, 0, 9)) && (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 148bb4cb0a2d..fd2c0cc1b958 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1137,8 +1137,7 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev, struct ras_err_data *err_data, struct ras_query_context *qctx, const char *blk_name, - bool is_ue, - bool is_de) + bool is_ue) { struct amdgpu_smuio_mcm_config_info *mcm_info; struct ras_err_node *err_node; @@ -1168,53 +1167,29 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev, } } else { - if (is_de) { - for_each_ras_error(err_node, err_data) { - err_info = &err_node->err_info; - mcm_info = &err_info->mcm_info; - if (err_info->de_count) { - RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, " - "%lld new deferred hardware errors detected in %s block\n", - mcm_info->socket_id, - mcm_info->die_id, - err_info->de_count, - blk_name); - } - } + if (adev->debug_disable_ce_logs) + return; - for_each_ras_error(err_node, &ras_mgr->err_data) { - err_info = &err_node->err_info; - mcm_info = &err_info->mcm_info; + for_each_ras_error(err_node, err_data) { + err_info = &err_node->err_info; + mcm_info = &err_info->mcm_info; + if (err_info->ce_count) { RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, " - "%lld deferred hardware errors detected in total in %s block\n", - mcm_info->socket_id, mcm_info->die_id, - err_info->de_count, blk_name); - } - } else { - if (adev->debug_disable_ce_logs) - return; - - for_each_ras_error(err_node, err_data) { - err_info = &err_node->err_info; - mcm_info = &err_info->mcm_info; - if (err_info->ce_count) { - RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, " - "%lld new correctable hardware errors detected in %s block\n", - mcm_info->socket_id, - mcm_info->die_id, - err_info->ce_count, - blk_name); - } + "%lld new correctable hardware errors detected in %s block\n", + mcm_info->socket_id, + mcm_info->die_id, + err_info->ce_count, + blk_name); } + } - for_each_ras_error(err_node, &ras_mgr->err_data) { - err_info = &err_node->err_info; - mcm_info = &err_info->mcm_info; - RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, " - "%lld correctable hardware errors detected in total in %s block\n", - mcm_info->socket_id, mcm_info->die_id, - err_info->ce_count, blk_name); - } + for_each_ras_error(err_node, &ras_mgr->err_data) { + err_info = &err_node->err_info; + mcm_info = &err_info->mcm_info; + RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d, " + "%lld correctable hardware errors detected in total in %s block\n", + mcm_info->socket_id, mcm_info->die_id, + err_info->ce_count, blk_name); } } } @@ -1235,8 +1210,7 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev, if (err_data->ce_count) { if (err_data_has_source_info(err_data)) { - amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx, - blk_name, false, false); + amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx, blk_name, false); } else if (!adev->aid_mask && adev->smuio.funcs && adev->smuio.funcs->get_socket_id && @@ -1258,8 +1232,7 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev, if (err_data->ue_count) { if (err_data_has_source_info(err_data)) { - amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx, - blk_name, true, false); + amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx, blk_name, true); } else if (!adev->aid_mask && adev->smuio.funcs && adev->smuio.funcs->get_socket_id && @@ -1278,29 +1251,6 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev, blk_name); } } - - if (err_data->de_count) { - if (err_data_has_source_info(err_data)) { - amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, qctx, - blk_name, false, true); - } else if (!adev->aid_mask && - adev->smuio.funcs && - adev->smuio.funcs->get_socket_id && - adev->smuio.funcs->get_die_id) { - RAS_EVENT_LOG(adev, event_id, "socket: %d, die: %d " - "%ld deferred hardware errors " - "detected in %s block\n", - adev->smuio.funcs->get_socket_id(adev), - adev->smuio.funcs->get_die_id(adev), - ras_mgr->err_data.de_count, - blk_name); - } else { - RAS_EVENT_LOG(adev, event_id, "%ld deferred hardware errors " - "detected in %s block\n", - ras_mgr->err_data.de_count, - blk_name); - } - } } static void amdgpu_ras_virt_error_generate_report(struct amdgpu_device *adev, @@ -1347,8 +1297,7 @@ static void amdgpu_rasmgr_error_data_statistic_update(struct ras_manager *obj, s if (err_data_has_source_info(err_data)) { for_each_ras_error(err_node, err_data) { err_info = &err_node->err_info; - amdgpu_ras_error_statistic_de_count(&obj->err_data, - &err_info->mcm_info, err_info->de_count); + amdgpu_ras_error_statistic_ce_count(&obj->err_data, &err_info->mcm_info, err_info->ce_count); amdgpu_ras_error_statistic_ue_count(&obj->err_data, @@ -1358,7 +1307,6 @@ static void amdgpu_rasmgr_error_data_statistic_update(struct ras_manager *obj, s /* for legacy asic path which doesn't has error source info */ obj->err_data.ue_count += err_data->ue_count; obj->err_data.ce_count += err_data->ce_count; - obj->err_data.de_count += err_data->de_count; } } @@ -1466,7 +1414,6 @@ static int amdgpu_ras_query_error_status_with_event(struct amdgpu_device *adev, info->ue_count = obj->err_data.ue_count; info->ce_count = obj->err_data.ce_count; - info->de_count = obj->err_data.de_count; out_fini_err_data: amdgpu_ras_error_data_fini(&err_data); @@ -2385,7 +2332,6 @@ static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj, */ obj->err_data.ue_count += err_data.ue_count; obj->err_data.ce_count += err_data.ce_count; - obj->err_data.de_count += err_data.de_count; } amdgpu_ras_error_data_fini(&err_data); @@ -3205,15 +3151,10 @@ int amdgpu_ras_init_badpage_info(struct amdgpu_device *adev) return 0; control = &con->eeprom_control; - con->ras_smu_drv = amdgpu_dpm_get_ras_smu_driver(adev); ret = amdgpu_ras_eeprom_init(control); control->is_eeprom_valid = !ret; - if (adev->umc.ras && - adev->umc.ras->get_retire_flip_bits) - adev->umc.ras->get_retire_flip_bits(adev); - if (control->ras_num_recs && control->is_eeprom_valid) { ret = amdgpu_ras_load_bad_pages(adev); if (ret) { @@ -4778,28 +4719,6 @@ int amdgpu_ras_error_statistic_ce_count(struct ras_err_data *err_data, return 0; } -int amdgpu_ras_error_statistic_de_count(struct ras_err_data *err_data, - struct amdgpu_smuio_mcm_config_info *mcm_info, - u64 count) -{ - struct ras_err_info *err_info; - - if (!err_data || !mcm_info) - return -EINVAL; - - if (!count) - return 0; - - err_info = amdgpu_ras_error_get_info(err_data, mcm_info); - if (!err_info) - return -EINVAL; - - err_info->de_count += count; - err_data->de_count += count; - - return 0; -} - #define mmMP0_SMN_C2PMSG_92 0x1609C #define mmMP0_SMN_C2PMSG_126 0x160BE static void amdgpu_ras_boot_time_error_reporting(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h index a44aed7f169e..23bff7a0f35b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h @@ -492,32 +492,6 @@ struct ras_critical_region { uint64_t size; }; -struct ras_eeprom_table_version { - uint32_t minor : 16; - uint32_t major : 16; -}; - -struct ras_eeprom_smu_funcs { - int (*get_ras_table_version)(struct amdgpu_device *adev, - uint32_t *table_version); - int (*get_badpage_count)(struct amdgpu_device *adev, uint32_t *count, uint32_t timeout); - int (*get_badpage_mca_addr)(struct amdgpu_device *adev, uint16_t index, uint64_t *mca_addr); - int (*set_timestamp)(struct amdgpu_device *adev, uint64_t timestamp); - int (*get_timestamp)(struct amdgpu_device *adev, - uint16_t index, uint64_t *timestamp); - int (*get_badpage_ipid)(struct amdgpu_device *adev, uint16_t index, uint64_t *ipid); - int (*erase_ras_table)(struct amdgpu_device *adev, uint32_t *result); -}; - -enum ras_smu_feature_flags { - RAS_SMU_FEATURE_BIT__RAS_EEPROM = BIT_ULL(0), -}; - -struct ras_smu_drv { - const struct ras_eeprom_smu_funcs *smu_eeprom_funcs; - void (*ras_smu_feature_flags)(struct amdgpu_device *adev, uint64_t *flags); -}; - struct amdgpu_ras { void *ras_mgr; /* ras infrastructure */ @@ -598,7 +572,6 @@ struct amdgpu_ras { /* Disable/Enable uniras switch */ bool uniras_enabled; - const struct ras_smu_drv *ras_smu_drv; }; struct ras_fs_data { @@ -977,9 +950,6 @@ int amdgpu_ras_error_statistic_ce_count(struct ras_err_data *err_data, int amdgpu_ras_error_statistic_ue_count(struct ras_err_data *err_data, struct amdgpu_smuio_mcm_config_info *mcm_info, u64 count); -int amdgpu_ras_error_statistic_de_count(struct ras_err_data *err_data, - struct amdgpu_smuio_mcm_config_info *mcm_info, - u64 count); void amdgpu_ras_query_boot_status(struct amdgpu_device *adev, u32 num_instances); void amdgpu_ras_set_fed(struct amdgpu_device *adev, bool status); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index baa8cc3646d5..95468b9463fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -1156,10 +1156,6 @@ static ssize_t amdgpu_ras_debugfs_table_read(struct file *f, char __user *buf, int res = -EFAULT; size_t data_len; - /* pmfw manages eeprom data by itself */ - if (amdgpu_ras_smu_eeprom_supported(adev)) - return 0; - mutex_lock(&control->ras_tbl_mutex); /* We want *pos - data_len > 0, which means there's @@ -1676,8 +1672,7 @@ void amdgpu_ras_eeprom_check_and_recover(struct amdgpu_device *adev) struct amdgpu_ras_eeprom_control *control; int res; - if (!__is_ras_eeprom_supported(adev) || !ras || - amdgpu_ras_smu_eeprom_supported(adev)) + if (!__is_ras_eeprom_supported(adev) || !ras) return; control = &ras->eeprom_control; if (!control->is_eeprom_valid) @@ -1699,145 +1694,6 @@ void amdgpu_ras_eeprom_check_and_recover(struct amdgpu_device *adev) return; } -static const struct ras_smu_drv *amdgpu_ras_get_smu_ras_drv(struct amdgpu_device *adev) -{ - struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); - - if (!ras) - return NULL; - - return ras->ras_smu_drv; -} - -static uint64_t amdgpu_ras_smu_get_feature_flags(struct amdgpu_device *adev) -{ - const struct ras_smu_drv *ras_smu_drv = amdgpu_ras_get_smu_ras_drv(adev); - uint64_t flags = 0ULL; - - if (!ras_smu_drv) - goto out; - - if (ras_smu_drv->ras_smu_feature_flags) - ras_smu_drv->ras_smu_feature_flags(adev, &flags); - -out: - return flags; -} - -bool amdgpu_ras_smu_eeprom_supported(struct amdgpu_device *adev) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - uint64_t flags = 0ULL; - - if (!__is_ras_eeprom_supported(adev) || !smu_ras_drv) - return false; - - if (!smu_ras_drv->smu_eeprom_funcs) - return false; - - flags = amdgpu_ras_smu_get_feature_flags(adev); - - return !!(flags & RAS_SMU_FEATURE_BIT__RAS_EEPROM); -} - -int amdgpu_ras_smu_get_table_version(struct amdgpu_device *adev, - uint32_t *table_version) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - - if (!amdgpu_ras_smu_eeprom_supported(adev)) - return -EOPNOTSUPP; - - if (smu_ras_drv->smu_eeprom_funcs->get_ras_table_version) - return smu_ras_drv->smu_eeprom_funcs->get_ras_table_version(adev, - table_version); - return -EOPNOTSUPP; -} - -int amdgpu_ras_smu_get_badpage_count(struct amdgpu_device *adev, - uint32_t *count, uint32_t timeout) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - - if (!amdgpu_ras_smu_eeprom_supported(adev)) - return -EOPNOTSUPP; - - if (smu_ras_drv->smu_eeprom_funcs->get_badpage_count) - return smu_ras_drv->smu_eeprom_funcs->get_badpage_count(adev, - count, timeout); - return -EOPNOTSUPP; -} - -int amdgpu_ras_smu_get_badpage_mca_addr(struct amdgpu_device *adev, - uint16_t index, uint64_t *mca_addr) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - - if (!amdgpu_ras_smu_eeprom_supported(adev)) - return -EOPNOTSUPP; - - if (smu_ras_drv->smu_eeprom_funcs->get_badpage_mca_addr) - return smu_ras_drv->smu_eeprom_funcs->get_badpage_mca_addr(adev, - index, mca_addr); - return -EOPNOTSUPP; -} - -int amdgpu_ras_smu_set_timestamp(struct amdgpu_device *adev, - uint64_t timestamp) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - - if (!amdgpu_ras_smu_eeprom_supported(adev)) - return -EOPNOTSUPP; - - if (smu_ras_drv->smu_eeprom_funcs->set_timestamp) - return smu_ras_drv->smu_eeprom_funcs->set_timestamp(adev, - timestamp); - return -EOPNOTSUPP; -} - -int amdgpu_ras_smu_get_timestamp(struct amdgpu_device *adev, - uint16_t index, uint64_t *timestamp) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - - if (!amdgpu_ras_smu_eeprom_supported(adev)) - return -EOPNOTSUPP; - - if (smu_ras_drv->smu_eeprom_funcs->get_timestamp) - return smu_ras_drv->smu_eeprom_funcs->get_timestamp(adev, - index, timestamp); - return -EOPNOTSUPP; -} - -int amdgpu_ras_smu_get_badpage_ipid(struct amdgpu_device *adev, - uint16_t index, uint64_t *ipid) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - - if (!amdgpu_ras_smu_eeprom_supported(adev)) - return -EOPNOTSUPP; - - if (smu_ras_drv->smu_eeprom_funcs->get_badpage_ipid) - return smu_ras_drv->smu_eeprom_funcs->get_badpage_ipid(adev, - index, ipid); - return -EOPNOTSUPP; -} - -int amdgpu_ras_smu_erase_ras_table(struct amdgpu_device *adev, - uint32_t *result) -{ - const struct ras_smu_drv *smu_ras_drv = amdgpu_ras_get_smu_ras_drv(adev); - - if (!amdgpu_ras_smu_eeprom_supported(adev)) - return -EOPNOTSUPP; - - if (smu_ras_drv->smu_eeprom_funcs->erase_ras_table) - return smu_ras_drv->smu_eeprom_funcs->erase_ras_table(adev, - result); - return -EOPNOTSUPP; -} - void amdgpu_ras_check_bad_page_status(struct amdgpu_device *adev) { struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h index 3c7fcce5fe8b..6e50b9f0569d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h @@ -163,29 +163,6 @@ int amdgpu_ras_eeprom_check(struct amdgpu_ras_eeprom_control *control); void amdgpu_ras_eeprom_check_and_recover(struct amdgpu_device *adev); -bool amdgpu_ras_smu_eeprom_supported(struct amdgpu_device *adev); - -int amdgpu_ras_smu_get_table_version(struct amdgpu_device *adev, - uint32_t *table_version); - -int amdgpu_ras_smu_get_badpage_count(struct amdgpu_device *adev, - uint32_t *count, uint32_t timeout); - -int amdgpu_ras_smu_get_badpage_mca_addr(struct amdgpu_device *adev, - uint16_t index, uint64_t *mca_addr); - -int amdgpu_ras_smu_set_timestamp(struct amdgpu_device *adev, - uint64_t timestamp); - -int amdgpu_ras_smu_get_timestamp(struct amdgpu_device *adev, - uint16_t index, uint64_t *timestamp); - -int amdgpu_ras_smu_get_badpage_ipid(struct amdgpu_device *adev, - uint16_t index, uint64_t *ipid); - -int amdgpu_ras_smu_erase_ras_table(struct amdgpu_device *adev, - uint32_t *result); - int amdgpu_ras_eeprom_read_idx(struct amdgpu_ras_eeprom_control *control, struct eeprom_table_record *record, u32 rec_idx, const u32 num); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h index a1011af6b52b..320c30ce4a62 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h @@ -89,6 +89,14 @@ struct amdgpu_reg_access { struct amdgpu_reg_smn_ext smn; }; +/* + * ASIC specific register table accessible by UMD + */ +struct amdgpu_allowed_register_entry { + uint32_t reg_offset; + bool grbm_indexed; +}; + void amdgpu_reg_access_init(struct amdgpu_device *adev); uint32_t amdgpu_reg_smc_rd32(struct amdgpu_device *adev, uint32_t reg); void amdgpu_reg_smc_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 4d417c4a5cd2..0d34f0eca991 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -264,31 +264,31 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, return r; } - r = amdgpu_device_wb_get(adev, &ring->rptr_offs); + r = amdgpu_wb_get(adev, &ring->rptr_offs); if (r) { dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r); return r; } - r = amdgpu_device_wb_get(adev, &ring->wptr_offs); + r = amdgpu_wb_get(adev, &ring->wptr_offs); if (r) { dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r); return r; } - r = amdgpu_device_wb_get(adev, &ring->fence_offs); + r = amdgpu_wb_get(adev, &ring->fence_offs); if (r) { dev_err(adev->dev, "(%d) ring fence_offs wb alloc failed\n", r); return r; } - r = amdgpu_device_wb_get(adev, &ring->trail_fence_offs); + r = amdgpu_wb_get(adev, &ring->trail_fence_offs); if (r) { dev_err(adev->dev, "(%d) ring trail_fence_offs wb alloc failed\n", r); return r; } - r = amdgpu_device_wb_get(adev, &ring->cond_exe_offs); + r = amdgpu_wb_get(adev, &ring->cond_exe_offs); if (r) { dev_err(adev->dev, "(%d) ring cond_exec_polling wb alloc failed\n", r); return r; @@ -401,11 +401,11 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) ring->sched.ready = false; - amdgpu_device_wb_free(ring->adev, ring->rptr_offs); - amdgpu_device_wb_free(ring->adev, ring->wptr_offs); + amdgpu_wb_free(ring->adev, ring->rptr_offs); + amdgpu_wb_free(ring->adev, ring->wptr_offs); - amdgpu_device_wb_free(ring->adev, ring->cond_exe_offs); - amdgpu_device_wb_free(ring->adev, ring->fence_offs); + amdgpu_wb_free(ring->adev, ring->cond_exe_offs); + amdgpu_wb_free(ring->adev, ring->fence_offs); amdgpu_bo_free_kernel(&ring->ring_obj, &ring->gpu_addr, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 6d9e96fabd58..4f1c711df5bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -1478,7 +1478,8 @@ void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, ip_name = "isp"; break; default: - BUG(); + WARN(1, "invalid HWIP %d\n", block_type); + return; } maj = IP_VERSION_MAJ(version); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c index 2a5f5e6188bb..a98a6cfd4fba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c @@ -186,7 +186,7 @@ void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev, if ((amdgpu_bad_page_threshold != 0) && err_data->err_addr_cnt) { amdgpu_ras_add_bad_pages(adev, err_data->err_addr, - err_data->err_addr_cnt, amdgpu_ras_smu_eeprom_supported(adev)); + err_data->err_addr_cnt, false); amdgpu_ras_save_bad_pages(adev, &err_count); amdgpu_dpm_send_hbm_bad_pages_num(adev, @@ -260,7 +260,6 @@ int amdgpu_umc_pasid_poison_handler(struct amdgpu_device *adev, if (ret == AMDGPU_RAS_SUCCESS && obj) { obj->err_data.ue_count += err_data.ue_count; obj->err_data.ce_count += err_data.ce_count; - obj->err_data.de_count += err_data.de_count; } amdgpu_ras_error_data_fini(&err_data); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h index cf06d5f856f9..b2a3db60d231 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h @@ -21,7 +21,6 @@ #ifndef __AMDGPU_UMC_H__ #define __AMDGPU_UMC_H__ #include "amdgpu_ras.h" -#include "amdgpu_mca.h" /* * (addr / 256) * 4096, the higher 26 bits in ErrorAddr * is the index of 4KB block @@ -78,18 +77,6 @@ #define UMC_NPS_SHIFT 40 #define UMC_NPS_MASK 0xffULL -/* three column bits and one row bit in MCA address flip - * in bad page retirement - */ -#define RETIRE_FLIP_BITS_NUM 4 - -struct amdgpu_umc_flip_bits { - uint32_t flip_bits_in_pa[RETIRE_FLIP_BITS_NUM]; - uint32_t flip_row_bit; - uint32_t r13_in_pa; - uint32_t bit_num; -}; - typedef int (*umc_func)(struct amdgpu_device *adev, uint32_t node_inst, uint32_t umc_inst, uint32_t ch_inst, void *data); @@ -101,9 +88,6 @@ struct amdgpu_umc_ras { void *ras_error_status); void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev, void *ras_error_status); - bool (*check_ecc_err_status)(struct amdgpu_device *adev, - enum amdgpu_mca_error_type type, void *ras_error_status); - void (*get_retire_flip_bits)(struct amdgpu_device *adev); }; struct amdgpu_umc_funcs { @@ -135,8 +119,6 @@ struct amdgpu_umc { /* active mask for umc node instance */ unsigned long active_mask; - struct amdgpu_umc_flip_bits flip_bits; - unsigned long err_addr_cnt; }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c index cd707d70a0bf..3985d56008cd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c @@ -272,7 +272,7 @@ static int umsch_mm_init(struct amdgpu_device *adev) adev->umsch_mm.engine_mask = (1 << UMSCH_SWIP_ENGINE_TYPE_VPE); adev->umsch_mm.vpe_hqd_mask = 0xfe; - r = amdgpu_device_wb_get(adev, &adev->umsch_mm.wb_index); + r = amdgpu_wb_get(adev, &adev->umsch_mm.wb_index); if (r) { dev_err(adev->dev, "failed to alloc wb for umsch: %d\n", r); return r; @@ -288,7 +288,7 @@ static int umsch_mm_init(struct amdgpu_device *adev) (void **)&adev->umsch_mm.cmd_buf_ptr); if (r) { dev_err(adev->dev, "failed to allocate cmdbuf bo %d\n", r); - amdgpu_device_wb_free(adev, adev->umsch_mm.wb_index); + amdgpu_wb_free(adev, adev->umsch_mm.wb_index); return r; } @@ -380,7 +380,7 @@ static int umsch_mm_sw_fini(struct amdgpu_ip_block *ip_block) &adev->umsch_mm.log_gpu_addr, (void **)&adev->umsch_mm.log_cpu_addr); - amdgpu_device_wb_free(adev, adev->umsch_mm.wb_index); + amdgpu_wb_free(adev, adev->umsch_mm.wb_index); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 82c8809d1d9c..9cc71a3a5362 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -540,6 +540,15 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_que amdgpu_userq_cleanup(queue); mutex_unlock(&uq_mgr->userq_mutex); + /* + * A failed unmap means MES could not remove the hung queue and is now + * unresponsive. Recover the GPU here so the wedged MES does not fail + * the next, unrelated queue submission and trigger a reset attributed + * to an innocent workload. + */ + if (r) + queue_work(adev->reset_domain->wq, &uq_mgr->reset_work); + cancel_delayed_work_sync(&queue->hang_detect_work); uq_funcs->mqd_destroy(queue); queue->userq_mgr = NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_video_codecs.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_video_codecs.h new file mode 100644 index 000000000000..3b2a6cb8632d --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_video_codecs.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT + * + * Copyright 2026 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __AMDGPU_VIDEO_CODECS_H__ +#define __AMDGPU_VIDEO_CODECS_H__ + +#include <linux/types.h> + +#define codec_info_build(type, width, height, level) \ + .codec_type = type,\ + .max_width = width,\ + .max_height = height,\ + .max_pixels_per_frame = height * width,\ + .max_level = level, + +struct amdgpu_video_codec_info { + u32 codec_type; + u32 max_width; + u32 max_height; + u32 max_pixels_per_frame; + u32 max_level; +}; + +struct amdgpu_video_codecs { + const u32 codec_count; + const struct amdgpu_video_codec_info *codec_array; +}; +#endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 9e8f7d2b898c..8f4b86063507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -34,6 +34,7 @@ #include "amdgpu_ras.h" #include "amdgpu_reset.h" #include "amdgpu_dpm.h" +#include "amdgpu_video_codecs.h" #include "vi.h" #include "soc15.h" #include "nv.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index f317f888b59f..f1dcf4f5bb78 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2460,19 +2460,6 @@ static void amdgpu_vm_destroy_task_info(struct kref *kref) kfree(ti); } -static inline struct amdgpu_vm * -amdgpu_vm_get_vm_from_pasid(struct amdgpu_device *adev, u32 pasid) -{ - struct amdgpu_vm *vm; - unsigned long flags; - - xa_lock_irqsave(&adev->vm_manager.pasids, flags); - vm = xa_load(&adev->vm_manager.pasids, pasid); - xa_unlock_irqrestore(&adev->vm_manager.pasids, flags); - - return vm; -} - /** * amdgpu_vm_put_task_info - reference down the vm task_info ptr * @@ -2519,8 +2506,16 @@ amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm) struct amdgpu_task_info * amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid) { - return amdgpu_vm_get_task_info_vm( - amdgpu_vm_get_vm_from_pasid(adev, pasid)); + struct amdgpu_task_info *ti; + struct amdgpu_vm *vm; + unsigned long flags; + + xa_lock_irqsave(&adev->vm_manager.pasids, flags); + vm = xa_load(&adev->vm_manager.pasids, pasid); + ti = amdgpu_vm_get_task_info_vm(vm); + xa_unlock_irqrestore(&adev->vm_manager.pasids, flags); + + return ti; } static int amdgpu_vm_create_task_info(struct amdgpu_vm *vm) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c index 7bf74ff93fbd..2b45010b7ebe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c @@ -789,7 +789,7 @@ static int vpe_ring_test_ring(struct amdgpu_ring *ring) uint64_t wb_addr; int ret; - ret = amdgpu_device_wb_get(adev, &index); + ret = amdgpu_wb_get(adev, &index); if (ret) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", ret); return ret; @@ -818,7 +818,7 @@ static int vpe_ring_test_ring(struct amdgpu_ring *ring) ret = -ETIMEDOUT; out: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return ret; } @@ -833,7 +833,7 @@ static int vpe_ring_test_ib(struct amdgpu_ring *ring, long timeout) uint64_t wb_addr; int ret; - ret = amdgpu_device_wb_get(adev, &index); + ret = amdgpu_wb_get(adev, &index); if (ret) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", ret); return ret; @@ -872,7 +872,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c new file mode 100644 index 000000000000..8b7061c94ccd --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright 2026 Advanced Micro Devices, Inc. + + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <linux/spinlock.h> + +#include "amdgpu.h" +#include "amdgpu_wb.h" + +/* + * amdgpu_wb_*() + * Writeback is the method by which the GPU updates special pages in memory + * with the status of certain GPU events (fences, ring pointers,etc.). + */ + +/** + * amdgpu_wb_fini - Disable Writeback and free memory + * + * @adev: amdgpu_device pointer + * + * Disables Writeback and frees the Writeback memory (all asics). + * Used at driver shutdown. + */ +void amdgpu_wb_fini(struct amdgpu_device *adev) +{ + if (adev->wb.wb_obj) { + amdgpu_bo_free_kernel(&adev->wb.wb_obj, + &adev->wb.gpu_addr, + (void **)&adev->wb.wb); + adev->wb.wb_obj = NULL; + } +} + +/** + * amdgpu_wb_init - Init Writeback driver info and allocate memory + * + * @adev: amdgpu_device pointer + * + * Initializes writeback and allocates writeback memory (all asics). + * Used at driver startup. + * Returns 0 on success or an -error on failure. + */ +int amdgpu_wb_init(struct amdgpu_device *adev) +{ + int r; + + if (adev->wb.wb_obj == NULL) { + /* AMDGPU_MAX_WB * sizeof(uint32_t) * 8 = AMDGPU_MAX_WB 256bit slots */ + r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * sizeof(uint32_t) * 8, + PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, + &adev->wb.wb_obj, &adev->wb.gpu_addr, + (void **)&adev->wb.wb); + if (r) { + dev_warn(adev->dev, "(%d) create WB bo failed\n", r); + return r; + } + + adev->wb.num_wb = AMDGPU_MAX_WB; + memset(&adev->wb.used, 0, sizeof(adev->wb.used)); + + /* clear wb memory */ + memset((char *)adev->wb.wb, 0, AMDGPU_MAX_WB * sizeof(uint32_t) * 8); + } + + return 0; +} + +/** + * amdgpu_wb_get - Allocate a wb entry + * + * @adev: amdgpu_device pointer + * @wb: wb index + * + * Allocate a wb slot for use by the driver (all asics). + * Returns 0 on success or -EINVAL on failure. + */ +int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb) +{ + unsigned long flags, offset; + + spin_lock_irqsave(&adev->wb.lock, flags); + offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb); + if (offset < adev->wb.num_wb) { + __set_bit(offset, adev->wb.used); + spin_unlock_irqrestore(&adev->wb.lock, flags); + *wb = offset << 3; /* convert to dw offset */ + return 0; + } else { + spin_unlock_irqrestore(&adev->wb.lock, flags); + return -EINVAL; + } +} + +/** + * amdgpu_wb_free - Free a wb entry + * + * @adev: amdgpu_device pointer + * @wb: wb index + * + * Free a wb slot allocated for use by the driver (all asics) + */ +void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb) +{ + unsigned long flags; + + wb >>= 3; + spin_lock_irqsave(&adev->wb.lock, flags); + if (wb < adev->wb.num_wb) + __clear_bit(wb, adev->wb.used); + spin_unlock_irqrestore(&adev->wb.lock, flags); +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h new file mode 100644 index 000000000000..7b8efa6a639c --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT + * + * Copyright 2026 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __AMDGPU_WB_H__ +#define __AMDGPU_WB_H__ + +#include <linux/types.h> +#include <linux/spinlock_types.h> +#include <linux/math.h> + +/* + * Writeback + */ +#define AMDGPU_MAX_WB 1024 /* Reserve at most 1024 WB slots for amdgpu-owned rings. */ + +/** + * struct amdgpu_wb - This struct is used for small GPU memory allocation. + * + * This struct is used to allocate a small amount of GPU memory that can be + * used to shadow certain states into the memory. This is especially useful for + * providing easy CPU access to some states without requiring register access + * (e.g., if some block is power gated, reading register may be problematic). + * + * Note: the term writeback was initially used because many of the amdgpu + * components had some level of writeback memory, and this struct initially + * described those components. + */ + +struct amdgpu_bo; +struct amdgpu_device; + +struct amdgpu_wb { + + /** + * @wb_obj: + * + * Buffer Object used for the writeback memory. + */ + struct amdgpu_bo *wb_obj; + + /** + * @wb: + * + * Pointer to the first writeback slot. In terms of CPU address + * this value can be accessed directly by using the offset as an index. + * For the GPU address, it is necessary to use gpu_addr and the offset. + */ + uint32_t *wb; + + /** + * @gpu_addr: + * + * Writeback base address in the GPU. + */ + uint64_t gpu_addr; + + /** + * @num_wb: + * + * Number of writeback slots reserved for amdgpu. + */ + u32 num_wb; + + /** + * @used: + * + * Track the writeback slot already used. + */ + unsigned long used[DIV_ROUND_UP(AMDGPU_MAX_WB, BITS_PER_LONG)]; + + /** + * @lock: + * + * Protects read and write of the used field array. + */ + spinlock_t lock; +}; + +void amdgpu_wb_fini(struct amdgpu_device *adev); +int amdgpu_wb_init(struct amdgpu_device *adev); +int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb); +void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb); +#endif diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 77e120a72815..e037c08c8547 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -36,6 +36,7 @@ #include "cikd.h" #include "atom.h" #include "amd_pcie.h" +#include "amdgpu_video_codecs.h" #include "cik.h" #include "gmc_v7_0.h" diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 120da838ac28..b951328d94cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -125,7 +125,8 @@ static int cik_sdma_init_microcode(struct amdgpu_device *adev) case CHIP_MULLINS: chip_name = "mullins"; break; - default: BUG(); + default: + return -EINVAL; } for (i = 0; i < adev->sdma.num_instances; i++) { @@ -605,7 +606,7 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring) u32 tmp; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -635,7 +636,7 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring) r = -ETIMEDOUT; error_free_wb: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -658,7 +659,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout) u64 gpu_addr; long r; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -699,7 +700,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index ddf190672530..55342962422b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -4080,7 +4080,7 @@ static int gfx_v10_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -4121,7 +4121,7 @@ err2: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err1: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -5350,6 +5350,15 @@ static void gfx_v10_0_constants_init(struct amdgpu_device *adev) gfx_v10_0_get_tcc_info(adev); adev->gfx.config.pa_sc_tile_steering_override = gfx_v10_0_init_pa_sc_tile_steering_override(adev); + /* Program DB_RING_CONTROL for multiple GFX pipes + * Default power up value is 1. + * Possible values: + * 0 - split occlusion counters between gfx pipes + * 1 - all occlusion counters to pipe 0 + * 2 - all occlusion counters to pipe 1 + */ + WREG32_FIELD15(GC, 0, DB_RING_CONTROL, COUNTER_CONTROL, + (adev->gfx.me.num_pipe_per_me > 1) ? 0 : 1); /* XXX SH_MEM regs */ /* where to put LDS, scratch, GPUVM in FSA64 space */ diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 2a121df90574..2ef6bc818aba 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -51,7 +51,7 @@ #include "mes_userqueue.h" #include "amdgpu_userq_fence.h" -#define GFX11_NUM_GFX_RINGS 1 +#define GFX11_NUM_GFX_RINGS 2 #define GFX11_MEC_HPD_SIZE 2048 #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L @@ -635,7 +635,7 @@ static int gfx_v11_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -676,7 +676,7 @@ err2: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err1: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -1625,7 +1625,10 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block) case IP_VERSION(11, 7, 0): case IP_VERSION(11, 7, 1): adev->gfx.me.num_me = 1; - adev->gfx.me.num_pipe_per_me = 1; + if (adev->gfx.rs64_enable) + adev->gfx.me.num_pipe_per_me = 1; + else + adev->gfx.me.num_pipe_per_me = 2; adev->gfx.me.num_queue_per_pipe = 2; adev->gfx.mec.num_mec = 1; adev->gfx.mec.num_pipe_per_mec = 4; @@ -2191,6 +2194,15 @@ static void gfx_v11_0_constants_init(struct amdgpu_device *adev) tmp = RREG32_SOC15(GC, 0, regTA_CNTL2); adev->gfx.config.ta_cntl2_truncate_coord_mode = REG_GET_FIELD(tmp, TA_CNTL2, TRUNCATE_COORD_MODE); + /* Program DB_RING_CONTROL for multiple GFX pipes + * Default power up value is 1. + * Possible values: + * 0 - split occlusion counters between gfx pipes + * 1 - all occlusion counters to pipe 0 + * 2 - all occlusion counters to pipe 1 + */ + WREG32_FIELD15_PREREG(GC, 0, DB_RING_CONTROL, COUNTER_CONTROL, + (adev->gfx.me.num_pipe_per_me > 1) ? 0 : 1); /* XXX SH_MEM regs */ /* where to put LDS, scratch, GPUVM in FSA64 space */ @@ -5357,6 +5369,7 @@ static void gfx_v11_0_ring_emit_gds_switch(struct amdgpu_ring *ring, static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; + int r; switch (amdgpu_user_queue) { case -1: @@ -5377,6 +5390,11 @@ static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block) adev->gfx.funcs = &gfx_v11_0_gfx_funcs; + gfx_v11_0_set_imu_funcs(adev); + r = gfx_v11_0_init_microcode(adev); + if (r) + return r; + if (adev->gfx.disable_kq) { /* We need one GFX ring temporarily to set up * the clear state. @@ -5384,7 +5402,11 @@ static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block) adev->gfx.num_gfx_rings = 1; adev->gfx.num_compute_rings = 0; } else { - adev->gfx.num_gfx_rings = GFX11_NUM_GFX_RINGS; + /* rs64 only supports one gfx pipe */ + if (adev->gfx.rs64_enable) + adev->gfx.num_gfx_rings = 1; + else + adev->gfx.num_gfx_rings = GFX11_NUM_GFX_RINGS; adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), AMDGPU_MAX_COMPUTE_RINGS); } @@ -5395,13 +5417,12 @@ static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block) gfx_v11_0_set_gds_init(adev); gfx_v11_0_set_rlc_funcs(adev); gfx_v11_0_set_mqd_funcs(adev); - gfx_v11_0_set_imu_funcs(adev); gfx_v11_0_init_rlcg_reg_access_ctrl(adev); amdgpu_init_rlc_reg_funcs(adev); - return gfx_v11_0_init_microcode(adev); + return 0; } static bool gfx_v11_0_is_rlc_enabled(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c index c765af54669c..6fedb6df8db9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c @@ -507,7 +507,7 @@ static int gfx_v12_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -548,7 +548,7 @@ err2: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err1: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -1827,6 +1827,15 @@ static void gfx_v12_0_constants_init(struct amdgpu_device *adev) gfx_v12_0_get_cu_info(adev, &adev->gfx.cu_info); gfx_v12_0_get_tcc_info(adev); adev->gfx.config.pa_sc_tile_steering_override = 0; + /* Program DB_RING_CONTROL for multiple GFX pipes + * Default power up value is 1. + * Possible values: + * 0 - split occlusion counters between gfx pipes + * 1 - all occlusion counters to pipe 0 + * 2 - all occlusion counters to pipe 1 + */ + WREG32_FIELD15_PREREG(GC, 0, DB_RING_CONTROL, COUNTER_CONTROL, + (adev->gfx.me.num_pipe_per_me > 1) ? 0 : 1); /* XXX SH_MEM regs */ /* where to put LDS, scratch, GPUVM in FSA64 space */ diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c index e87f1baf5cb6..b19a4956c222 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c @@ -320,7 +320,7 @@ static int gfx_v12_1_ring_test_ib(struct amdgpu_ring *ring, long timeout) memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -361,7 +361,7 @@ err2: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err1: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index bee2ff6865f9..9e0840df8849 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -876,7 +876,7 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) uint32_t tmp; long r; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -917,7 +917,7 @@ err2: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err1: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 9f81fd715418..556e5cb3f4cd 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1232,7 +1232,7 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) uint32_t tmp; long r; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -1273,7 +1273,7 @@ err2: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err1: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -4267,7 +4267,7 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev) BUG_ON(!ring->funcs->emit_rreg); spin_lock_irqsave(&kiq->ring_lock, flags); - if (amdgpu_device_wb_get(adev, ®_val_offs)) { + if (amdgpu_wb_get(adev, ®_val_offs)) { pr_err("critical bug! too many kiq readers\n"); goto failed_unlock; } @@ -4315,7 +4315,7 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev) mb(); value = (uint64_t)adev->wb.wb[reg_val_offs] | (uint64_t)adev->wb.wb[reg_val_offs + 1 ] << 32ULL; - amdgpu_device_wb_free(adev, reg_val_offs); + amdgpu_wb_free(adev, reg_val_offs); return value; failed_undo: @@ -4324,7 +4324,7 @@ failed_unlock: spin_unlock_irqrestore(&kiq->ring_lock, flags); failed_kiq_read: if (reg_val_offs) - amdgpu_device_wb_free(adev, reg_val_offs); + amdgpu_wb_free(adev, reg_val_offs); pr_err("failed to read gpu clock\n"); return ~0; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index b89cbc2df951..44d38b76cb4f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -458,7 +458,7 @@ static int gfx_v9_4_3_ring_test_ib(struct amdgpu_ring *ring, long timeout) uint32_t tmp; long r; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -499,7 +499,7 @@ err2: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err1: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index a914dd8183b5..b49098931d19 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -124,7 +124,7 @@ static int gmc_v6_0_init_microcode(struct amdgpu_device *adev) chip_name = "hainan"; break; default: - BUG(); + return -EINVAL; } /* this memory configuration requires special firmware */ diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c index cffb1e6bab35..a9c00adcfe41 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c @@ -747,7 +747,7 @@ static int jpeg_v2_0_set_interrupt_state(struct amdgpu_device *adev, return 0; } -static int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev, +int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h index 654e43e83e2c..4f400fb476f1 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h @@ -58,6 +58,10 @@ void jpeg_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring, void jpeg_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); void jpeg_v2_0_dec_ring_nop(struct amdgpu_ring *ring, uint32_t count); +int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + struct amdgpu_iv_entry *entry); + extern const struct amdgpu_ip_block_version jpeg_v2_0_ip_block; #endif /* __JPEG_V2_0_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c index d0445df39d2c..e9ccadeb7696 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c @@ -539,25 +539,6 @@ static int jpeg_v3_0_set_interrupt_state(struct amdgpu_device *adev, return 0; } -static int jpeg_v3_0_process_interrupt(struct amdgpu_device *adev, - struct amdgpu_irq_src *source, - struct amdgpu_iv_entry *entry) -{ - DRM_DEBUG("IH: JPEG TRAP\n"); - - switch (entry->src_id) { - case VCN_2_0__SRCID__JPEG_DECODE: - amdgpu_fence_process(adev->jpeg.inst->ring_dec); - break; - default: - DRM_ERROR("Unhandled interrupt: %d %d\n", - entry->src_id, entry->src_data[0]); - break; - } - - return 0; -} - static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring, unsigned int vmid, struct amdgpu_fence *timedout_fence) @@ -630,7 +611,7 @@ static void jpeg_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev) static const struct amdgpu_irq_src_funcs jpeg_v3_0_irq_funcs = { .set = jpeg_v3_0_set_interrupt_state, - .process = jpeg_v3_0_process_interrupt, + .process = jpeg_v2_0_process_interrupt, }; static void jpeg_v3_0_set_irq_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c index 72a4b2d0676f..1cdbe353ae40 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c @@ -625,7 +625,7 @@ static int jpeg_v5_0_0_set_interrupt_state(struct amdgpu_device *adev, return 0; } -static int jpeg_v5_0_0_process_interrupt(struct amdgpu_device *adev, +int jpeg_v5_0_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.h b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.h index 5abb96159814..4eeb0c14702c 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.h +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.h @@ -32,4 +32,8 @@ extern const struct amdgpu_ip_block_version jpeg_v5_0_0_ip_block; +int jpeg_v5_0_0_process_interrupt(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + struct amdgpu_iv_entry *entry); + #endif /* __JPEG_V5_0_0_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c index e7546816baba..66d4c487eee5 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c @@ -32,6 +32,7 @@ #include "vcn/vcn_5_3_0_offset.h" #include "vcn/vcn_5_3_0_sh_mask.h" #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h" +#include "jpeg_v5_0_0.h" #include "jpeg_v5_3_0.h" static void jpeg_v5_3_0_set_dec_ring_funcs(struct amdgpu_device *adev); @@ -608,25 +609,6 @@ static int jpeg_v5_3_0_set_interrupt_state(struct amdgpu_device *adev, return 0; } -static int jpeg_v5_3_0_process_interrupt(struct amdgpu_device *adev, - struct amdgpu_irq_src *source, - struct amdgpu_iv_entry *entry) -{ - DRM_DEBUG("IH: JPEG TRAP\n"); - - switch (entry->src_id) { - case VCN_5_0__SRCID__JPEG_DECODE: - amdgpu_fence_process(adev->jpeg.inst->ring_dec); - break; - default: - DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", - entry->src_id, entry->src_data[0]); - break; - } - - return 0; -} - static int jpeg_v5_3_0_ring_reset(struct amdgpu_ring *ring, unsigned int vmid, struct amdgpu_fence *timedout_fence) @@ -697,7 +679,7 @@ static void jpeg_v5_3_0_set_dec_ring_funcs(struct amdgpu_device *adev) static const struct amdgpu_irq_src_funcs jpeg_v5_3_0_irq_funcs = { .set = jpeg_v5_3_0_set_interrupt_state, - .process = jpeg_v5_3_0_process_interrupt, + .process = jpeg_v5_0_0_process_interrupt, }; static void jpeg_v5_3_0_set_irq_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index e947c16e694d..defa050fd871 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -521,7 +521,7 @@ static int mes_userq_preempt(struct amdgpu_usermode_queue *queue) if (queue->state != AMDGPU_USERQ_STATE_MAPPED) return 0; - r = amdgpu_device_wb_get(adev, &fence_offset); + r = amdgpu_wb_get(adev, &fence_offset); if (r) return r; @@ -549,7 +549,7 @@ static int mes_userq_preempt(struct amdgpu_usermode_queue *queue) r = -ETIMEDOUT; out: - amdgpu_device_wb_free(adev, fence_offset); + amdgpu_wb_free(adev, fence_offset); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c index 8f136ff7d96f..72ca7302bbfb 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -198,7 +198,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, timeout = 15 * 600 * 1000; } - ret = amdgpu_device_wb_get(adev, &status_offset); + ret = amdgpu_wb_get(adev, &status_offset); if (ret) return ret; @@ -270,7 +270,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, goto error_wb_free; } - amdgpu_device_wb_free(adev, status_offset); + amdgpu_wb_free(adev, status_offset); return 0; error_undo: @@ -281,7 +281,7 @@ error_unlock_free: spin_unlock_irqrestore(&mes->ring_lock[0], flags); error_wb_free: - amdgpu_device_wb_free(adev, status_offset); + amdgpu_wb_free(adev, status_offset); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c index ce5064200743..04465804c254 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c @@ -175,7 +175,7 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, timeout = 15 * 600 * 1000; } - ret = amdgpu_device_wb_get(adev, &status_offset); + ret = amdgpu_wb_get(adev, &status_offset); if (ret) return ret; @@ -253,7 +253,7 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, goto error_wb_free; } - amdgpu_device_wb_free(adev, status_offset); + amdgpu_wb_free(adev, status_offset); return 0; error_undo: @@ -264,7 +264,7 @@ error_unlock_free: spin_unlock_irqrestore(ring_lock, flags); error_wb_free: - amdgpu_device_wb_free(adev, status_offset); + amdgpu_wb_free(adev, status_offset); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c index f7d5879c6e44..dbdb9ba02a5f 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c @@ -43,7 +43,6 @@ static int mes_v12_1_xcc_hw_init(struct amdgpu_ip_block *ip_block, int xcc_id); static int mes_v12_1_hw_fini(struct amdgpu_ip_block *ip_block); static int mes_v12_1_kiq_hw_init(struct amdgpu_device *adev, uint32_t xcc_id); static int mes_v12_1_kiq_hw_fini(struct amdgpu_device *adev, uint32_t xcc_id); -static int mes_v12_1_self_test(struct amdgpu_device *adev, int xcc_id); static int mes_v12_1_setup_coop_mode(struct amdgpu_device *adev, int xcc_id); #define MES_EOP_SIZE 2048 @@ -178,7 +177,7 @@ static int mes_v12_1_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, timeout = 15 * 600 * 1000; } - ret = amdgpu_device_wb_get(adev, &status_offset); + ret = amdgpu_wb_get(adev, &status_offset); if (ret) return ret; @@ -253,7 +252,7 @@ static int mes_v12_1_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, goto error_wb_free; } - amdgpu_device_wb_free(adev, status_offset); + amdgpu_wb_free(adev, status_offset); return 0; error_undo: @@ -264,7 +263,7 @@ error_unlock_free: spin_unlock_irqrestore(ring_lock, flags); error_wb_free: - amdgpu_device_wb_free(adev, status_offset); + amdgpu_wb_free(adev, status_offset); return r; } @@ -1994,31 +1993,10 @@ static int mes_v12_1_early_init(struct amdgpu_ip_block *ip_block) return 0; } -static int mes_v12_1_late_init(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int xcc_id, num_xcc = NUM_XCC(adev->gfx.xcc_mask); - - /* TODO: remove it if issue fixed. */ - if (adev->mes.enable_coop_mode) - return 0; - - for (xcc_id = 0; xcc_id < num_xcc; xcc_id++) { - /* for COOP mode, only test master xcc. */ - if (adev->mes.enable_coop_mode && - adev->mes.master_xcc_ids[xcc_id] != xcc_id) - continue; - - mes_v12_1_self_test(adev, xcc_id); - } - - return 0; -} - static const struct amd_ip_funcs mes_v12_1_ip_funcs = { .name = "mes_v12_1", .early_init = mes_v12_1_early_init, - .late_init = mes_v12_1_late_init, + .late_init = NULL, .sw_init = mes_v12_1_sw_init, .sw_fini = mes_v12_1_sw_fini, .hw_init = mes_v12_1_hw_init, @@ -2034,313 +2012,3 @@ const struct amdgpu_ip_block_version mes_v12_1_ip_block = { .rev = 0, .funcs = &mes_v12_1_ip_funcs, }; - -static int mes_v12_1_alloc_test_buf(struct amdgpu_device *adev, - struct amdgpu_bo **bo, uint64_t *addr, - void **ptr, int size) -{ - amdgpu_bo_create_kernel(adev, size, PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, - bo, addr, ptr); - if (!*bo) { - dev_err(adev->dev, "failed to allocate test buffer bo\n"); - return -ENOMEM; - } - memset(*ptr, 0, size); - return 0; -} - -static int mes_v12_1_map_test_bo(struct amdgpu_device *adev, - struct amdgpu_bo *bo, struct amdgpu_vm *vm, - struct amdgpu_bo_va **bo_va, u64 va, int size) -{ - struct amdgpu_sync sync; - int r; - - r = amdgpu_map_static_csa(adev, vm, bo, bo_va, va, size); - if (r) - return r; - - amdgpu_sync_create(&sync); - - r = amdgpu_vm_bo_update(adev, *bo_va, false); - if (r) { - dev_err(adev->dev, "failed to do vm_bo_update on meta data\n"); - goto error; - } - amdgpu_sync_fence(&sync, (*bo_va)->last_pt_update, GFP_KERNEL); - - r = amdgpu_vm_update_pdes(adev, vm, false); - if (r) { - dev_err(adev->dev, "failed to update pdes on meta data\n"); - goto error; - } - amdgpu_sync_fence(&sync, vm->last_update, GFP_KERNEL); - amdgpu_sync_wait(&sync, false); - -error: - amdgpu_sync_free(&sync); - return r; -} - -static int mes_v12_1_test_ring(struct amdgpu_device *adev, int xcc_id, - u32 *queue_ptr, u64 fence_gpu_addr, - void *fence_cpu_ptr, void *wptr_cpu_addr, - u64 doorbell_idx, int queue_type) -{ - volatile uint32_t *cpu_ptr = fence_cpu_ptr; - int num_xcc = NUM_XCC(adev->gfx.xcc_mask); - int sdma_ring_align = 0x10, compute_ring_align = 0x100; - uint32_t tmp, xcc_offset; - int r = 0, i, j, wptr = 0; - - if (queue_type == AMDGPU_RING_TYPE_COMPUTE) { - if (!adev->mes.enable_coop_mode) { - WREG32_SOC15(GC, GET_INST(GC, xcc_id), - regSCRATCH_REG0, 0xCAFEDEAD); - } else { - for (i = 0; i < num_xcc; i++) { - if (adev->mes.master_xcc_ids[i] == xcc_id) - WREG32_SOC15(GC, GET_INST(GC, i), - regSCRATCH_REG0, 0xCAFEDEAD); - } - } - - xcc_offset = SOC15_REG_OFFSET(GC, 0, regSCRATCH_REG0); - queue_ptr[wptr++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); - queue_ptr[wptr++] = xcc_offset - PACKET3_SET_UCONFIG_REG_START; - queue_ptr[wptr++] = 0xDEADBEEF; - - for (i = wptr; i < compute_ring_align; i++) - queue_ptr[wptr++] = PACKET3(PACKET3_NOP, 0x3FFF); - - } else if (queue_type == AMDGPU_RING_TYPE_SDMA) { - *cpu_ptr = 0xCAFEDEAD; - - queue_ptr[wptr++] = SDMA_PKT_COPY_LINEAR_HEADER_OP(SDMA_OP_WRITE) | - SDMA_PKT_COPY_LINEAR_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR); - queue_ptr[wptr++] = lower_32_bits(fence_gpu_addr); - queue_ptr[wptr++] = upper_32_bits(fence_gpu_addr); - queue_ptr[wptr++] = SDMA_PKT_WRITE_UNTILED_DW_3_COUNT(0); - queue_ptr[wptr++] = 0xDEADBEEF; - - for (i = wptr; i < sdma_ring_align; i++) - queue_ptr[wptr++] = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP); - - wptr <<= 2; - } - - atomic64_set((atomic64_t *)wptr_cpu_addr, wptr); - WDOORBELL64(doorbell_idx, wptr); - - for (i = 0; i < adev->usec_timeout; i++) { - if (queue_type == AMDGPU_RING_TYPE_SDMA) { - tmp = le32_to_cpu(*cpu_ptr); - } else { - if (!adev->mes.enable_coop_mode) { - tmp = RREG32_SOC15(GC, GET_INST(GC, xcc_id), - regSCRATCH_REG0); - } else { - for (j = 0; j < num_xcc; j++) { - if (xcc_id != adev->mes.master_xcc_ids[j]) - continue; - - tmp = RREG32_SOC15(GC, GET_INST(GC, j), - regSCRATCH_REG0); - if (tmp != 0xDEADBEEF) - break; - } - } - } - - if (tmp == 0xDEADBEEF) - break; - - if (amdgpu_emu_mode == 1) - msleep(1); - else - udelay(1); - } - - if (i >= adev->usec_timeout) { - dev_err(adev->dev, "xcc%d: mes self test (%s) failed\n", xcc_id, - queue_type == AMDGPU_RING_TYPE_SDMA ? "sdma" : "compute"); - - while (halt_if_hws_hang) - schedule(); - - r = -ETIMEDOUT; - } else { - dev_info(adev->dev, "xcc%d: mes self test (%s) pass\n", xcc_id, - queue_type == AMDGPU_RING_TYPE_SDMA ? "sdma" : "compute"); - } - - return r; -} - -#define USER_CTX_SIZE (PAGE_SIZE * 2) -#define USER_CTX_VA AMDGPU_VA_RESERVED_BOTTOM -#define RING_OFFSET(addr) ((addr)) -#define EOP_OFFSET(addr) ((addr) + PAGE_SIZE) -#define WPTR_OFFSET(addr) ((addr) + USER_CTX_SIZE - sizeof(u64)) -#define RPTR_OFFSET(addr) ((addr) + USER_CTX_SIZE - sizeof(u64) * 2) -#define FENCE_OFFSET(addr) ((addr) + USER_CTX_SIZE - sizeof(u64) * 3) - -static int mes_v12_1_test_queue(struct amdgpu_device *adev, int xcc_id, - int pasid, struct amdgpu_vm *vm, u64 meta_gpu_addr, - u64 queue_gpu_addr, void *ctx_ptr, int queue_type) -{ - struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)]; - struct amdgpu_mqd *mqd_mgr = &adev->mqds[queue_type]; - struct amdgpu_mqd_prop mqd_prop = {0}; - struct mes_add_queue_input add_queue = {0}; - struct mes_remove_queue_input remove_queue = {0}; - struct amdgpu_bo *mqd_bo = NULL; - int num_xcc = NUM_XCC(adev->gfx.xcc_mask); - int i, r, off, mqd_size, mqd_count = 1; - void *mqd_ptr = NULL; - u64 mqd_gpu_addr, doorbell_idx; - - /* extra one page size padding for mes fw */ - mqd_size = mqd_mgr->mqd_size + PAGE_SIZE; - - if (queue_type == AMDGPU_RING_TYPE_SDMA) { - doorbell_idx = adev->mes.db_start_dw_offset + \ - adev->doorbell_index.sdma_engine[0]; - } else { - doorbell_idx = adev->mes.db_start_dw_offset + \ - adev->doorbell_index.userqueue_start; - } - - if (adev->mes.enable_coop_mode && - queue_type == AMDGPU_RING_TYPE_COMPUTE) { - for (i = 0, mqd_count = 0; i < num_xcc; i++) { - if (adev->mes.master_xcc_ids[i] == xcc_id) - mqd_count++; - } - mqd_size *= mqd_count; - } - - r = mes_v12_1_alloc_test_buf(adev, &mqd_bo, &mqd_gpu_addr, - &mqd_ptr, mqd_size * mqd_count); - if (r < 0) - return r; - - mqd_prop.mqd_gpu_addr = mqd_gpu_addr; - mqd_prop.hqd_base_gpu_addr = RING_OFFSET(USER_CTX_VA); - mqd_prop.eop_gpu_addr = EOP_OFFSET(USER_CTX_VA); - mqd_prop.wptr_gpu_addr = WPTR_OFFSET(USER_CTX_VA); - mqd_prop.rptr_gpu_addr = RPTR_OFFSET(USER_CTX_VA); - mqd_prop.doorbell_index = doorbell_idx; - mqd_prop.queue_size = PAGE_SIZE; - mqd_prop.mqd_stride_size = mqd_size; - mqd_prop.use_doorbell = true; - mqd_prop.hqd_active = false; - - mqd_mgr->init_mqd(adev, mqd_ptr, &mqd_prop); - if (mqd_count > 1) { - for (i = 1; i < mqd_count; i++) { - off = mqd_size * i; - mqd_prop.mqd_gpu_addr = mqd_gpu_addr + off; - mqd_mgr->init_mqd(adev, (char *)mqd_ptr + off, - &mqd_prop); - } - } - - add_queue.xcc_id = xcc_id; - add_queue.process_id = pasid; - add_queue.page_table_base_addr = adev->vm_manager.vram_base_offset + - amdgpu_bo_gpu_offset(vm->root.bo) - adev->gmc.vram_start; - add_queue.process_va_start = 0; - add_queue.process_va_end = adev->vm_manager.max_pfn - 1; - add_queue.process_context_addr = meta_gpu_addr; - add_queue.gang_context_addr = meta_gpu_addr + AMDGPU_MES_PROC_CTX_SIZE; - add_queue.doorbell_offset = doorbell_idx; - add_queue.mqd_addr = mqd_gpu_addr; - add_queue.wptr_addr = mqd_prop.wptr_gpu_addr; - add_queue.wptr_mc_addr = WPTR_OFFSET(queue_gpu_addr); - add_queue.queue_type = queue_type; - add_queue.vm_cntx_cntl = hub->vm_cntx_cntl; - - r = mes_v12_1_add_hw_queue(&adev->mes, &add_queue); - if (r) - goto error; - - mes_v12_1_test_ring(adev, xcc_id, (u32 *)RING_OFFSET((char *)ctx_ptr), - FENCE_OFFSET(USER_CTX_VA), - FENCE_OFFSET((char *)ctx_ptr), - WPTR_OFFSET((char *)ctx_ptr), - doorbell_idx, queue_type); - - remove_queue.xcc_id = xcc_id; - remove_queue.doorbell_offset = doorbell_idx; - remove_queue.gang_context_addr = add_queue.gang_context_addr; - remove_queue.queue_type = queue_type; - r = mes_v12_1_remove_hw_queue(&adev->mes, &remove_queue); - -error: - amdgpu_bo_free_kernel(&mqd_bo, &mqd_gpu_addr, &mqd_ptr); - return r; -} - -static int mes_v12_1_self_test(struct amdgpu_device *adev, int xcc_id) -{ - int queue_types[] = { AMDGPU_RING_TYPE_COMPUTE, - /* AMDGPU_RING_TYPE_SDMA */ }; - struct amdgpu_bo_va *bo_va = NULL; - struct amdgpu_vm *vm = NULL; - struct amdgpu_bo *meta_bo = NULL, *ctx_bo = NULL; - void *meta_ptr = NULL, *ctx_ptr = NULL; - u64 meta_gpu_addr, ctx_gpu_addr; - int size, i, r, pasid; - - pasid = amdgpu_pasid_alloc(16); - if (pasid < 0) - pasid = 0; - - size = AMDGPU_MES_PROC_CTX_SIZE + AMDGPU_MES_GANG_CTX_SIZE; - r = mes_v12_1_alloc_test_buf(adev, &meta_bo, &meta_gpu_addr, - &meta_ptr, size); - if (r < 0) - goto err2; - - r = mes_v12_1_alloc_test_buf(adev, &ctx_bo, &ctx_gpu_addr, - &ctx_ptr, USER_CTX_SIZE); - if (r < 0) - goto err2; - - vm = kzalloc(sizeof(*vm), GFP_KERNEL); - if (!vm) { - r = -ENOMEM; - goto err2; - } - - r = amdgpu_vm_init(adev, vm, -1, pasid); - if (r) - goto err1; - - r = mes_v12_1_map_test_bo(adev, ctx_bo, vm, &bo_va, - USER_CTX_VA, USER_CTX_SIZE); - if (r) - goto err0; - - for (i = 0; i < ARRAY_SIZE(queue_types); i++) { - memset(ctx_ptr, 0, USER_CTX_SIZE); - - r = mes_v12_1_test_queue(adev, xcc_id, pasid, vm, meta_gpu_addr, - ctx_gpu_addr, ctx_ptr, queue_types[i]); - if (r) - break; - } - - amdgpu_unmap_static_csa(adev, vm, ctx_bo, bo_va, USER_CTX_VA); -err0: - amdgpu_vm_fini(adev, vm); -err1: - kfree(vm); -err2: - amdgpu_bo_free_kernel(&meta_bo, &meta_gpu_addr, &meta_ptr); - amdgpu_bo_free_kernel(&ctx_bo, &ctx_gpu_addr, &ctx_ptr); - amdgpu_pasid_free(pasid); - return r; -} - diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index 77557ee3ca16..96faaf8c5737 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -36,6 +36,7 @@ #include "amdgpu_psp.h" #include "atom.h" #include "amd_pcie.h" +#include "amdgpu_video_codecs.h" #include "gc/gc_10_1_0_offset.h" #include "gc/gc_10_1_0_sh_mask.h" diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 93ec52c1f367..c7253b908351 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -138,7 +138,7 @@ static int sdma_v2_4_init_microcode(struct amdgpu_device *adev) chip_name = "topaz"; break; default: - BUG(); + return -EINVAL; } for (i = 0; i < adev->sdma.num_instances; i++) { @@ -536,7 +536,7 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring) u32 tmp; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -567,7 +567,7 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring) r = -ETIMEDOUT; error_free_wb: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -590,7 +590,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout) u64 gpu_addr; long r; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -635,7 +635,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index c2d098cd72ce..05cce4bde73e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -298,7 +298,8 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev) case CHIP_STONEY: chip_name = "stoney"; break; - default: BUG(); + default: + return -EINVAL; } for (i = 0; i < adev->sdma.num_instances; i++) { @@ -810,7 +811,7 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring) u32 tmp; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -841,7 +842,7 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring) r = -ETIMEDOUT; error_free_wb: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -864,7 +865,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) u64 gpu_addr; long r; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -908,7 +909,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index cb64d17000df..20c8ebf0e159 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -1468,7 +1468,7 @@ static int sdma_v4_0_ring_test_ring(struct amdgpu_ring *ring) u32 tmp; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -1499,7 +1499,7 @@ static int sdma_v4_0_ring_test_ring(struct amdgpu_ring *ring) r = -ETIMEDOUT; error_free_wb: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -1522,7 +1522,7 @@ static int sdma_v4_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) u32 tmp = 0; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -1567,7 +1567,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c index 484f1a6b5fbc..6fe3d3d56c40 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c @@ -1062,7 +1062,7 @@ static int sdma_v4_4_2_ring_test_ring(struct amdgpu_ring *ring) u32 tmp; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -1093,7 +1093,7 @@ static int sdma_v4_4_2_ring_test_ring(struct amdgpu_ring *ring) r = -ETIMEDOUT; error_free_wb: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -1116,7 +1116,7 @@ static int sdma_v4_4_2_ring_test_ib(struct amdgpu_ring *ring, long timeout) u32 tmp = 0; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -1161,7 +1161,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index b809942b1eb7..1ca0e7f65442 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -1019,7 +1019,7 @@ static int sdma_v5_0_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); return r; @@ -1031,7 +1031,7 @@ static int sdma_v5_0_ring_test_ring(struct amdgpu_ring *ring) r = amdgpu_ring_alloc(ring, 20); if (r) { drm_err(adev_to_drm(adev), "dma failed to lock ring %d (%d).\n", ring->idx, r); - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -1056,7 +1056,7 @@ static int sdma_v5_0_ring_test_ring(struct amdgpu_ring *ring) if (i >= adev->usec_timeout) r = -ETIMEDOUT; - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -1083,7 +1083,7 @@ static int sdma_v5_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) tmp = 0xCAFEDEAD; memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); return r; @@ -1135,7 +1135,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index 87c1e29fd298..81f1e9882177 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -919,7 +919,7 @@ static int sdma_v5_2_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); return r; @@ -931,7 +931,7 @@ static int sdma_v5_2_ring_test_ring(struct amdgpu_ring *ring) r = amdgpu_ring_alloc(ring, 20); if (r) { drm_err(adev_to_drm(adev), "dma failed to lock ring %d (%d).\n", ring->idx, r); - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -956,7 +956,7 @@ static int sdma_v5_2_ring_test_ring(struct amdgpu_ring *ring) if (i >= adev->usec_timeout) r = -ETIMEDOUT; - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -983,7 +983,7 @@ static int sdma_v5_2_ring_test_ib(struct amdgpu_ring *ring, long timeout) tmp = 0xCAFEDEAD; memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); return r; @@ -1034,7 +1034,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c index 7a3f1a60b014..cf3d2997fff8 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c @@ -910,7 +910,7 @@ static int sdma_v6_0_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); return r; @@ -922,7 +922,7 @@ static int sdma_v6_0_ring_test_ring(struct amdgpu_ring *ring) r = amdgpu_ring_alloc(ring, 5); if (r) { drm_err(adev_to_drm(adev), "dma failed to lock ring %d (%d).\n", ring->idx, r); - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -947,7 +947,7 @@ static int sdma_v6_0_ring_test_ring(struct amdgpu_ring *ring) if (i >= adev->usec_timeout) r = -ETIMEDOUT; - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -974,7 +974,7 @@ static int sdma_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) tmp = 0xCAFEDEAD; memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); return r; @@ -1025,7 +1025,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c index 84305b6800fe..69cb89298a3e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c @@ -925,7 +925,7 @@ static int sdma_v7_0_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); return r; @@ -937,7 +937,7 @@ static int sdma_v7_0_ring_test_ring(struct amdgpu_ring *ring) r = amdgpu_ring_alloc(ring, 5); if (r) { drm_err(adev_to_drm(adev), "dma failed to lock ring %d (%d).\n", ring->idx, r); - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -962,7 +962,7 @@ static int sdma_v7_0_ring_test_ring(struct amdgpu_ring *ring) if (i >= adev->usec_timeout) r = -ETIMEDOUT; - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -989,7 +989,7 @@ static int sdma_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) tmp = 0xCAFEDEAD; memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); return r; @@ -1040,7 +1040,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c index 322e6f4dd121..18366e16ef3f 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c @@ -915,7 +915,7 @@ static int sdma_v7_1_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); return r; @@ -927,7 +927,7 @@ static int sdma_v7_1_ring_test_ring(struct amdgpu_ring *ring) r = amdgpu_ring_alloc(ring, 5); if (r) { DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -952,7 +952,7 @@ static int sdma_v7_1_ring_test_ring(struct amdgpu_ring *ring) if (i >= adev->usec_timeout) r = -ETIMEDOUT; - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -979,7 +979,7 @@ static int sdma_v7_1_ring_test_ib(struct amdgpu_ring *ring, long timeout) tmp = 0xCAFEDEAD; memset(&ib, 0, sizeof(ib)); - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); return r; @@ -1030,7 +1030,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index b104469c38ec..7100f30ffeff 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c @@ -35,6 +35,7 @@ #include "amdgpu_vce.h" #include "atom.h" #include "amd_pcie.h" +#include "amdgpu_video_codecs.h" #include "si_dpm.h" #include "sid.h" @@ -2217,7 +2218,7 @@ static void si_init_golden_registers(struct amdgpu_device *adev) default: - BUG(); + break; } } @@ -2734,7 +2735,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev) amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); break; default: - BUG(); + break; } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c index 549708075eb4..47f1d325bd1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c @@ -213,7 +213,7 @@ static int si_dma_ring_test_ring(struct amdgpu_ring *ring) u32 tmp; u64 gpu_addr; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -242,7 +242,7 @@ static int si_dma_ring_test_ring(struct amdgpu_ring *ring) r = -ETIMEDOUT; error_free_wb: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } @@ -265,7 +265,7 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout) u64 gpu_addr; long r; - r = amdgpu_device_wb_get(adev, &index); + r = amdgpu_wb_get(adev, &index); if (r) return r; @@ -304,7 +304,7 @@ err1: amdgpu_ib_free(&ib, NULL); dma_fence_put(f); err0: - amdgpu_device_wb_free(adev, index); + amdgpu_wb_free(adev, index); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index ed3fd58b78d0..3d4573d93742 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -77,6 +77,7 @@ #include "mxgpu_ai.h" #include "amdgpu_ras.h" #include "amdgpu_xgmi.h" +#include "amdgpu_video_codecs.h" #include <uapi/linux/kfd_ioctl.h> #define mmMP0_MISC_CGTT_CTRL0 0x01b9 diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c index 09f28dbd60ee..713746a75d1f 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc21.c +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -33,6 +33,7 @@ #include "amdgpu_ucode.h" #include "amdgpu_psp.h" #include "amdgpu_smu.h" +#include "amdgpu_video_codecs.h" #include "atom.h" #include "amd_pcie.h" @@ -406,6 +407,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev) case IP_VERSION(14, 0, 4): case IP_VERSION(14, 0, 5): case IP_VERSION(15, 0, 0): + case IP_VERSION(15, 0, 9): return AMD_RESET_METHOD_MODE2; default: if (amdgpu_dpm_is_baco_supported(adev)) @@ -849,7 +851,6 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block) AMD_CG_SUPPORT_BIF_LS; adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG | AMD_PG_SUPPORT_VCN | - AMD_PG_SUPPORT_JPEG_DPG | AMD_PG_SUPPORT_JPEG | AMD_PG_SUPPORT_GFX_PG; adev->external_rev_id = adev->rev_id + 0xF; @@ -877,7 +878,6 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block) AMD_CG_SUPPORT_BIF_LS; adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG | AMD_PG_SUPPORT_VCN | - AMD_PG_SUPPORT_JPEG_DPG | AMD_PG_SUPPORT_JPEG | AMD_PG_SUPPORT_GFX_PG; adev->external_rev_id = adev->rev_id + 0x40; diff --git a/drivers/gpu/drm/amd/amdgpu/soc24.c b/drivers/gpu/drm/amd/amdgpu/soc24.c index e5e3a460e486..9a658e4837f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc24.c +++ b/drivers/gpu/drm/amd/amdgpu/soc24.c @@ -34,6 +34,7 @@ #include "amdgpu_smu.h" #include "atom.h" #include "amd_pcie.h" +#include "amdgpu_video_codecs.h" #include "gc/gc_12_0_0_offset.h" #include "gc/gc_12_0_0_sh_mask.h" diff --git a/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c b/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c index a9039fb1a77b..43e92e2a85e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/soc_v1_0.c @@ -29,6 +29,7 @@ #include "gfxhub_v12_1.h" #include "sdma_v7_1.h" #include "gfx_v12_1.h" +#include "amdgpu_video_codecs.h" #include "gc/gc_12_1_0_offset.h" #include "gc/gc_12_1_0_sh_mask.h" diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c index 67bdf7303e6b..99d19de42525 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c @@ -28,30 +28,8 @@ #include "umc/umc_12_0_0_sh_mask.h" #include "mp/mp_13_0_6_sh_mask.h" -bool umc_v12_0_is_deferred_error(struct amdgpu_device *adev, uint64_t mc_umc_status) -{ - dev_dbg(adev->dev, - "MCA_UMC_STATUS(0x%llx): Val:%llu, Poison:%llu, Deferred:%llu, PCC:%llu, UC:%llu, TCC:%llu\n", - mc_umc_status, - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val), - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Poison), - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred), - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC), - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC), - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) - ); - - return (amdgpu_ras_is_poison_mode_supported(adev) && - (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) && - ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1) || - (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Poison) == 1))); -} - bool umc_v12_0_is_uncorrectable_error(struct amdgpu_device *adev, uint64_t mc_umc_status) { - if (umc_v12_0_is_deferred_error(adev, mc_umc_status)) - return false; - return ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) && (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 || REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 || @@ -60,9 +38,6 @@ bool umc_v12_0_is_uncorrectable_error(struct amdgpu_device *adev, uint64_t mc_um bool umc_v12_0_is_correctable_error(struct amdgpu_device *adev, uint64_t mc_umc_status) { - if (umc_v12_0_is_deferred_error(adev, mc_umc_status)) - return false; - return (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 && (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1 || (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 && @@ -73,135 +48,9 @@ bool umc_v12_0_is_correctable_error(struct amdgpu_device *adev, uint64_t mc_umc_ !(umc_v12_0_is_uncorrectable_error(adev, mc_umc_status))))); } -static void umc_v12_0_get_retire_flip_bits(struct amdgpu_device *adev) -{ - enum amdgpu_memory_partition nps = AMDGPU_NPS1_PARTITION_MODE; - uint32_t vram_type = adev->gmc.vram_type; - struct amdgpu_umc_flip_bits *flip_bits = &(adev->umc.flip_bits); - - if (adev->gmc.gmc_funcs->query_mem_partition_mode) - nps = adev->gmc.gmc_funcs->query_mem_partition_mode(adev); - - if (adev->gmc.num_umc == 16) { - /* default setting */ - flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_C2_BIT; - flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_C3_BIT; - flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_C4_BIT; - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R13_BIT; - flip_bits->flip_row_bit = 13; - flip_bits->bit_num = 4; - flip_bits->r13_in_pa = UMC_V12_0_PA_R13_BIT; - - if (nps == AMDGPU_NPS2_PARTITION_MODE) { - flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_CH5_BIT; - flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_C2_BIT; - flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_B1_BIT; - flip_bits->r13_in_pa = UMC_V12_0_PA_R12_BIT; - } else if (nps == AMDGPU_NPS4_PARTITION_MODE) { - flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_CH4_BIT; - flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_CH5_BIT; - flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_B0_BIT; - flip_bits->r13_in_pa = UMC_V12_0_PA_R11_BIT; - } - - switch (vram_type) { - case AMDGPU_VRAM_TYPE_HBM: - /* other nps modes are taken as nps1 */ - if (nps == AMDGPU_NPS2_PARTITION_MODE) - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R12_BIT; - else if (nps == AMDGPU_NPS4_PARTITION_MODE) - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R11_BIT; - - break; - case AMDGPU_VRAM_TYPE_HBM3E: - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R12_BIT; - flip_bits->flip_row_bit = 12; - - if (nps == AMDGPU_NPS2_PARTITION_MODE) - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R11_BIT; - else if (nps == AMDGPU_NPS4_PARTITION_MODE) - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R10_BIT; - - break; - default: - dev_warn(adev->dev, - "Unknown HBM type, set RAS retire flip bits to the value in NPS1 mode.\n"); - break; - } - } else if (adev->gmc.num_umc == 8) { - /* default setting */ - flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_CH5_BIT; - flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_C2_BIT; - flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_B1_BIT; - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R11_BIT; - flip_bits->flip_row_bit = 12; - flip_bits->bit_num = 4; - flip_bits->r13_in_pa = UMC_V12_0_PA_R12_BIT; - - if (nps == AMDGPU_NPS2_PARTITION_MODE) { - flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_CH4_BIT; - flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_CH5_BIT; - flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_B0_BIT; - flip_bits->r13_in_pa = UMC_V12_0_PA_R11_BIT; - } - - switch (vram_type) { - case AMDGPU_VRAM_TYPE_HBM: - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R12_BIT; - - /* other nps modes are taken as nps1 */ - if (nps == AMDGPU_NPS2_PARTITION_MODE) - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R11_BIT; - - break; - case AMDGPU_VRAM_TYPE_HBM3E: - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R11_BIT; - flip_bits->flip_row_bit = 12; - - if (nps == AMDGPU_NPS2_PARTITION_MODE) - flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R10_BIT; - - break; - default: - dev_warn(adev->dev, - "Unknown HBM type, set RAS retire flip bits to the value in NPS1 mode.\n"); - break; - } - } else { - dev_warn(adev->dev, - "Unsupported UMC number(%d), failed to set RAS flip bits.\n", - adev->gmc.num_umc); - - return; - } - - adev->umc.retire_unit = 0x1 << flip_bits->bit_num; -} - -static bool umc_v12_0_check_ecc_err_status(struct amdgpu_device *adev, - enum amdgpu_mca_error_type type, void *ras_error_status) -{ - uint64_t mc_umc_status = *(uint64_t *)ras_error_status; - - switch (type) { - case AMDGPU_MCA_ERROR_TYPE_UE: - return umc_v12_0_is_uncorrectable_error(adev, mc_umc_status); - case AMDGPU_MCA_ERROR_TYPE_CE: - return umc_v12_0_is_correctable_error(adev, mc_umc_status); - case AMDGPU_MCA_ERROR_TYPE_DE: - return umc_v12_0_is_deferred_error(adev, mc_umc_status); - default: - return false; - } - - return false; -} - struct amdgpu_umc_ras umc_v12_0_ras = { .ras_block = { .hw_ops = NULL, }, - .check_ecc_err_status = umc_v12_0_check_ecc_err_status, - .get_retire_flip_bits = umc_v12_0_get_retire_flip_bits, }; diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h index 9d9e84d8d3bb..906dc7fa1008 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h +++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h @@ -66,12 +66,9 @@ (((REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdLo) & 0x1) << 2) | \ (REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdHi) & 0x03)) -bool umc_v12_0_is_deferred_error(struct amdgpu_device *adev, uint64_t mc_umc_status); bool umc_v12_0_is_uncorrectable_error(struct amdgpu_device *adev, uint64_t mc_umc_status); bool umc_v12_0_is_correctable_error(struct amdgpu_device *adev, uint64_t mc_umc_status); -typedef bool (*check_error_type_func)(struct amdgpu_device *adev, uint64_t mc_umc_status); - extern struct amdgpu_umc_ras umc_v12_0_ras; #endif diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 5715b6b596af..514715793f78 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -34,6 +34,7 @@ #include "amdgpu_ucode.h" #include "atom.h" #include "amd_pcie.h" +#include "amdgpu_video_codecs.h" #include "gmc/gmc_8_1_d.h" #include "gmc/gmc_8_1_sh_mask.h" diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 411ee894f623..2c1a936459ac 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -3303,6 +3303,11 @@ static int kfd_ioctl_create_process(struct file *filep, struct kfd_process *p, v } filep->private_data = process; + ret = kfd_debugfs_add_process(process); + if (ret) + pr_warn("Failed to create debugfs entry for the kfd_process, ret = %d\n", + ret); + mutex_unlock(&kfd_processes_mutex); ret = kfd_create_process_sysfs(process); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c index 7d4e07452cdb..464836f2a53f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c @@ -33,6 +33,7 @@ static struct list_head procs; struct debugfs_proc_entry { struct list_head list; struct dentry *proc_dentry; + struct kfd_process *process; pid_t pid; }; @@ -140,34 +141,97 @@ static const struct file_operations kfd_debugfs_pasid_fops = { .read = kfd_debugfs_pasid_read, }; -void kfd_debugfs_add_process(struct kfd_process *p) +/* This helper locates the debugfs entry of a kfd process */ +static struct debugfs_proc_entry *kfd_debugfs_find_process_entry(struct kfd_process *p) { + struct debugfs_proc_entry *entry; + + list_for_each_entry(entry, &procs, list) { + if (entry->process == p) + return entry; + } + + return NULL; +} + +/* This helper creates pasid file of a kfd process under debugfs */ +static void kfd_debugfs_create_pasid_files(struct kfd_process *p, + struct dentry *dir) +{ + char name[MAX_DEBUGFS_FILENAME_LEN]; + struct kfd_process_device *pdd; int i; + + /* create pasid file for each GPU */ + for (i = 0; i < p->n_pdds; i++) { + pdd = p->pdds[i]; + snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "pasid_%u", pdd->dev->id); + debugfs_create_file((const char *)name, S_IFREG | 0444, + dir, pdd, &kfd_debugfs_pasid_fops); + } +} + +int kfd_debugfs_add_process(struct kfd_process *p) +{ + struct debugfs_proc_entry *primary_entry; char name[MAX_DEBUGFS_FILENAME_LEN]; + struct kfd_process *primary_process; struct debugfs_proc_entry *entry; + int ret; entry = kzalloc_obj(*entry); if (!entry) - return; + return -ENOMEM; - list_add(&entry->list, &procs); + entry->process = p; entry->pid = p->lead_thread->pid; - snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "%d", - (int)entry->pid); - entry->proc_dentry = debugfs_create_dir(name, debugfs_proc); - /* Create debugfs files for each GPU: - * - proc/<pid>/pasid_<gpuid> - */ - for (i = 0; i < p->n_pdds; i++) { - struct kfd_process_device *pdd = p->pdds[i]; + if (p->context_id == KFD_CONTEXT_ID_PRIMARY) { + snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "%d", + (int)entry->pid); + entry->proc_dentry = debugfs_create_dir(name, debugfs_proc); + } else { + primary_process = kfd_lookup_process_by_mm(p->lead_thread->mm); + if (!primary_process) { + ret = -ESRCH; + goto err_free_entry; + } - snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "pasid_%u", - pdd->dev->id); - debugfs_create_file((const char *)name, S_IFREG | 0444, - entry->proc_dentry, pdd, - &kfd_debugfs_pasid_fops); + primary_entry = kfd_debugfs_find_process_entry(primary_process); + kfd_unref_process(primary_process); + if (!primary_entry) { + pr_warn("Failed to find the primary debugfs entry for pid %d\n", + entry->pid); + ret = -ENOENT; + goto err_free_entry; + } + + snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "context_%u", + p->context_id); + entry->proc_dentry = debugfs_create_dir(name, + primary_entry->proc_dentry); } + if (IS_ERR_OR_NULL(entry->proc_dentry)) { + ret = entry->proc_dentry ? PTR_ERR(entry->proc_dentry) : -ENOMEM; + goto err_free_entry; + } + + list_add(&entry->list, &procs); + kfd_debugfs_create_pasid_files(p, entry->proc_dentry); + + return 0; + +err_free_entry: + kfree(entry); + return ret; +} + +/* This helper removes a debugfs entry and its sub-entries */ +static void kfd_debugfs_remove_entry(struct debugfs_proc_entry *entry) +{ + debugfs_remove(entry->proc_dentry); + list_del(&entry->list); + kfree(entry); } void kfd_debugfs_remove_process(struct kfd_process *p) @@ -175,13 +239,22 @@ void kfd_debugfs_remove_process(struct kfd_process *p) struct debugfs_proc_entry *entry, *next; mutex_lock(&kfd_processes_mutex); + if (p->context_id == KFD_CONTEXT_ID_PRIMARY) { + /* remove entries of secondary contexts */ + list_for_each_entry_safe(entry, next, &procs, list) { + if (entry->pid != p->lead_thread->pid || entry->process == p) + continue; + + kfd_debugfs_remove_entry(entry); + } + } + list_for_each_entry_safe(entry, next, &procs, list) { - if (entry->pid != p->lead_thread->pid) + if (entry->process != p) continue; - debugfs_remove_recursive(entry->proc_dentry); - list_del(&entry->list); - kfree(entry); + kfd_debugfs_remove_entry(entry); } + mutex_unlock(&kfd_processes_mutex); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 97402e6c8f83..cc42feb24277 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -3777,6 +3777,12 @@ out: dqm_unlock(dqm); return r; } + +size_t mqd_size_from_queue_type(struct device_queue_manager *dqm, enum kfd_queue_type type) +{ + return dqm->mqd_mgrs[get_mqd_type_from_queue_type(type)]->mqd_size; +} + #if defined(CONFIG_DEBUG_FS) static void seq_reg_dump(struct seq_file *m, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 2229f8b2f446..c9f9f7a87111 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -335,6 +335,8 @@ bool kfd_dqm_is_queue_in_process(struct device_queue_manager *dqm, int doorbell_off, u32 *queue_format); int kfd_reset_queue_mes(struct device_queue_manager *dqm, int queue_type, int pipe, int queue, unsigned int db); +size_t mqd_size_from_queue_type(struct device_queue_manager *dqm, + enum kfd_queue_type type); static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index dae01e2bb464..f5fd78f0df7d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -61,6 +61,9 @@ static int allocate_event_notification_slot(struct kfd_process *p, return -ENOMEM; if (restore_id) { + if (*restore_id >= KFD_SIGNAL_EVENT_LIMIT) + return -EINVAL; + id = idr_alloc(&p->event_idr, ev, *restore_id, *restore_id + 1, GFP_KERNEL); } else { @@ -158,7 +161,7 @@ static int create_signal_event(struct file *devkfd, struct kfd_process *p, ret = allocate_event_notification_slot(p, ev, restore_id); if (ret) { - pr_warn("Signal event wasn't created because out of kernel memory\n"); + pr_warn("Failed to create signal event notification slot\n"); return ret; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 90f010cbe54e..88191a4c1657 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -32,6 +32,7 @@ #include <linux/atomic.h> #include <linux/workqueue.h> #include <linux/spinlock.h> +#include <linux/iosys-map.h> #include <uapi/linux/kfd_ioctl.h> #include <linux/idr.h> #include <linux/kfifo.h> @@ -440,7 +441,8 @@ enum kfd_queue_type { KFD_QUEUE_TYPE_SDMA, KFD_QUEUE_TYPE_HIQ, KFD_QUEUE_TYPE_SDMA_XGMI, - KFD_QUEUE_TYPE_SDMA_BY_ENG_ID + KFD_QUEUE_TYPE_SDMA_BY_ENG_ID, + KFD_QUEUE_TYPE_MAX, }; enum kfd_queue_format { @@ -710,7 +712,7 @@ struct qcm_process_device { /* CWSR memory */ struct kgd_mem *cwsr_mem; - void *cwsr_kaddr; + struct iosys_map cwsr_map; uint64_t cwsr_base; uint64_t tba_addr; uint64_t tma_addr; @@ -1649,14 +1651,14 @@ int kfd_debugfs_hang_hws(struct kfd_node *dev); int pm_debugfs_hang_hws(struct packet_manager *pm); int dqm_debugfs_hang_hws(struct device_queue_manager *dqm); -void kfd_debugfs_add_process(struct kfd_process *p); +int kfd_debugfs_add_process(struct kfd_process *p); void kfd_debugfs_remove_process(struct kfd_process *p); #else static inline void kfd_debugfs_init(void) {} static inline void kfd_debugfs_fini(void) {} -static inline void kfd_debugfs_add_process(struct kfd_process *p) {} +static inline int kfd_debugfs_add_process(struct kfd_process *p) { return 0; } static inline void kfd_debugfs_remove_process(struct kfd_process *p) {} #endif diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 767c2cc8e29e..eb508fe3ded7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -33,6 +33,7 @@ #include <linux/mman.h> #include <linux/file.h> #include <linux/pm_runtime.h> +#include <drm/ttm/ttm_bo.h> #include "amdgpu_amdkfd.h" #include "amdgpu.h" #include "amdgpu_reset.h" @@ -745,6 +746,22 @@ static void kfd_process_free_gpuvm(struct kgd_mem *mem, NULL); } +static void kfd_process_free_gpuvm_map(struct kgd_mem *mem, + struct kfd_process_device *pdd, + struct iosys_map *map) +{ + struct kfd_node *dev = pdd->dev; + + if (map && !iosys_map_is_null(map)) { + amdgpu_amdkfd_gpuvm_unmap_bo_from_kernel(mem); + iosys_map_clear(map); + } + + amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->adev, mem, pdd->drm_priv); + amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, mem, pdd->drm_priv, + NULL); +} + /* kfd_process_alloc_gpuvm - Allocate GPU VM for the KFD process * This function should be only called right after the process * is created and when kfd_processes_mutex is still being held @@ -931,7 +948,7 @@ static void kfd_process_free_id(struct kfd_process *process) { struct kfd_process *primary_process; - if (process->context_id != KFD_CONTEXT_ID_PRIMARY) + if (process->context_id == KFD_CONTEXT_ID_PRIMARY) return; primary_process = kfd_lookup_process_by_mm(process->lead_thread->mm); @@ -996,7 +1013,10 @@ struct kfd_process *kfd_create_process(struct task_struct *thread) if (ret) pr_warn("Failed to create sysfs entry for the kfd_process"); - kfd_debugfs_add_process(process); + ret = kfd_debugfs_add_process(process); + if (ret) + pr_warn("Failed to create debugfs entry for the kfd_process, ret = %d\n", + ret); init_waitqueue_head(&process->wait_irq_drain); } @@ -1186,9 +1206,9 @@ static void kfd_process_destroy_pdds(struct kfd_process *p) if (pdd->drm_file) fput(pdd->drm_file); - if (pdd->qpd.cwsr_kaddr && !pdd->qpd.cwsr_base) - free_pages((unsigned long)pdd->qpd.cwsr_kaddr, - get_order(KFD_CWSR_TBA_TMA_SIZE)); + if (!iosys_map_is_null(&pdd->qpd.cwsr_map) && !pdd->qpd.cwsr_base) + free_pages((unsigned long)pdd->qpd.cwsr_map.vaddr, + get_order(KFD_CWSR_TBA_TMA_SIZE)); idr_destroy(&pdd->alloc_idr); @@ -1495,7 +1515,7 @@ static int kfd_process_device_init_cwsr_dgpu(struct kfd_process_device *pdd) void *kaddr; int ret; - if (!dev->kfd->cwsr_enabled || qpd->cwsr_kaddr || !qpd->cwsr_base) + if (!dev->kfd->cwsr_enabled || !iosys_map_is_null(&qpd->cwsr_map) || !qpd->cwsr_base) return 0; if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 4, 2) && !dev->adev->apu_prefer_gtt) @@ -1510,17 +1530,28 @@ static int kfd_process_device_init_cwsr_dgpu(struct kfd_process_device *pdd) return ret; qpd->cwsr_mem = mem; - qpd->cwsr_kaddr = kaddr; + + /* Set up iosys_map based on whether memory is MMIO or system memory */ + if (mem->bo->kmap.bo_kmap_type & TTM_BO_MAP_IOMEM_MASK) + iosys_map_set_vaddr_iomem(&qpd->cwsr_map, kaddr); + else + iosys_map_set_vaddr(&qpd->cwsr_map, kaddr); + qpd->tba_addr = qpd->cwsr_base; - memcpy(qpd->cwsr_kaddr, dev->kfd->cwsr_isa, dev->kfd->cwsr_isa_size); + /* Copy CWSR ISA to buffer using appropriate accessor */ + iosys_map_memcpy_to(&qpd->cwsr_map, 0, dev->kfd->cwsr_isa, + dev->kfd->cwsr_isa_size); kfd_process_set_trap_debug_flag(&pdd->qpd, pdd->process->debug_trap_enabled); qpd->tma_addr = qpd->tba_addr + KFD_CWSR_TMA_OFFSET; - pr_debug("set tba :0x%llx, tma:0x%llx, cwsr_kaddr:%p for pqm.\n", - qpd->tba_addr, qpd->tma_addr, qpd->cwsr_kaddr); + pr_debug("set tba :0x%llx, tma:0x%llx, cwsr_map:%s at %p for pqm.\n", + qpd->tba_addr, qpd->tma_addr, + qpd->cwsr_map.is_iomem ? "iomem" : "system", + qpd->cwsr_map.is_iomem ? (void *)qpd->cwsr_map.vaddr_iomem : + qpd->cwsr_map.vaddr); return 0; } @@ -1530,24 +1561,24 @@ static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd) struct kfd_node *dev = pdd->dev; struct qcm_process_device *qpd = &pdd->qpd; - if (!dev->kfd->cwsr_enabled || !qpd->cwsr_kaddr || !qpd->cwsr_base) + if (!dev->kfd->cwsr_enabled || iosys_map_is_null(&qpd->cwsr_map) || !qpd->cwsr_base) return; - kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, &qpd->cwsr_kaddr); + kfd_process_free_gpuvm_map(qpd->cwsr_mem, pdd, &qpd->cwsr_map); } void kfd_process_set_trap_handler(struct qcm_process_device *qpd, uint64_t tba_addr, uint64_t tma_addr) { - if (qpd->cwsr_kaddr) { + if (!iosys_map_is_null(&qpd->cwsr_map)) { /* KFD trap handler is bound, record as second-level TBA/TMA * in first-level TMA. First-level trap will jump to second. */ - uint64_t *tma = - (uint64_t *)(qpd->cwsr_kaddr + KFD_CWSR_TMA_OFFSET); - tma[0] = tba_addr; - tma[1] = tma_addr; + iosys_map_wr(&qpd->cwsr_map, KFD_CWSR_TMA_OFFSET, + uint64_t, tba_addr); + iosys_map_wr(&qpd->cwsr_map, KFD_CWSR_TMA_OFFSET + sizeof(uint64_t), + uint64_t, tma_addr); } else { /* No trap handler bound, bind as first-level TBA/TMA. */ qpd->tba_addr = tba_addr; @@ -1613,10 +1644,10 @@ bool kfd_process_xnack_mode(struct kfd_process *p, bool supported) void kfd_process_set_trap_debug_flag(struct qcm_process_device *qpd, bool enabled) { - if (qpd->cwsr_kaddr) { - uint64_t *tma = - (uint64_t *)(qpd->cwsr_kaddr + KFD_CWSR_TMA_OFFSET); - tma[2] = enabled; + if (!iosys_map_is_null(&qpd->cwsr_map)) { + iosys_map_wr(&qpd->cwsr_map, + KFD_CWSR_TMA_OFFSET + 2 * sizeof(uint64_t), + uint64_t, enabled); } } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index acbdca91cde5..97e77a5a35e5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -265,6 +265,11 @@ static int init_user_queue(struct process_queue_manager *pqm, (*q)->process = pqm->process; if (dev->kfd->shared_resources.enable_mes) { + if (!q_properties->wptr_bo) { + pr_debug("Queue initialization with shared MES requires queue buffers to be initialized\n"); + return -EINVAL; + } + retval = amdgpu_amdkfd_alloc_kernel_mem(dev->adev, AMDGPU_MES_GANG_CTX_SIZE, AMDGPU_GEM_DOMAIN_GTT, @@ -1003,6 +1008,23 @@ int kfd_criu_restore_queue(struct kfd_process *p, goto exit; } + pdd = kfd_process_device_data_by_id(p, q_data->gpu_id); + if (!pdd) { + pr_err("Failed to get pdd\n"); + ret = -EINVAL; + goto exit; + } + + if (q_data->type >= KFD_QUEUE_TYPE_MAX) { + ret = -EINVAL; + goto exit; + } + + if (q_data->mqd_size != mqd_size_from_queue_type(pdd->dev->dqm, q_data->type)) { + ret = -EINVAL; + goto exit; + } + *priv_data_offset += sizeof(*q_data); q_extra_data_size = (uint64_t)q_data->ctl_stack_size + q_data->mqd_size; @@ -1025,13 +1047,6 @@ int kfd_criu_restore_queue(struct kfd_process *p, *priv_data_offset += q_extra_data_size; - pdd = kfd_process_device_data_by_id(p, q_data->gpu_id); - if (!pdd) { - pr_err("Failed to get pdd\n"); - ret = -EINVAL; - goto exit; - } - /* * data stored in this order: * mqd[xcc0], mqd[xcc1],..., ctl_stack[xcc0], ctl_stack[xcc1]... @@ -1042,24 +1057,10 @@ int kfd_criu_restore_queue(struct kfd_process *p, memset(&qp, 0, sizeof(qp)); set_queue_properties_from_criu(&qp, q_data, NUM_XCC(pdd->dev->xcc_mask)); - ret = kfd_queue_acquire_buffers(pdd, &qp); - if (ret) { - pr_debug("failed to acquire user queue buffers for CRIU\n"); - goto exit; - } - - ret = kfd_queue_acquire_buffers(pdd, &qp); - if (ret) { - pr_debug("failed to acquire user queue buffers for CRIU\n"); - goto exit; - } - print_queue_properties(&qp); ret = pqm_create_queue(&p->pqm, pdd->dev, &qp, &queue_id, q_data, mqd, ctl_stack, NULL); if (ret) { - kfd_queue_unref_bo_vas(pdd, &qp); - kfd_queue_release_buffers(pdd, &qp); pr_err("Failed to create new queue err:%d\n", ret); goto exit; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c index 0aa99d1a542f..2692d1890ba2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c @@ -799,8 +799,8 @@ int amdgpu_dm_process_dmub_aux_transfer_sync( /*write req may receive a byte indicating partially written number as well*/ if (p_notify->aux_reply.length && payload->data) { /* Bound the reply to the scratch buffer it was read into. */ - ret = min((uint32_t)p_notify->aux_reply.length, - (uint32_t)sizeof(p_notify->aux_reply.data)); + ret = min_t(uint32_t, p_notify->aux_reply.length, + sizeof(p_notify->aux_reply.data)); /* * During a write-status-update retry the caller zeroes @@ -809,7 +809,7 @@ int amdgpu_dm_process_dmub_aux_transfer_sync( * so only clamp to payload->length for regular transfers. */ if (!payload->write_status_update) - ret = min(ret, payload->length); + ret = min_t(int, ret, payload->length); memcpy(payload->data, p_notify->aux_reply.data, ret); } else { diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index f76ba6753551..c09c60ad3f38 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -2110,10 +2110,3 @@ ssize_t amdgpu_dpm_get_xcp_metrics(struct amdgpu_device *adev, int xcp_id, return ret; } - -const struct ras_smu_drv *amdgpu_dpm_get_ras_smu_driver(struct amdgpu_device *adev) -{ - void *pp_handle = adev->powerplay.pp_handle; - - return smu_get_ras_smu_driver(pp_handle); -} diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index aa3f427819a0..c7ea29385682 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -612,6 +612,5 @@ int amdgpu_dpm_reset_vcn(struct amdgpu_device *adev, uint32_t inst_mask); bool amdgpu_dpm_reset_vcn_is_supported(struct amdgpu_device *adev); bool amdgpu_dpm_is_temp_metrics_supported(struct amdgpu_device *adev, enum smu_temp_metric_type type); -const struct ras_smu_drv *amdgpu_dpm_get_ras_smu_driver(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 541cf0a985eb..504fd9762a8e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -801,6 +801,7 @@ static int smu_set_funcs(struct amdgpu_device *adev) break; case IP_VERSION(15, 0, 0): case IP_VERSION(15, 0, 5): + case IP_VERSION(15, 0, 9): smu_v15_0_0_set_ppt_funcs(smu); break; case IP_VERSION(15, 0, 8): @@ -2817,17 +2818,6 @@ const struct amdgpu_ip_block_version smu_v15_0_ip_block = { .funcs = &smu_ip_funcs, }; -const struct ras_smu_drv *smu_get_ras_smu_driver(void *handle) -{ - struct smu_context *smu = (struct smu_context *)handle; - const struct ras_smu_drv *tmp = NULL; - int ret; - - ret = smu_get_ras_smu_drv(smu, &tmp); - - return ret ? NULL : tmp; -} - static int smu_load_microcode(void *handle) { struct smu_context *smu = handle; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 378781c05bea..f8fd93999617 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -1618,13 +1618,6 @@ struct pptable_funcs { */ int (*ras_send_msg)(struct smu_context *smu, enum smu_message_type msg, uint32_t param, uint32_t *read_arg); - - - /** - * @get_ras_smu_drv: Get RAS smu driver interface - * Return: ras_smu_drv * - */ - int (*get_ras_smu_drv)(struct smu_context *smu, const struct ras_smu_drv **ras_smu_drv); }; typedef enum { @@ -1972,7 +1965,6 @@ int smu_set_pm_policy(struct smu_context *smu, enum pp_pm_policy p_type, int level); ssize_t smu_get_pm_policy_info(struct smu_context *smu, enum pp_pm_policy p_type, char *sysbuf); -const struct ras_smu_drv *smu_get_ras_smu_driver(void *handle); int amdgpu_smu_ras_send_msg(struct amdgpu_device *adev, enum smu_message_type msg, uint32_t param, uint32_t *readarg); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c index dea27fcb2b20..ecdbf9bb8eb7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c @@ -1017,133 +1017,3 @@ const struct smu_temp_funcs smu_v13_0_12_temp_funcs = { .temp_metrics_is_supported = smu_v13_0_12_is_temp_metrics_supported, .get_temp_metrics = smu_v13_0_12_get_temp_metrics, }; - -static int smu_v13_0_12_get_ras_table_version(struct amdgpu_device *adev, - uint32_t *table_version) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - - return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetRASTableVersion, 0, table_version); -} - -static int smu_v13_0_12_get_badpage_count(struct amdgpu_device *adev, uint32_t *count, - uint32_t timeout) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - uint64_t end, now; - int ret = 0; - - now = (uint64_t)ktime_to_ms(ktime_get()); - end = now + timeout; - do { - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetBadPageCount, 0, count); - /* eeprom is not ready */ - if (ret != -EBUSY) - return ret; - usleep_range(10000, 15000); - now = (uint64_t)ktime_to_ms(ktime_get()); - } while (now < end); - - dev_err(adev->dev, - "smu get bad page count timeout!\n"); - return ret; -} - -static int smu_v13_0_12_set_timestamp(struct amdgpu_device *adev, uint64_t timestamp) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - - return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_SetTimestamp, (uint32_t)timestamp, 0); -} - -static int smu_v13_0_12_get_timestamp(struct amdgpu_device *adev, - uint16_t index, uint64_t *timestamp) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - uint32_t temp; - int ret; - - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetTimestamp, index, &temp); - if (!ret) - *timestamp = temp; - - return ret; -} - -static int smu_v13_0_12_get_badpage_ipid(struct amdgpu_device *adev, - uint16_t index, uint64_t *ipid) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - uint32_t temp_arg, temp_ipid_lo, temp_ipid_high; - int ret; - - temp_arg = index | (1 << 16); - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetBadPageIpid, temp_arg, &temp_ipid_lo); - if (ret) - return ret; - - temp_arg = index | (2 << 16); - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetBadPageIpid, temp_arg, &temp_ipid_high); - if (!ret) - *ipid = (uint64_t)temp_ipid_high << 32 | temp_ipid_lo; - return ret; -} - -static int smu_v13_0_12_erase_ras_table(struct amdgpu_device *adev, - uint32_t *result) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - - return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_EraseRasTable, 0, result); -} - -static int smu_v13_0_12_get_badpage_mca_addr(struct amdgpu_device *adev, - uint16_t index, uint64_t *mca_addr) -{ - struct smu_context *smu = adev->powerplay.pp_handle; - uint32_t temp_arg, temp_addr_lo, temp_addr_high; - int ret; - - temp_arg = index | (1 << 16); - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetBadPageMcaAddr, temp_arg, &temp_addr_lo); - if (ret) - return ret; - - temp_arg = index | (2 << 16); - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetBadPageMcaAddr, temp_arg, &temp_addr_high); - if (!ret) - *mca_addr = (uint64_t)temp_addr_high << 32 | temp_addr_lo; - return ret; -} - -static const struct ras_eeprom_smu_funcs smu_v13_0_12_eeprom_smu_funcs = { - .get_ras_table_version = smu_v13_0_12_get_ras_table_version, - .get_badpage_count = smu_v13_0_12_get_badpage_count, - .get_badpage_mca_addr = smu_v13_0_12_get_badpage_mca_addr, - .set_timestamp = smu_v13_0_12_set_timestamp, - .get_timestamp = smu_v13_0_12_get_timestamp, - .get_badpage_ipid = smu_v13_0_12_get_badpage_ipid, - .erase_ras_table = smu_v13_0_12_erase_ras_table, -}; - -static void smu_v13_0_12_ras_smu_feature_flags(struct amdgpu_device *adev, uint64_t *flags) -{ - if (!flags) - return; - - *flags = 0ULL; -} - -const struct ras_smu_drv smu_v13_0_12_ras_smu_drv = { - .smu_eeprom_funcs = &smu_v13_0_12_eeprom_smu_funcs, - .ras_smu_feature_flags = smu_v13_0_12_ras_smu_feature_flags, -}; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 334c92a28994..64db62a8d642 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -3273,26 +3273,6 @@ static void smu_v13_0_6_set_temp_funcs(struct smu_context *smu) == IP_VERSION(13, 0, 12)) ? &smu_v13_0_12_temp_funcs : NULL; } -static int smu_v13_0_6_get_ras_smu_drv(struct smu_context *smu, const struct ras_smu_drv **ras_smu_drv) -{ - if (!ras_smu_drv) - return -EINVAL; - - if (amdgpu_sriov_vf(smu->adev)) - return -EOPNOTSUPP; - - switch (amdgpu_ip_version(smu->adev, MP1_HWIP, 0)) { - case IP_VERSION(13, 0, 12): - *ras_smu_drv = &smu_v13_0_12_ras_smu_drv; - break; - default: - *ras_smu_drv = NULL; - break; - } - - return 0; -} - static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { /* init dpm */ .init_allowed_features = smu_v13_0_6_init_allowed_features, @@ -3351,7 +3331,6 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { .dpm_reset_vcn = smu_v13_0_6_reset_vcn, .post_init = smu_v13_0_6_post_init, .ras_send_msg = smu_v13_0_6_ras_send_msg, - .get_ras_smu_drv = smu_v13_0_6_get_ras_smu_drv, }; void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h index a150fc88902c..a66bf33dbb58 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h @@ -117,7 +117,6 @@ int smu_v13_0_12_get_system_power(struct smu_context *smu, extern const struct cmn2asic_mapping smu_v13_0_12_feature_mask_map[]; extern const struct cmn2asic_msg_mapping smu_v13_0_12_message_map[]; extern const struct smu_temp_funcs smu_v13_0_12_temp_funcs; -extern const struct ras_smu_drv smu_v13_0_12_ras_smu_drv; #if defined(SWSMU_CODE_LAYER_L2) #include "smu_cmn.h" diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c index d6cf643205ab..0fbcaf884419 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c @@ -1621,19 +1621,23 @@ static int smu_v14_0_2_get_power_limit(struct smu_context *smu, table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; CustomSkuTable_t *skutable = &pptable->CustomSkuTable; - int16_t od_percent_upper = 0, od_percent_lower = 0; + uint32_t pp_limit = smu->adev->pm.ac_power ? + skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] : + skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0]; uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; - uint32_t power_limit; + uint32_t min_limit = min_t(uint32_t, pp_limit, msg_limit); + uint32_t max_limit = max_t(uint32_t, pp_limit, msg_limit); + int16_t od_percent_upper = 0, od_percent_lower = 0; + int ret; - if (smu_v14_0_get_current_power_limit(smu, &power_limit)) - power_limit = smu->adev->pm.ac_power ? - skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] : - skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0]; + if (current_power_limit) { + ret = smu_v14_0_get_current_power_limit(smu, current_power_limit); + if (ret) + *current_power_limit = pp_limit; + } - if (current_power_limit) - *current_power_limit = power_limit; if (default_power_limit) - *default_power_limit = power_limit; + *default_power_limit = pp_limit; if (powerplay_table) { if (smu->od_enabled && @@ -1647,15 +1651,15 @@ static int smu_v14_0_2_get_power_limit(struct smu_context *smu, } 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); + od_percent_upper, od_percent_lower, pp_limit); if (max_power_limit) { - *max_power_limit = msg_limit * (100 + od_percent_upper); + *max_power_limit = max_limit * (100 + od_percent_upper); *max_power_limit /= 100; } if (min_power_limit) { - *min_power_limit = power_limit * (100 + od_percent_lower); + *min_power_limit = min_limit * (100 + od_percent_lower); *min_power_limit /= 100; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c index f3fb6ed4bc95..046069e93854 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c @@ -583,6 +583,7 @@ int smu_v15_0_gfx_off_control(struct smu_context *smu, bool enable) switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(15, 0, 0): + case IP_VERSION(15, 0, 9): if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) return 0; if (enable) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index a214ddbd4c86..bb8d09e73c7d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -1177,7 +1177,8 @@ static int smu_v15_0_common_get_dpm_profile_freq(struct smu_context *smu, smu_v15_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &clk_limit); break; case SMU_FCLK: - if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 0)) + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 0) || + amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 9)) smu_v15_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &clk_limit); else clk_limit = SMU_15_0_UMD_PSTATE_FCLK; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h index 24848da90234..45e3758e9ed8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h @@ -98,7 +98,6 @@ #define smu_is_asic_wbrf_supported(smu) smu_ppt_funcs(is_asic_wbrf_supported, false, smu) #define smu_enable_uclk_shadow(smu, enable) smu_ppt_funcs(enable_uclk_shadow, 0, smu, enable) #define smu_set_wbrf_exclusion_ranges(smu, freq_band_range) smu_ppt_funcs(set_wbrf_exclusion_ranges, -EOPNOTSUPP, smu, freq_band_range) -#define smu_get_ras_smu_drv(smu, ras_smu_drv) smu_ppt_funcs(get_ras_smu_drv, -EOPNOTSUPP, smu, ras_smu_drv) #endif #endif |
