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
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCalAUTQAKCRC93/aFa7yZ
 2IwkAPsHuKk0u14lRMTj0dcB03Z47av/MUsVCn4Obt6J/sOlRgEA7Z6Oh+fo/v5f
 lk5vQUWOFHQQ4TpHlsOgtytk+PBPfwE=
 =RT1e
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Dave Airlie 2026-07-10 11:43:08 +10:00
commit e3cdab67ef
94 changed files with 972 additions and 1646 deletions

View File

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

View File

@ -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,
@ -429,106 +425,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.
*/
@ -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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, &reg_val_offs)) {
if (amdgpu_wb_get(adev, &reg_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 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_
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;
}

View File

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

View File

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

View File

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

View File

@ -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 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
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;
}

View File

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

View File

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

View File

@ -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);
"%lld new correctable hardware errors detected in %s block\n",
mcm_info->socket_id,
mcm_info->die_id,
err_info->ce_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);
}
}
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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 @@ static int vpe_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return ret;
}

View File

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

View File

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

View File

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

View File

@ -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 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int gfx_v10_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
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 */

View File

@ -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 @@ static int gfx_v11_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
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)

View File

@ -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 @@ static int gfx_v12_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
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 */

View File

@ -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 @@ static int gfx_v12_1_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err1:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err1:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
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, &reg_val_offs)) {
if (amdgpu_wb_get(adev, &reg_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 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
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;
}

View File

@ -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 @@ static int gfx_v9_4_3_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err1:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
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;
}

View File

@ -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 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
spin_unlock_irqrestore(ring_lock, flags);
error_wb_free:
amdgpu_device_wb_free(adev, status_offset);
amdgpu_wb_free(adev, status_offset);
return r;
}

View File

@ -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 @@ static int mes_v12_1_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
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;
}

View File

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

View File

@ -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 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v4_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v4_4_2_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v5_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v5_2_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

@ -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 @@ static int sdma_v7_1_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

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

View File

@ -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 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
amdgpu_ib_free(&ib, NULL);
dma_fence_put(f);
err0:
amdgpu_device_wb_free(adev, index);
amdgpu_wb_free(adev, index);
return r;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
{
int i;
char name[MAX_DEBUGFS_FILENAME_LEN];
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;
entry->process = p;
entry->pid = p->lead_thread->pid;
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;
}
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);
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);
kfd_debugfs_create_pasid_files(p, entry->proc_dentry);
/* 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];
return 0;
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);
}
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);
}

View File

@ -3777,6 +3777,12 @@ bool kfd_dqm_is_queue_in_process(struct device_queue_manager *dqm,
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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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