drm/radeon: implement pci config reset for CIK (v3)
pci config reset is a low level reset that resets the entire chip from the bus interface. It can be more reliable if soft reset fails. v2: fix rebase v3: hide behind module parameter Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4a5c8ea59f
commit
0279ed19bd
|
@ -4880,6 +4880,160 @@ static void cik_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
|
|||
cik_print_gpu_status_regs(rdev);
|
||||
}
|
||||
|
||||
struct kv_reset_save_regs {
|
||||
u32 gmcon_reng_execute;
|
||||
u32 gmcon_misc;
|
||||
u32 gmcon_misc3;
|
||||
};
|
||||
|
||||
static void kv_save_regs_for_reset(struct radeon_device *rdev,
|
||||
struct kv_reset_save_regs *save)
|
||||
{
|
||||
save->gmcon_reng_execute = RREG32(GMCON_RENG_EXECUTE);
|
||||
save->gmcon_misc = RREG32(GMCON_MISC);
|
||||
save->gmcon_misc3 = RREG32(GMCON_MISC3);
|
||||
|
||||
WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute & ~RENG_EXECUTE_ON_PWR_UP);
|
||||
WREG32(GMCON_MISC, save->gmcon_misc & ~(RENG_EXECUTE_ON_REG_UPDATE |
|
||||
STCTRL_STUTTER_EN));
|
||||
}
|
||||
|
||||
static void kv_restore_regs_for_reset(struct radeon_device *rdev,
|
||||
struct kv_reset_save_regs *save)
|
||||
{
|
||||
int i;
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0x200010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0x300010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x210000);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0xa00010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x21003);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0xb00010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x2b00);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0xc00010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0xd00010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x420000);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0x100010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x120202);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0x500010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x3e3e36);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0x600010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x373f3e);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0x700010ff);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
WREG32(GMCON_PGFSM_WRITE, 0);
|
||||
|
||||
WREG32(GMCON_PGFSM_WRITE, 0x3e1332);
|
||||
WREG32(GMCON_PGFSM_CONFIG, 0xe00010ff);
|
||||
|
||||
WREG32(GMCON_MISC3, save->gmcon_misc3);
|
||||
WREG32(GMCON_MISC, save->gmcon_misc);
|
||||
WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute);
|
||||
}
|
||||
|
||||
static void cik_gpu_pci_config_reset(struct radeon_device *rdev)
|
||||
{
|
||||
struct evergreen_mc_save save;
|
||||
struct kv_reset_save_regs kv_save = { 0 };
|
||||
u32 tmp, i;
|
||||
|
||||
dev_info(rdev->dev, "GPU pci config reset\n");
|
||||
|
||||
/* disable dpm? */
|
||||
|
||||
/* disable cg/pg */
|
||||
cik_fini_pg(rdev);
|
||||
cik_fini_cg(rdev);
|
||||
|
||||
/* Disable GFX parsing/prefetching */
|
||||
WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
|
||||
|
||||
/* Disable MEC parsing/prefetching */
|
||||
WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT);
|
||||
|
||||
/* sdma0 */
|
||||
tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET);
|
||||
tmp |= SDMA_HALT;
|
||||
WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp);
|
||||
/* sdma1 */
|
||||
tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET);
|
||||
tmp |= SDMA_HALT;
|
||||
WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp);
|
||||
/* XXX other engines? */
|
||||
|
||||
/* halt the rlc, disable cp internal ints */
|
||||
cik_rlc_stop(rdev);
|
||||
|
||||
udelay(50);
|
||||
|
||||
/* disable mem access */
|
||||
evergreen_mc_stop(rdev, &save);
|
||||
if (evergreen_mc_wait_for_idle(rdev)) {
|
||||
dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
|
||||
}
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
kv_save_regs_for_reset(rdev, &kv_save);
|
||||
|
||||
/* disable BM */
|
||||
pci_clear_master(rdev->pdev);
|
||||
/* reset */
|
||||
radeon_pci_config_reset(rdev);
|
||||
|
||||
udelay(100);
|
||||
|
||||
/* wait for asic to come out of reset */
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
/* does asic init need to be run first??? */
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
kv_restore_regs_for_reset(rdev, &kv_save);
|
||||
}
|
||||
|
||||
/**
|
||||
* cik_asic_reset - soft reset GPU
|
||||
*
|
||||
|
@ -4898,10 +5052,17 @@ int cik_asic_reset(struct radeon_device *rdev)
|
|||
if (reset_mask)
|
||||
r600_set_bios_scratch_engine_hung(rdev, true);
|
||||
|
||||
/* try soft reset */
|
||||
cik_gpu_soft_reset(rdev, reset_mask);
|
||||
|
||||
reset_mask = cik_gpu_check_soft_reset(rdev);
|
||||
|
||||
/* try pci config reset */
|
||||
if (reset_mask && radeon_hard_reset)
|
||||
cik_gpu_pci_config_reset(rdev);
|
||||
|
||||
reset_mask = cik_gpu_check_soft_reset(rdev);
|
||||
|
||||
if (!reset_mask)
|
||||
r600_set_bios_scratch_engine_hung(rdev, false);
|
||||
|
||||
|
|
|
@ -724,6 +724,17 @@
|
|||
|
||||
#define ATC_MISC_CG 0x3350
|
||||
|
||||
#define GMCON_RENG_EXECUTE 0x3508
|
||||
#define RENG_EXECUTE_ON_PWR_UP (1 << 0)
|
||||
#define GMCON_MISC 0x350c
|
||||
#define RENG_EXECUTE_ON_REG_UPDATE (1 << 11)
|
||||
#define STCTRL_STUTTER_EN (1 << 16)
|
||||
|
||||
#define GMCON_PGFSM_CONFIG 0x3538
|
||||
#define GMCON_PGFSM_WRITE 0x353c
|
||||
#define GMCON_PGFSM_READ 0x3540
|
||||
#define GMCON_MISC3 0x3544
|
||||
|
||||
#define MC_SEQ_CNTL_3 0x3600
|
||||
# define CAC_EN (1 << 31)
|
||||
#define MC_SEQ_G5PDX_CTRL 0x3604
|
||||
|
|
Loading…
Reference in New Issue