drm/amdgpu: fix VRAM partially encroached issue in GDDR6 memory training(V2)
[why] In GDDR6 BIST training, a certain mount of bottom VRAM will be encroached by UMC, that causes problems(like GTT corrupted and page fault observed). [how] Saving the content of this bottom VRAM to system memory before training, and restoring it after training to avoid VRAM corruption. Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Tianci.Yin <tianci.yin@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
a9d4fe2fd6
commit
240c811ccd
@ -172,6 +172,8 @@ struct psp_dtm_context {
|
|||||||
#define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942
|
#define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942
|
||||||
#define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES 0x1000
|
#define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES 0x1000
|
||||||
#define GDDR6_MEM_TRAINING_OFFSET 0x8000
|
#define GDDR6_MEM_TRAINING_OFFSET 0x8000
|
||||||
|
/*Define the VRAM size that will be encroached by BIST training.*/
|
||||||
|
#define GDDR6_MEM_TRAINING_ENCROACHED_SIZE 0x2000000
|
||||||
|
|
||||||
enum psp_memory_training_init_flag {
|
enum psp_memory_training_init_flag {
|
||||||
PSP_MEM_TRAIN_NOT_SUPPORT = 0x0,
|
PSP_MEM_TRAIN_NOT_SUPPORT = 0x0,
|
||||||
|
@ -971,10 +971,13 @@ Err_out:
|
|||||||
*/
|
*/
|
||||||
static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
|
static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
uint32_t p2c_header[4];
|
|
||||||
struct psp_memory_training_context *ctx = &psp->mem_train_ctx;
|
struct psp_memory_training_context *ctx = &psp->mem_train_ctx;
|
||||||
uint32_t *pcache = (uint32_t*)ctx->sys_cache;
|
uint32_t *pcache = (uint32_t*)ctx->sys_cache;
|
||||||
|
struct amdgpu_device *adev = psp->adev;
|
||||||
|
uint32_t p2c_header[4];
|
||||||
|
uint32_t sz;
|
||||||
|
void *buf;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) {
|
if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) {
|
||||||
DRM_DEBUG("Memory training is not supported.\n");
|
DRM_DEBUG("Memory training is not supported.\n");
|
||||||
@ -989,7 +992,7 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false);
|
amdgpu_device_vram_access(adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false);
|
||||||
DRM_DEBUG("sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n",
|
DRM_DEBUG("sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n",
|
||||||
pcache[0], pcache[1], pcache[2], pcache[3],
|
pcache[0], pcache[1], pcache[2], pcache[3],
|
||||||
p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]);
|
p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]);
|
||||||
@ -1026,11 +1029,38 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
|
|||||||
DRM_DEBUG("Memory training ops:%x.\n", ops);
|
DRM_DEBUG("Memory training ops:%x.\n", ops);
|
||||||
|
|
||||||
if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) {
|
if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) {
|
||||||
|
/*
|
||||||
|
* Long traing will encroach certain mount of bottom VRAM,
|
||||||
|
* saving the content of this bottom VRAM to system memory
|
||||||
|
* before training, and restoring it after training to avoid
|
||||||
|
* VRAM corruption.
|
||||||
|
*/
|
||||||
|
sz = GDDR6_MEM_TRAINING_ENCROACHED_SIZE;
|
||||||
|
|
||||||
|
if (adev->gmc.visible_vram_size < sz || !adev->mman.aper_base_kaddr) {
|
||||||
|
DRM_ERROR("visible_vram_size %llx or aper_base_kaddr %p is not initialized.\n",
|
||||||
|
adev->gmc.visible_vram_size,
|
||||||
|
adev->mman.aper_base_kaddr);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = vmalloc(sz);
|
||||||
|
if (!buf) {
|
||||||
|
DRM_ERROR("failed to allocate system memory.\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz);
|
||||||
ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);
|
ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("Send long training msg failed.\n");
|
DRM_ERROR("Send long training msg failed.\n");
|
||||||
|
vfree(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy_toio(adev->mman.aper_base_kaddr, buf, sz);
|
||||||
|
adev->nbio.funcs->hdp_flush(adev, NULL);
|
||||||
|
vfree(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ops & PSP_MEM_TRAIN_SAVE) {
|
if (ops & PSP_MEM_TRAIN_SAVE) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user