mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
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:
commit
e3cdab67ef
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
151
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h
Normal file
151
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h
Normal 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__ */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -1170,7 +1170,7 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_
|
|||
BUG_ON(!ring->funcs->emit_rreg);
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
if (amdgpu_device_wb_get(adev, ®_val_offs)) {
|
||||
if (amdgpu_wb_get(adev, ®_val_offs)) {
|
||||
pr_err("critical bug! too many kiq readers\n");
|
||||
goto failed_unlock;
|
||||
}
|
||||
|
|
@ -1213,7 +1213,7 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_
|
|||
|
||||
mb();
|
||||
value = adev->wb.wb[reg_val_offs];
|
||||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
amdgpu_wb_free(adev, reg_val_offs);
|
||||
return value;
|
||||
|
||||
failed_undo:
|
||||
|
|
@ -1222,7 +1222,7 @@ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
47
drivers/gpu/drm/amd/amdgpu/amdgpu_video_codecs.h
Normal file
47
drivers/gpu/drm/amd/amdgpu/amdgpu_video_codecs.h
Normal 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
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
129
drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c
Normal file
129
drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c
Normal 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);
|
||||
}
|
||||
102
drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h
Normal file
102
drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h
Normal 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
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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, ®_val_offs)) {
|
||||
if (amdgpu_wb_get(adev, ®_val_offs)) {
|
||||
pr_err("critical bug! too many kiq readers\n");
|
||||
goto failed_unlock;
|
||||
}
|
||||
|
|
@ -4315,7 +4315,7 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
|
|||
mb();
|
||||
value = (uint64_t)adev->wb.wb[reg_val_offs] |
|
||||
(uint64_t)adev->wb.wb[reg_val_offs + 1 ] << 32ULL;
|
||||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
amdgpu_wb_free(adev, reg_val_offs);
|
||||
return value;
|
||||
|
||||
failed_undo:
|
||||
|
|
@ -4324,7 +4324,7 @@ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user