drm/amdgpu: Add init levels
Add init levels to define the level to which device needs to be initialized. Signed-off-by: Lijo Lazar <lijo.lazar@amd.com> Acked-by: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com> Tested-by: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
8a84d2a472
commit
14f2fe34f5
2 changed files with 88 additions and 0 deletions
|
@ -823,6 +823,24 @@ struct amdgpu_mqd {
|
||||||
struct amdgpu_mqd_prop *p);
|
struct amdgpu_mqd_prop *p);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Custom Init levels could be defined for different situations where a full
|
||||||
|
* initialization of all hardware blocks are not expected. Sample cases are
|
||||||
|
* custom init sequences after resume after S0i3/S3, reset on initialization,
|
||||||
|
* partial reset of blocks etc. Presently, this defines only two levels. Levels
|
||||||
|
* are described in corresponding struct definitions - amdgpu_init_default,
|
||||||
|
* amdgpu_init_minimal_xgmi.
|
||||||
|
*/
|
||||||
|
enum amdgpu_init_lvl_id {
|
||||||
|
AMDGPU_INIT_LEVEL_DEFAULT,
|
||||||
|
AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct amdgpu_init_level {
|
||||||
|
enum amdgpu_init_lvl_id level;
|
||||||
|
uint32_t hwini_ip_block_mask;
|
||||||
|
};
|
||||||
|
|
||||||
#define AMDGPU_RESET_MAGIC_NUM 64
|
#define AMDGPU_RESET_MAGIC_NUM 64
|
||||||
#define AMDGPU_MAX_DF_PERFMONS 4
|
#define AMDGPU_MAX_DF_PERFMONS 4
|
||||||
struct amdgpu_reset_domain;
|
struct amdgpu_reset_domain;
|
||||||
|
@ -1168,6 +1186,8 @@ struct amdgpu_device {
|
||||||
bool enforce_isolation[MAX_XCP];
|
bool enforce_isolation[MAX_XCP];
|
||||||
/* Added this mutex for cleaner shader isolation between GFX and compute processes */
|
/* Added this mutex for cleaner shader isolation between GFX and compute processes */
|
||||||
struct mutex enforce_isolation_mutex;
|
struct mutex enforce_isolation_mutex;
|
||||||
|
|
||||||
|
struct amdgpu_init_level *init_lvl;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
|
static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
|
||||||
|
@ -1621,4 +1641,6 @@ extern const struct attribute_group amdgpu_vram_mgr_attr_group;
|
||||||
extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
|
extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
|
||||||
extern const struct attribute_group amdgpu_flash_attr_group;
|
extern const struct attribute_group amdgpu_flash_attr_group;
|
||||||
|
|
||||||
|
void amdgpu_set_init_level(struct amdgpu_device *adev,
|
||||||
|
enum amdgpu_init_lvl_id lvl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -144,6 +144,50 @@ const char *amdgpu_asic_name[] = {
|
||||||
"LAST",
|
"LAST",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM - 1, 0)
|
||||||
|
/*
|
||||||
|
* Default init level where all blocks are expected to be initialized. This is
|
||||||
|
* the level of initialization expected by default and also after a full reset
|
||||||
|
* of the device.
|
||||||
|
*/
|
||||||
|
struct amdgpu_init_level amdgpu_init_default = {
|
||||||
|
.level = AMDGPU_INIT_LEVEL_DEFAULT,
|
||||||
|
.hwini_ip_block_mask = AMDGPU_IP_BLK_MASK_ALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minimal blocks needed to be initialized before a XGMI hive can be reset. This
|
||||||
|
* is used for cases like reset on initialization where the entire hive needs to
|
||||||
|
* be reset before first use.
|
||||||
|
*/
|
||||||
|
struct amdgpu_init_level amdgpu_init_minimal_xgmi = {
|
||||||
|
.level = AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
|
||||||
|
.hwini_ip_block_mask =
|
||||||
|
BIT(AMD_IP_BLOCK_TYPE_GMC) | BIT(AMD_IP_BLOCK_TYPE_SMC) |
|
||||||
|
BIT(AMD_IP_BLOCK_TYPE_COMMON) | BIT(AMD_IP_BLOCK_TYPE_IH)
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool amdgpu_ip_member_of_hwini(struct amdgpu_device *adev,
|
||||||
|
enum amd_ip_block_type block)
|
||||||
|
{
|
||||||
|
return (adev->init_lvl->hwini_ip_block_mask & (1U << block)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void amdgpu_set_init_level(struct amdgpu_device *adev,
|
||||||
|
enum amdgpu_init_lvl_id lvl)
|
||||||
|
{
|
||||||
|
switch (lvl) {
|
||||||
|
case AMDGPU_INIT_LEVEL_MINIMAL_XGMI:
|
||||||
|
adev->init_lvl = &amdgpu_init_minimal_xgmi;
|
||||||
|
break;
|
||||||
|
case AMDGPU_INIT_LEVEL_DEFAULT:
|
||||||
|
fallthrough;
|
||||||
|
default:
|
||||||
|
adev->init_lvl = &amdgpu_init_default;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev);
|
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2655,6 +2699,9 @@ static int amdgpu_device_ip_hw_init_phase1(struct amdgpu_device *adev)
|
||||||
continue;
|
continue;
|
||||||
if (adev->ip_blocks[i].status.hw)
|
if (adev->ip_blocks[i].status.hw)
|
||||||
continue;
|
continue;
|
||||||
|
if (!amdgpu_ip_member_of_hwini(
|
||||||
|
adev, adev->ip_blocks[i].version->type))
|
||||||
|
continue;
|
||||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
|
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
|
||||||
(amdgpu_sriov_vf(adev) && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)) ||
|
(amdgpu_sriov_vf(adev) && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)) ||
|
||||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
|
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
|
||||||
|
@ -2680,6 +2727,9 @@ static int amdgpu_device_ip_hw_init_phase2(struct amdgpu_device *adev)
|
||||||
continue;
|
continue;
|
||||||
if (adev->ip_blocks[i].status.hw)
|
if (adev->ip_blocks[i].status.hw)
|
||||||
continue;
|
continue;
|
||||||
|
if (!amdgpu_ip_member_of_hwini(
|
||||||
|
adev, adev->ip_blocks[i].version->type))
|
||||||
|
continue;
|
||||||
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
|
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
|
||||||
if (r) {
|
if (r) {
|
||||||
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
|
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
|
||||||
|
@ -2703,6 +2753,10 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
|
||||||
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_PSP)
|
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_PSP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!amdgpu_ip_member_of_hwini(adev,
|
||||||
|
AMD_IP_BLOCK_TYPE_PSP))
|
||||||
|
break;
|
||||||
|
|
||||||
if (!adev->ip_blocks[i].status.sw)
|
if (!adev->ip_blocks[i].status.sw)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2825,6 +2879,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
||||||
}
|
}
|
||||||
adev->ip_blocks[i].status.sw = true;
|
adev->ip_blocks[i].status.sw = true;
|
||||||
|
|
||||||
|
if (!amdgpu_ip_member_of_hwini(
|
||||||
|
adev, adev->ip_blocks[i].version->type))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
|
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
|
||||||
/* need to do common hw init early so everything is set up for gmc */
|
/* need to do common hw init early so everything is set up for gmc */
|
||||||
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
|
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
|
||||||
|
@ -4215,6 +4273,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||||
|
|
||||||
amdgpu_device_set_mcbp(adev);
|
amdgpu_device_set_mcbp(adev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By default, use default mode where all blocks are expected to be
|
||||||
|
* initialized. At present a 'swinit' of blocks is required to be
|
||||||
|
* completed before the need for a different level is detected.
|
||||||
|
*/
|
||||||
|
amdgpu_set_init_level(adev, AMDGPU_INIT_LEVEL_DEFAULT);
|
||||||
/* early init functions */
|
/* early init functions */
|
||||||
r = amdgpu_device_ip_early_init(adev);
|
r = amdgpu_device_ip_early_init(adev);
|
||||||
if (r)
|
if (r)
|
||||||
|
@ -5414,6 +5478,8 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||||
|
/* After reset, it's default init level */
|
||||||
|
amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_DEFAULT);
|
||||||
if (need_full_reset) {
|
if (need_full_reset) {
|
||||||
/* post card */
|
/* post card */
|
||||||
amdgpu_ras_set_fed(tmp_adev, false);
|
amdgpu_ras_set_fed(tmp_adev, false);
|
||||||
|
|
Loading…
Add table
Reference in a new issue