Commit 054e01d6 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/radeon: save/restore the PD addr on suspend/resume

This fixes a problem with GPU resets and TLB flushes on SI/CIK.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a284e9d1
...@@ -5749,20 +5749,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) ...@@ -5749,20 +5749,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
WREG32(0x15D8, 0); WREG32(0x15D8, 0);
WREG32(0x15DC, 0); WREG32(0x15DC, 0);
/* empty context1-15 */ /* restore context1-15 */
/* FIXME start with 4G, once using 2 level pt switch to full
* vm size space
*/
/* set vm size, must be a multiple of 4 */ /* set vm size, must be a multiple of 4 */
WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
for (i = 1; i < 16; i++) { for (i = 1; i < 16; i++) {
if (i < 8) if (i < 8)
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
rdev->gart.table_addr >> 12); rdev->vm_manager.saved_table_addr[i]);
else else
WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
rdev->gart.table_addr >> 12); rdev->vm_manager.saved_table_addr[i]);
} }
/* enable context1-15 */ /* enable context1-15 */
...@@ -5827,6 +5824,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) ...@@ -5827,6 +5824,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
*/ */
static void cik_pcie_gart_disable(struct radeon_device *rdev) static void cik_pcie_gart_disable(struct radeon_device *rdev)
{ {
unsigned i;
for (i = 1; i < 16; ++i) {
uint32_t reg;
if (i < 8)
reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
else
reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
}
/* Disable all tables */ /* Disable all tables */
WREG32(VM_CONTEXT0_CNTL, 0); WREG32(VM_CONTEXT0_CNTL, 0);
WREG32(VM_CONTEXT1_CNTL, 0); WREG32(VM_CONTEXT1_CNTL, 0);
......
...@@ -1271,7 +1271,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) ...@@ -1271,7 +1271,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn);
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
rdev->gart.table_addr >> 12); rdev->vm_manager.saved_table_addr[i]);
} }
/* enable context1-7 */ /* enable context1-7 */
...@@ -1303,6 +1303,13 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) ...@@ -1303,6 +1303,13 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
static void cayman_pcie_gart_disable(struct radeon_device *rdev) static void cayman_pcie_gart_disable(struct radeon_device *rdev)
{ {
unsigned i;
for (i = 1; i < 8; ++i) {
rdev->vm_manager.saved_table_addr[i] = RREG32(
VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2));
}
/* Disable all tables */ /* Disable all tables */
WREG32(VM_CONTEXT0_CNTL, 0); WREG32(VM_CONTEXT0_CNTL, 0);
WREG32(VM_CONTEXT1_CNTL, 0); WREG32(VM_CONTEXT1_CNTL, 0);
......
...@@ -915,6 +915,8 @@ struct radeon_vm_manager { ...@@ -915,6 +915,8 @@ struct radeon_vm_manager {
u64 vram_base_offset; u64 vram_base_offset;
/* is vm enabled? */ /* is vm enabled? */
bool enabled; bool enabled;
/* for hw to save the PD addr on suspend/resume */
uint32_t saved_table_addr[RADEON_NUM_VM];
}; };
/* /*
......
...@@ -4290,10 +4290,10 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) ...@@ -4290,10 +4290,10 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
for (i = 1; i < 16; i++) { for (i = 1; i < 16; i++) {
if (i < 8) if (i < 8)
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
rdev->gart.table_addr >> 12); rdev->vm_manager.saved_table_addr[i]);
else else
WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
rdev->gart.table_addr >> 12); rdev->vm_manager.saved_table_addr[i]);
} }
/* enable context1-15 */ /* enable context1-15 */
...@@ -4325,6 +4325,17 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) ...@@ -4325,6 +4325,17 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
static void si_pcie_gart_disable(struct radeon_device *rdev) static void si_pcie_gart_disable(struct radeon_device *rdev)
{ {
unsigned i;
for (i = 1; i < 16; ++i) {
uint32_t reg;
if (i < 8)
reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
else
reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
}
/* Disable all tables */ /* Disable all tables */
WREG32(VM_CONTEXT0_CNTL, 0); WREG32(VM_CONTEXT0_CNTL, 0);
WREG32(VM_CONTEXT1_CNTL, 0); WREG32(VM_CONTEXT1_CNTL, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment