drm/radeon/kms: simplify & improve GPU reset V2
This simplify and improve GPU reset for R1XX-R6XX hw, it's not 100% reliable here are result: - R1XX/R2XX works bunch of time in a row, sometimes it seems it can work indifinitly - R3XX/R3XX the most unreliable one, sometimes you will be able to reset few times, sometimes not even once - R5XX more reliable than previous hw, seems to work most of the times but once in a while it fails for no obvious reasons (same status than previous reset just no same happy ending) - R6XX/R7XX are lot more reliable with this patch, still it seems that it can fail after a bunch (reset every 2sec for 3hour bring down the GPU & computer) This have been tested on various hw, for some odd reasons i wasn't able to lockup RS480/RS690 (while they use to love locking up). Note that on R1XX-R5XX the cursor will disapear after lockup haven't checked why, switch to console and back to X will restore cursor. Next step is to record the bogus command that leaded to the lockup. V2 Fix r6xx resume path to avoid reinitializing blit module, use the gpu_lockup boolean to avoid entering inifinite waiting loop on fence while reiniting the GPU Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
a2d07b7438
commit
90aca4d274
@ -662,26 +662,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
|
||||
if (r100_debugfs_cp_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for CP !\n");
|
||||
}
|
||||
/* Reset CP */
|
||||
tmp = RREG32(RADEON_CP_CSQ_STAT);
|
||||
if ((tmp & (1 << 31))) {
|
||||
DRM_INFO("radeon: cp busy (0x%08X) resetting\n", tmp);
|
||||
WREG32(RADEON_CP_CSQ_MODE, 0);
|
||||
WREG32(RADEON_CP_CSQ_CNTL, 0);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
|
||||
tmp = RREG32(RADEON_RBBM_SOFT_RESET);
|
||||
mdelay(2);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, 0);
|
||||
tmp = RREG32(RADEON_RBBM_SOFT_RESET);
|
||||
mdelay(2);
|
||||
tmp = RREG32(RADEON_CP_CSQ_STAT);
|
||||
if ((tmp & (1 << 31))) {
|
||||
DRM_INFO("radeon: cp reset failed (0x%08X)\n", tmp);
|
||||
}
|
||||
} else {
|
||||
DRM_INFO("radeon: cp idle (0x%08X)\n", tmp);
|
||||
}
|
||||
|
||||
if (!rdev->me_fw) {
|
||||
r = r100_cp_init_microcode(rdev);
|
||||
if (r) {
|
||||
@ -786,39 +766,6 @@ void r100_cp_disable(struct radeon_device *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
int r100_cp_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
bool reinit_cp;
|
||||
int i;
|
||||
|
||||
reinit_cp = rdev->cp.ready;
|
||||
rdev->cp.ready = false;
|
||||
WREG32(RADEON_CP_CSQ_MODE, 0);
|
||||
WREG32(RADEON_CP_CSQ_CNTL, 0);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
|
||||
(void)RREG32(RADEON_RBBM_SOFT_RESET);
|
||||
udelay(200);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, 0);
|
||||
/* Wait to prevent race in RBBM_STATUS */
|
||||
mdelay(1);
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
if (!(tmp & (1 << 16))) {
|
||||
DRM_INFO("CP reset succeed (RBBM_STATUS=0x%08X)\n",
|
||||
tmp);
|
||||
if (reinit_cp) {
|
||||
return r100_cp_init(rdev, rdev->cp.ring_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
DRM_UDELAY(1);
|
||||
}
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
DRM_ERROR("Failed to reset CP (RBBM_STATUS=0x%08X)!\n", tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void r100_cp_commit(struct radeon_device *rdev)
|
||||
{
|
||||
WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
|
||||
@ -1732,51 +1679,6 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void r100_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* TODO: anythings to do here ? pipes ? */
|
||||
r100_hdp_reset(rdev);
|
||||
}
|
||||
|
||||
void r100_hdp_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
|
||||
tmp |= (7 << 28);
|
||||
WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
|
||||
(void)RREG32(RADEON_HOST_PATH_CNTL);
|
||||
udelay(200);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, 0);
|
||||
WREG32(RADEON_HOST_PATH_CNTL, tmp);
|
||||
(void)RREG32(RADEON_HOST_PATH_CNTL);
|
||||
}
|
||||
|
||||
int r100_rb2d_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int i;
|
||||
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2);
|
||||
(void)RREG32(RADEON_RBBM_SOFT_RESET);
|
||||
udelay(200);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, 0);
|
||||
/* Wait to prevent race in RBBM_STATUS */
|
||||
mdelay(1);
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
if (!(tmp & (1 << 26))) {
|
||||
DRM_INFO("RB2D reset succeed (RBBM_STATUS=0x%08X)\n",
|
||||
tmp);
|
||||
return 0;
|
||||
}
|
||||
DRM_UDELAY(1);
|
||||
}
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
DRM_ERROR("Failed to reset RB2D (RBBM_STATUS=0x%08X)!\n", tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp)
|
||||
{
|
||||
lockup->last_cp_rptr = cp->rptr;
|
||||
@ -1863,31 +1765,77 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev)
|
||||
return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp);
|
||||
}
|
||||
|
||||
void r100_bm_disable(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
/* disable bus mastering */
|
||||
tmp = RREG32(R_000030_BUS_CNTL);
|
||||
WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000044);
|
||||
mdelay(1);
|
||||
WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042);
|
||||
mdelay(1);
|
||||
WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
|
||||
tmp = RREG32(RADEON_BUS_CNTL);
|
||||
mdelay(1);
|
||||
pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
|
||||
pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
int r100_asic_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t status;
|
||||
struct r100_mc_save save;
|
||||
u32 status, tmp;
|
||||
|
||||
/* reset order likely matter */
|
||||
status = RREG32(RADEON_RBBM_STATUS);
|
||||
/* reset HDP */
|
||||
r100_hdp_reset(rdev);
|
||||
/* reset rb2d */
|
||||
if (status & ((1 << 17) | (1 << 18) | (1 << 27))) {
|
||||
r100_rb2d_reset(rdev);
|
||||
r100_mc_stop(rdev, &save);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
if (!G_000E40_GUI_ACTIVE(status)) {
|
||||
return 0;
|
||||
}
|
||||
/* TODO: reset 3D engine */
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* stop CP */
|
||||
WREG32(RADEON_CP_CSQ_CNTL, 0);
|
||||
tmp = RREG32(RADEON_CP_RB_CNTL);
|
||||
WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
|
||||
WREG32(RADEON_CP_RB_RPTR_WR, 0);
|
||||
WREG32(RADEON_CP_RB_WPTR, 0);
|
||||
WREG32(RADEON_CP_RB_CNTL, tmp);
|
||||
/* save PCI state */
|
||||
pci_save_state(rdev->pdev);
|
||||
/* disable bus mastering */
|
||||
r100_bm_disable(rdev);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_SE(1) |
|
||||
S_0000F0_SOFT_RESET_RE(1) |
|
||||
S_0000F0_SOFT_RESET_PP(1) |
|
||||
S_0000F0_SOFT_RESET_RB(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* reset CP */
|
||||
status = RREG32(RADEON_RBBM_STATUS);
|
||||
if (status & (1 << 16)) {
|
||||
r100_cp_reset(rdev);
|
||||
}
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* restore PCI & busmastering */
|
||||
pci_restore_state(rdev->pdev);
|
||||
r100_enable_bm(rdev);
|
||||
/* Check if GPU is idle */
|
||||
status = RREG32(RADEON_RBBM_STATUS);
|
||||
if (status & RADEON_RBBM_ACTIVE) {
|
||||
DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
|
||||
if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) ||
|
||||
G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
|
||||
dev_err(rdev->dev, "failed to reset GPU\n");
|
||||
rdev->gpu_lockup = true;
|
||||
return -1;
|
||||
}
|
||||
DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status);
|
||||
r100_mc_resume(rdev, &save);
|
||||
dev_info(rdev->dev, "GPU reset succeed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3475,7 +3423,7 @@ static int r100_startup(struct radeon_device *rdev)
|
||||
/* Resume clock */
|
||||
r100_clock_startup(rdev);
|
||||
/* Initialize GPU configuration (# pipes, ...) */
|
||||
r100_gpu_init(rdev);
|
||||
// r100_gpu_init(rdev);
|
||||
/* Initialize GART (initialize after TTM so we can allocate
|
||||
* memory through TTM but finalize after TTM) */
|
||||
r100_enable_bm(rdev);
|
||||
|
@ -74,6 +74,134 @@
|
||||
#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
|
||||
|
||||
/* Registers */
|
||||
#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
|
||||
#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
|
||||
#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
|
||||
#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
|
||||
#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
|
||||
#define S_0000F0_SOFT_RESET_SE(x) (((x) & 0x1) << 2)
|
||||
#define G_0000F0_SOFT_RESET_SE(x) (((x) >> 2) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_SE 0xFFFFFFFB
|
||||
#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
|
||||
#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
|
||||
#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
|
||||
#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
|
||||
#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
|
||||
#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
|
||||
#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
|
||||
#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
|
||||
#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
|
||||
#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
|
||||
#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
|
||||
#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
|
||||
#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
|
||||
#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
|
||||
#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
|
||||
#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
|
||||
#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
|
||||
#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
|
||||
#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
|
||||
#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
|
||||
#define R_000030_BUS_CNTL 0x000030
|
||||
#define S_000030_BUS_DBL_RESYNC(x) (((x) & 0x1) << 0)
|
||||
#define G_000030_BUS_DBL_RESYNC(x) (((x) >> 0) & 0x1)
|
||||
#define C_000030_BUS_DBL_RESYNC 0xFFFFFFFE
|
||||
#define S_000030_BUS_MSTR_RESET(x) (((x) & 0x1) << 1)
|
||||
#define G_000030_BUS_MSTR_RESET(x) (((x) >> 1) & 0x1)
|
||||
#define C_000030_BUS_MSTR_RESET 0xFFFFFFFD
|
||||
#define S_000030_BUS_FLUSH_BUF(x) (((x) & 0x1) << 2)
|
||||
#define G_000030_BUS_FLUSH_BUF(x) (((x) >> 2) & 0x1)
|
||||
#define C_000030_BUS_FLUSH_BUF 0xFFFFFFFB
|
||||
#define S_000030_BUS_STOP_REQ_DIS(x) (((x) & 0x1) << 3)
|
||||
#define G_000030_BUS_STOP_REQ_DIS(x) (((x) >> 3) & 0x1)
|
||||
#define C_000030_BUS_STOP_REQ_DIS 0xFFFFFFF7
|
||||
#define S_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 4)
|
||||
#define G_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) >> 4) & 0x1)
|
||||
#define C_000030_BUS_PM4_READ_COMBINE_EN 0xFFFFFFEF
|
||||
#define S_000030_BUS_WRT_COMBINE_EN(x) (((x) & 0x1) << 5)
|
||||
#define G_000030_BUS_WRT_COMBINE_EN(x) (((x) >> 5) & 0x1)
|
||||
#define C_000030_BUS_WRT_COMBINE_EN 0xFFFFFFDF
|
||||
#define S_000030_BUS_MASTER_DIS(x) (((x) & 0x1) << 6)
|
||||
#define G_000030_BUS_MASTER_DIS(x) (((x) >> 6) & 0x1)
|
||||
#define C_000030_BUS_MASTER_DIS 0xFFFFFFBF
|
||||
#define S_000030_BIOS_ROM_WRT_EN(x) (((x) & 0x1) << 7)
|
||||
#define G_000030_BIOS_ROM_WRT_EN(x) (((x) >> 7) & 0x1)
|
||||
#define C_000030_BIOS_ROM_WRT_EN 0xFFFFFF7F
|
||||
#define S_000030_BM_DAC_CRIPPLE(x) (((x) & 0x1) << 8)
|
||||
#define G_000030_BM_DAC_CRIPPLE(x) (((x) >> 8) & 0x1)
|
||||
#define C_000030_BM_DAC_CRIPPLE 0xFFFFFEFF
|
||||
#define S_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 9)
|
||||
#define G_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) >> 9) & 0x1)
|
||||
#define C_000030_BUS_NON_PM4_READ_COMBINE_EN 0xFFFFFDFF
|
||||
#define S_000030_BUS_XFERD_DISCARD_EN(x) (((x) & 0x1) << 10)
|
||||
#define G_000030_BUS_XFERD_DISCARD_EN(x) (((x) >> 10) & 0x1)
|
||||
#define C_000030_BUS_XFERD_DISCARD_EN 0xFFFFFBFF
|
||||
#define S_000030_BUS_SGL_READ_DISABLE(x) (((x) & 0x1) << 11)
|
||||
#define G_000030_BUS_SGL_READ_DISABLE(x) (((x) >> 11) & 0x1)
|
||||
#define C_000030_BUS_SGL_READ_DISABLE 0xFFFFF7FF
|
||||
#define S_000030_BIOS_DIS_ROM(x) (((x) & 0x1) << 12)
|
||||
#define G_000030_BIOS_DIS_ROM(x) (((x) >> 12) & 0x1)
|
||||
#define C_000030_BIOS_DIS_ROM 0xFFFFEFFF
|
||||
#define S_000030_BUS_PCI_READ_RETRY_EN(x) (((x) & 0x1) << 13)
|
||||
#define G_000030_BUS_PCI_READ_RETRY_EN(x) (((x) >> 13) & 0x1)
|
||||
#define C_000030_BUS_PCI_READ_RETRY_EN 0xFFFFDFFF
|
||||
#define S_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) & 0x1) << 14)
|
||||
#define G_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) >> 14) & 0x1)
|
||||
#define C_000030_BUS_AGP_AD_STEPPING_EN 0xFFFFBFFF
|
||||
#define S_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) & 0x1) << 15)
|
||||
#define G_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) >> 15) & 0x1)
|
||||
#define C_000030_BUS_PCI_WRT_RETRY_EN 0xFFFF7FFF
|
||||
#define S_000030_BUS_RETRY_WS(x) (((x) & 0xF) << 16)
|
||||
#define G_000030_BUS_RETRY_WS(x) (((x) >> 16) & 0xF)
|
||||
#define C_000030_BUS_RETRY_WS 0xFFF0FFFF
|
||||
#define S_000030_BUS_MSTR_RD_MULT(x) (((x) & 0x1) << 20)
|
||||
#define G_000030_BUS_MSTR_RD_MULT(x) (((x) >> 20) & 0x1)
|
||||
#define C_000030_BUS_MSTR_RD_MULT 0xFFEFFFFF
|
||||
#define S_000030_BUS_MSTR_RD_LINE(x) (((x) & 0x1) << 21)
|
||||
#define G_000030_BUS_MSTR_RD_LINE(x) (((x) >> 21) & 0x1)
|
||||
#define C_000030_BUS_MSTR_RD_LINE 0xFFDFFFFF
|
||||
#define S_000030_BUS_SUSPEND(x) (((x) & 0x1) << 22)
|
||||
#define G_000030_BUS_SUSPEND(x) (((x) >> 22) & 0x1)
|
||||
#define C_000030_BUS_SUSPEND 0xFFBFFFFF
|
||||
#define S_000030_LAT_16X(x) (((x) & 0x1) << 23)
|
||||
#define G_000030_LAT_16X(x) (((x) >> 23) & 0x1)
|
||||
#define C_000030_LAT_16X 0xFF7FFFFF
|
||||
#define S_000030_BUS_RD_DISCARD_EN(x) (((x) & 0x1) << 24)
|
||||
#define G_000030_BUS_RD_DISCARD_EN(x) (((x) >> 24) & 0x1)
|
||||
#define C_000030_BUS_RD_DISCARD_EN 0xFEFFFFFF
|
||||
#define S_000030_ENFRCWRDY(x) (((x) & 0x1) << 25)
|
||||
#define G_000030_ENFRCWRDY(x) (((x) >> 25) & 0x1)
|
||||
#define C_000030_ENFRCWRDY 0xFDFFFFFF
|
||||
#define S_000030_BUS_MSTR_WS(x) (((x) & 0x1) << 26)
|
||||
#define G_000030_BUS_MSTR_WS(x) (((x) >> 26) & 0x1)
|
||||
#define C_000030_BUS_MSTR_WS 0xFBFFFFFF
|
||||
#define S_000030_BUS_PARKING_DIS(x) (((x) & 0x1) << 27)
|
||||
#define G_000030_BUS_PARKING_DIS(x) (((x) >> 27) & 0x1)
|
||||
#define C_000030_BUS_PARKING_DIS 0xF7FFFFFF
|
||||
#define S_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) & 0x1) << 28)
|
||||
#define G_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) >> 28) & 0x1)
|
||||
#define C_000030_BUS_MSTR_DISCONNECT_EN 0xEFFFFFFF
|
||||
#define S_000030_SERR_EN(x) (((x) & 0x1) << 29)
|
||||
#define G_000030_SERR_EN(x) (((x) >> 29) & 0x1)
|
||||
#define C_000030_SERR_EN 0xDFFFFFFF
|
||||
#define S_000030_BUS_READ_BURST(x) (((x) & 0x1) << 30)
|
||||
#define G_000030_BUS_READ_BURST(x) (((x) >> 30) & 0x1)
|
||||
#define C_000030_BUS_READ_BURST 0xBFFFFFFF
|
||||
#define S_000030_BUS_RDY_READ_DLY(x) (((x) & 0x1) << 31)
|
||||
#define G_000030_BUS_RDY_READ_DLY(x) (((x) >> 31) & 0x1)
|
||||
#define C_000030_BUS_RDY_READ_DLY 0x7FFFFFFF
|
||||
#define R_000040_GEN_INT_CNTL 0x000040
|
||||
#define S_000040_CRTC_VBLANK(x) (((x) & 0x1) << 0)
|
||||
#define G_000040_CRTC_VBLANK(x) (((x) >> 0) & 0x1)
|
||||
|
@ -151,6 +151,10 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
|
||||
u32 tmp;
|
||||
int r;
|
||||
|
||||
WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0);
|
||||
WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0);
|
||||
WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0);
|
||||
WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0);
|
||||
tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
|
||||
tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
|
||||
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
|
||||
@ -323,7 +327,6 @@ void r300_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t gb_tile_config, tmp;
|
||||
|
||||
r100_hdp_reset(rdev);
|
||||
/* FIXME: rv380 one pipes ? */
|
||||
if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
|
||||
(rdev->family == CHIP_R350)) {
|
||||
@ -376,57 +379,6 @@ void r300_gpu_init(struct radeon_device *rdev)
|
||||
rdev->num_gb_pipes, rdev->num_z_pipes);
|
||||
}
|
||||
|
||||
int r300_ga_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
bool reinit_cp;
|
||||
int i;
|
||||
|
||||
reinit_cp = rdev->cp.ready;
|
||||
rdev->cp.ready = false;
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
WREG32(RADEON_CP_CSQ_MODE, 0);
|
||||
WREG32(RADEON_CP_CSQ_CNTL, 0);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, 0x32005);
|
||||
(void)RREG32(RADEON_RBBM_SOFT_RESET);
|
||||
udelay(200);
|
||||
WREG32(RADEON_RBBM_SOFT_RESET, 0);
|
||||
/* Wait to prevent race in RBBM_STATUS */
|
||||
mdelay(1);
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
if (tmp & ((1 << 20) | (1 << 26))) {
|
||||
DRM_ERROR("VAP & CP still busy (RBBM_STATUS=0x%08X)", tmp);
|
||||
/* GA still busy soft reset it */
|
||||
WREG32(0x429C, 0x200);
|
||||
WREG32(R300_VAP_PVS_STATE_FLUSH_REG, 0);
|
||||
WREG32(R300_RE_SCISSORS_TL, 0);
|
||||
WREG32(R300_RE_SCISSORS_BR, 0);
|
||||
WREG32(0x24AC, 0);
|
||||
}
|
||||
/* Wait to prevent race in RBBM_STATUS */
|
||||
mdelay(1);
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
if (!(tmp & ((1 << 20) | (1 << 26)))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
if (!(tmp & ((1 << 20) | (1 << 26)))) {
|
||||
DRM_INFO("GA reset succeed (RBBM_STATUS=0x%08X)\n",
|
||||
tmp);
|
||||
if (reinit_cp) {
|
||||
return r100_cp_init(rdev, rdev->cp.ring_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
DRM_UDELAY(1);
|
||||
}
|
||||
tmp = RREG32(RADEON_RBBM_STATUS);
|
||||
DRM_ERROR("Failed to reset GA ! (RBBM_STATUS=0x%08X)\n", tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool r300_gpu_is_lockup(struct radeon_device *rdev)
|
||||
{
|
||||
u32 rbbm_status;
|
||||
@ -451,37 +403,69 @@ bool r300_gpu_is_lockup(struct radeon_device *rdev)
|
||||
|
||||
int r300_asic_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t status;
|
||||
struct r100_mc_save save;
|
||||
u32 status, tmp;
|
||||
|
||||
/* reset order likely matter */
|
||||
status = RREG32(RADEON_RBBM_STATUS);
|
||||
r100_mc_stop(rdev, &save);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
if (!G_000E40_GUI_ACTIVE(status)) {
|
||||
return 0;
|
||||
}
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* reset HDP */
|
||||
r100_hdp_reset(rdev);
|
||||
/* reset rb2d */
|
||||
if (status & ((1 << 17) | (1 << 18) | (1 << 27))) {
|
||||
r100_rb2d_reset(rdev);
|
||||
}
|
||||
/* reset GA */
|
||||
if (status & ((1 << 20) | (1 << 26))) {
|
||||
r300_ga_reset(rdev);
|
||||
}
|
||||
/* reset CP */
|
||||
status = RREG32(RADEON_RBBM_STATUS);
|
||||
if (status & (1 << 16)) {
|
||||
r100_cp_reset(rdev);
|
||||
}
|
||||
/* stop CP */
|
||||
WREG32(RADEON_CP_CSQ_CNTL, 0);
|
||||
tmp = RREG32(RADEON_CP_RB_CNTL);
|
||||
WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
|
||||
WREG32(RADEON_CP_RB_RPTR_WR, 0);
|
||||
WREG32(RADEON_CP_RB_WPTR, 0);
|
||||
WREG32(RADEON_CP_RB_CNTL, tmp);
|
||||
/* save PCI state */
|
||||
pci_save_state(rdev->pdev);
|
||||
/* disable bus mastering */
|
||||
r100_bm_disable(rdev);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) |
|
||||
S_0000F0_SOFT_RESET_GA(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* resetting the CP seems to be problematic sometimes it end up
|
||||
* hard locking the computer, but it's necessary for successfull
|
||||
* reset more test & playing is needed on R3XX/R4XX to find a
|
||||
* reliable (if any solution)
|
||||
*/
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* reset MC */
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* restore PCI & busmastering */
|
||||
pci_restore_state(rdev->pdev);
|
||||
r100_enable_bm(rdev);
|
||||
/* Check if GPU is idle */
|
||||
status = RREG32(RADEON_RBBM_STATUS);
|
||||
if (status & RADEON_RBBM_ACTIVE) {
|
||||
DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
|
||||
if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
|
||||
dev_err(rdev->dev, "failed to reset GPU\n");
|
||||
rdev->gpu_lockup = true;
|
||||
return -1;
|
||||
}
|
||||
DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status);
|
||||
r100_mc_resume(rdev, &save);
|
||||
dev_info(rdev->dev, "GPU reset succeed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* r300,r350,rv350,rv380 VRAM info
|
||||
*/
|
||||
|
@ -209,7 +209,52 @@
|
||||
#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
|
||||
#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
|
||||
#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
|
||||
|
||||
#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
|
||||
#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
|
||||
#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
|
||||
#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
|
||||
#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
|
||||
#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2)
|
||||
#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB
|
||||
#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
|
||||
#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
|
||||
#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
|
||||
#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
|
||||
#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
|
||||
#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
|
||||
#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
|
||||
#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
|
||||
#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
|
||||
#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
|
||||
#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
|
||||
#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
|
||||
#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
|
||||
#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
|
||||
#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
|
||||
#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
|
||||
#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
|
||||
#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
|
||||
#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
|
||||
#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
|
||||
#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13)
|
||||
#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF
|
||||
#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14)
|
||||
#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF
|
||||
|
||||
#define R_00000D_SCLK_CNTL 0x00000D
|
||||
#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
|
||||
|
@ -53,7 +53,6 @@ static void r520_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned pipe_select_current, gb_pipe_select, tmp;
|
||||
|
||||
r100_hdp_reset(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
/*
|
||||
* DST_PIPE_CONFIG 0x170C
|
||||
|
@ -749,7 +749,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
|
||||
S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) |
|
||||
S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
|
||||
S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
|
||||
u32 srbm_reset = 0;
|
||||
u32 tmp;
|
||||
|
||||
dev_info(rdev->dev, "GPU softreset \n");
|
||||
@ -764,7 +763,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
|
||||
dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
|
||||
}
|
||||
/* Disable CP parsing/prefetching */
|
||||
WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
|
||||
WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
|
||||
/* Check if any of the rendering block is busy and reset it */
|
||||
if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
|
||||
(RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
|
||||
@ -783,55 +782,17 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
|
||||
S_008020_SOFT_RESET_VGT(1);
|
||||
dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
|
||||
WREG32(R_008020_GRBM_SOFT_RESET, tmp);
|
||||
(void)RREG32(R_008020_GRBM_SOFT_RESET);
|
||||
mdelay(1);
|
||||
RREG32(R_008020_GRBM_SOFT_RESET);
|
||||
mdelay(15);
|
||||
WREG32(R_008020_GRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(R_008020_GRBM_SOFT_RESET);
|
||||
}
|
||||
/* Reset CP (we always reset CP) */
|
||||
tmp = S_008020_SOFT_RESET_CP(1);
|
||||
dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
|
||||
WREG32(R_008020_GRBM_SOFT_RESET, tmp);
|
||||
(void)RREG32(R_008020_GRBM_SOFT_RESET);
|
||||
udelay(50);
|
||||
RREG32(R_008020_GRBM_SOFT_RESET);
|
||||
mdelay(15);
|
||||
WREG32(R_008020_GRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(R_008020_GRBM_SOFT_RESET);
|
||||
/* Reset others GPU block if necessary */
|
||||
if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
|
||||
if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_GRBM(1);
|
||||
if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_IH(1);
|
||||
if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_VMC(1);
|
||||
if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_MC(1);
|
||||
if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_MC(1);
|
||||
if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_MC(1);
|
||||
if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_MC(1);
|
||||
if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_MC(1);
|
||||
if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
|
||||
if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
|
||||
if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
|
||||
srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
|
||||
dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
|
||||
WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
|
||||
(void)RREG32(R_000E60_SRBM_SOFT_RESET);
|
||||
mdelay(1);
|
||||
WREG32(R_000E60_SRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(R_000E60_SRBM_SOFT_RESET);
|
||||
WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
|
||||
(void)RREG32(R_000E60_SRBM_SOFT_RESET);
|
||||
mdelay(1);
|
||||
WREG32(R_000E60_SRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(R_000E60_SRBM_SOFT_RESET);
|
||||
/* Wait a little for things to settle down */
|
||||
mdelay(1);
|
||||
dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
|
||||
@ -840,10 +801,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
|
||||
RREG32(R_008014_GRBM_STATUS2));
|
||||
dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
|
||||
RREG32(R_000E50_SRBM_STATUS));
|
||||
/* After reset we need to reinit the asic as GPU often endup in an
|
||||
* incoherent state.
|
||||
*/
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
rv515_mc_resume(rdev, &save);
|
||||
return 0;
|
||||
}
|
||||
|
@ -447,6 +447,9 @@ int r600_blit_init(struct radeon_device *rdev)
|
||||
u32 packet2s[16];
|
||||
int num_packet2s = 0;
|
||||
|
||||
/* don't reinitialize blit */
|
||||
if (rdev->r600_blit.shader_obj)
|
||||
return 0;
|
||||
mutex_init(&rdev->r600_blit.mutex);
|
||||
rdev->r600_blit.state_offset = 0;
|
||||
|
||||
|
@ -1188,6 +1188,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
|
||||
|
||||
/* Common functions */
|
||||
/* AGP */
|
||||
extern int radeon_gpu_reset(struct radeon_device *rdev);
|
||||
extern void radeon_agp_disable(struct radeon_device *rdev);
|
||||
extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
|
||||
extern void radeon_gart_restore(struct radeon_device *rdev);
|
||||
|
@ -367,7 +367,7 @@ static struct radeon_asic rs600_asic = {
|
||||
.resume = &rs600_resume,
|
||||
.vga_set_state = &r100_vga_set_state,
|
||||
.gpu_is_lockup = &r300_gpu_is_lockup,
|
||||
.asic_reset = &r300_asic_reset,
|
||||
.asic_reset = &rs600_asic_reset,
|
||||
.gart_tlb_flush = &rs600_gart_tlb_flush,
|
||||
.gart_set_page = &rs600_gart_set_page,
|
||||
.cp_commit = &r100_cp_commit,
|
||||
@ -406,7 +406,7 @@ static struct radeon_asic rs690_asic = {
|
||||
.resume = &rs690_resume,
|
||||
.vga_set_state = &r100_vga_set_state,
|
||||
.gpu_is_lockup = &r300_gpu_is_lockup,
|
||||
.asic_reset = &r300_asic_reset,
|
||||
.asic_reset = &rs600_asic_reset,
|
||||
.gart_tlb_flush = &rs400_gart_tlb_flush,
|
||||
.gart_set_page = &rs400_gart_set_page,
|
||||
.cp_commit = &r100_cp_commit,
|
||||
@ -445,7 +445,7 @@ static struct radeon_asic rv515_asic = {
|
||||
.resume = &rv515_resume,
|
||||
.vga_set_state = &r100_vga_set_state,
|
||||
.gpu_is_lockup = &r300_gpu_is_lockup,
|
||||
.asic_reset = &rv515_asic_reset,
|
||||
.asic_reset = &rs600_asic_reset,
|
||||
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
|
||||
.gart_set_page = &rv370_pcie_gart_set_page,
|
||||
.cp_commit = &r100_cp_commit,
|
||||
@ -484,7 +484,7 @@ static struct radeon_asic r520_asic = {
|
||||
.resume = &r520_resume,
|
||||
.vga_set_state = &r100_vga_set_state,
|
||||
.gpu_is_lockup = &r300_gpu_is_lockup,
|
||||
.asic_reset = &rv515_asic_reset,
|
||||
.asic_reset = &rs600_asic_reset,
|
||||
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
|
||||
.gart_set_page = &rv370_pcie_gart_set_page,
|
||||
.cp_commit = &r100_cp_commit,
|
||||
@ -560,6 +560,7 @@ static struct radeon_asic rs780_asic = {
|
||||
.suspend = &r600_suspend,
|
||||
.resume = &r600_resume,
|
||||
.cp_commit = &r600_cp_commit,
|
||||
.gpu_is_lockup = &r600_gpu_is_lockup,
|
||||
.vga_set_state = &r600_vga_set_state,
|
||||
.asic_reset = &r600_asic_reset,
|
||||
.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
|
||||
|
@ -111,8 +111,6 @@ void r100_vram_init_sizes(struct radeon_device *rdev);
|
||||
void r100_wb_disable(struct radeon_device *rdev);
|
||||
void r100_wb_fini(struct radeon_device *rdev);
|
||||
int r100_wb_init(struct radeon_device *rdev);
|
||||
void r100_hdp_reset(struct radeon_device *rdev);
|
||||
int r100_rb2d_reset(struct radeon_device *rdev);
|
||||
int r100_cp_reset(struct radeon_device *rdev);
|
||||
void r100_vga_render_disable(struct radeon_device *rdev);
|
||||
int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
|
||||
@ -127,7 +125,7 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
|
||||
unsigned idx);
|
||||
void r100_enable_bm(struct radeon_device *rdev);
|
||||
void r100_set_common_regs(struct radeon_device *rdev);
|
||||
|
||||
void r100_bm_disable(struct radeon_device *rdev);
|
||||
/*
|
||||
* r200,rv250,rs300,rv280
|
||||
*/
|
||||
@ -180,6 +178,7 @@ void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
|
||||
/*
|
||||
* rs600.
|
||||
*/
|
||||
extern int rs600_asic_reset(struct radeon_device *rdev);
|
||||
extern int rs600_init(struct radeon_device *rdev);
|
||||
extern void rs600_fini(struct radeon_device *rdev);
|
||||
extern int rs600_suspend(struct radeon_device *rdev);
|
||||
@ -214,7 +213,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev);
|
||||
*/
|
||||
int rv515_init(struct radeon_device *rdev);
|
||||
void rv515_fini(struct radeon_device *rdev);
|
||||
int rv515_asic_reset(struct radeon_device *rdev);
|
||||
uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg);
|
||||
void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
|
||||
void rv515_ring_start(struct radeon_device *rdev);
|
||||
|
@ -220,10 +220,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
int r;
|
||||
|
||||
mutex_lock(&rdev->cs_mutex);
|
||||
if (rdev->gpu_lockup) {
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* initialize parser */
|
||||
memset(&parser, 0, sizeof(struct radeon_cs_parser));
|
||||
parser.filp = filp;
|
||||
|
@ -639,6 +639,8 @@ void radeon_device_fini(struct radeon_device *rdev)
|
||||
{
|
||||
DRM_INFO("radeon: finishing device.\n");
|
||||
rdev->shutdown = true;
|
||||
/* evict vram memory */
|
||||
radeon_bo_evict_vram(rdev);
|
||||
radeon_fini(rdev);
|
||||
destroy_workqueue(rdev->wq);
|
||||
vga_switcheroo_unregister_client(rdev->pdev);
|
||||
@ -737,6 +739,26 @@ int radeon_resume_kms(struct drm_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_gpu_reset(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
radeon_save_bios_scratch_regs(rdev);
|
||||
radeon_suspend(rdev);
|
||||
|
||||
r = radeon_asic_reset(rdev);
|
||||
if (!r) {
|
||||
dev_info(rdev->dev, "GPU reset succeed\n");
|
||||
radeon_resume(rdev);
|
||||
radeon_restore_bios_scratch_regs(rdev);
|
||||
drm_helper_resume_force_mode(rdev->ddev);
|
||||
return 0;
|
||||
}
|
||||
/* bad news, how to tell it to userspace ? */
|
||||
dev_info(rdev->dev, "GPU reset failed\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Debugfs
|
||||
|
@ -209,8 +209,9 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
|
||||
r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
|
||||
radeon_fence_signaled(fence), timeout);
|
||||
radeon_irq_kms_sw_irq_put(rdev);
|
||||
if (unlikely(r < 0))
|
||||
if (unlikely(r < 0)) {
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
radeon_irq_kms_sw_irq_get(rdev);
|
||||
r = wait_event_timeout(rdev->fence_drv.queue,
|
||||
@ -230,14 +231,16 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
|
||||
*/
|
||||
if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) {
|
||||
/* good news we believe it's a lockup */
|
||||
dev_warn(rdev->dev, "GPU lockup (last fence id 0x%08X)\n", seq);
|
||||
r = radeon_asic_reset(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq);
|
||||
/* FIXME: what should we do ? marking everyone
|
||||
* as signaled for now
|
||||
*/
|
||||
rdev->gpu_lockup = true;
|
||||
WREG32(rdev->fence_drv.scratch_reg, fence->seq);
|
||||
r = radeon_gpu_reset(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rdev->gpu_lockup = false;
|
||||
}
|
||||
timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
|
||||
write_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
|
||||
|
@ -173,7 +173,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
|
||||
int i, j;
|
||||
|
||||
if (!rdev->gart.ready) {
|
||||
DRM_ERROR("trying to bind memory to unitialized GART !\n");
|
||||
WARN(1, "trying to bind memory to unitialized GART !\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
t = offset / RADEON_GPU_PAGE_SIZE;
|
||||
|
@ -242,8 +242,6 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
|
||||
void rs400_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* FIXME: HDP same place on rs400 ? */
|
||||
r100_hdp_reset(rdev);
|
||||
/* FIXME: is this correct ? */
|
||||
r420_pipes_init(rdev);
|
||||
if (rs400_mc_wait_for_idle(rdev)) {
|
||||
|
@ -147,6 +147,78 @@ void rs600_hpd_fini(struct radeon_device *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
void rs600_bm_disable(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
/* disable bus mastering */
|
||||
pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
|
||||
pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
int rs600_asic_reset(struct radeon_device *rdev)
|
||||
{
|
||||
u32 status, tmp;
|
||||
|
||||
struct rv515_mc_save save;
|
||||
|
||||
/* Stops all mc clients */
|
||||
rv515_mc_stop(rdev, &save);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
if (!G_000E40_GUI_ACTIVE(status)) {
|
||||
return 0;
|
||||
}
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* stop CP */
|
||||
WREG32(RADEON_CP_CSQ_CNTL, 0);
|
||||
tmp = RREG32(RADEON_CP_RB_CNTL);
|
||||
WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
|
||||
WREG32(RADEON_CP_RB_RPTR_WR, 0);
|
||||
WREG32(RADEON_CP_RB_WPTR, 0);
|
||||
WREG32(RADEON_CP_RB_CNTL, tmp);
|
||||
pci_save_state(rdev->pdev);
|
||||
/* disable bus mastering */
|
||||
rs600_bm_disable(rdev);
|
||||
/* reset GA+VAP */
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) |
|
||||
S_0000F0_SOFT_RESET_GA(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* reset CP */
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* reset MC */
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1));
|
||||
RREG32(R_0000F0_RBBM_SOFT_RESET);
|
||||
mdelay(500);
|
||||
WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
|
||||
mdelay(1);
|
||||
status = RREG32(R_000E40_RBBM_STATUS);
|
||||
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
|
||||
/* restore PCI & busmastering */
|
||||
pci_restore_state(rdev->pdev);
|
||||
/* Check if GPU is idle */
|
||||
if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
|
||||
dev_err(rdev->dev, "failed to reset GPU\n");
|
||||
rdev->gpu_lockup = true;
|
||||
return -1;
|
||||
}
|
||||
rv515_mc_resume(rdev, &save);
|
||||
dev_info(rdev->dev, "GPU reset succeed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* GART.
|
||||
*/
|
||||
@ -454,7 +526,6 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
|
||||
void rs600_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
r100_hdp_reset(rdev);
|
||||
r420_pipes_init(rdev);
|
||||
/* Wait for mc idle */
|
||||
if (rs600_mc_wait_for_idle(rdev))
|
||||
|
@ -178,6 +178,52 @@
|
||||
#define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_000074_MC_IND_DATA 0x00000000
|
||||
#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
|
||||
#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
|
||||
#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
|
||||
#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
|
||||
#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
|
||||
#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2)
|
||||
#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB
|
||||
#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
|
||||
#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
|
||||
#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
|
||||
#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
|
||||
#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
|
||||
#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
|
||||
#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
|
||||
#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
|
||||
#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
|
||||
#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
|
||||
#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
|
||||
#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
|
||||
#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
|
||||
#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
|
||||
#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
|
||||
#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
|
||||
#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
|
||||
#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
|
||||
#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
|
||||
#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
|
||||
#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13)
|
||||
#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF
|
||||
#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14)
|
||||
#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF
|
||||
#define R_000134_HDP_FB_LOCATION 0x000134
|
||||
#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
|
||||
#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
|
||||
|
@ -48,8 +48,6 @@ static int rs690_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
|
||||
static void rs690_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* FIXME: HDP same place on rs690 ? */
|
||||
r100_hdp_reset(rdev);
|
||||
/* FIXME: is this correct ? */
|
||||
r420_pipes_init(rdev);
|
||||
if (rs690_mc_wait_for_idle(rdev)) {
|
||||
|
@ -146,16 +146,11 @@ void rv515_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned pipe_select_current, gb_pipe_select, tmp;
|
||||
|
||||
r100_hdp_reset(rdev);
|
||||
r100_rb2d_reset(rdev);
|
||||
|
||||
if (r100_gui_wait_for_idle(rdev)) {
|
||||
printk(KERN_WARNING "Failed to wait GUI idle while "
|
||||
"reseting GPU. Bad things might happen.\n");
|
||||
}
|
||||
|
||||
rv515_vga_render_disable(rdev);
|
||||
|
||||
r420_pipes_init(rdev);
|
||||
gb_pipe_select = RREG32(0x402C);
|
||||
tmp = RREG32(0x170C);
|
||||
@ -173,91 +168,6 @@ void rv515_gpu_init(struct radeon_device *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
int rv515_ga_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
bool reinit_cp;
|
||||
int i;
|
||||
|
||||
reinit_cp = rdev->cp.ready;
|
||||
rdev->cp.ready = false;
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
WREG32(CP_CSQ_MODE, 0);
|
||||
WREG32(CP_CSQ_CNTL, 0);
|
||||
WREG32(RBBM_SOFT_RESET, 0x32005);
|
||||
(void)RREG32(RBBM_SOFT_RESET);
|
||||
udelay(200);
|
||||
WREG32(RBBM_SOFT_RESET, 0);
|
||||
/* Wait to prevent race in RBBM_STATUS */
|
||||
mdelay(1);
|
||||
tmp = RREG32(RBBM_STATUS);
|
||||
if (tmp & ((1 << 20) | (1 << 26))) {
|
||||
DRM_ERROR("VAP & CP still busy (RBBM_STATUS=0x%08X)\n", tmp);
|
||||
/* GA still busy soft reset it */
|
||||
WREG32(0x429C, 0x200);
|
||||
WREG32(VAP_PVS_STATE_FLUSH_REG, 0);
|
||||
WREG32(0x43E0, 0);
|
||||
WREG32(0x43E4, 0);
|
||||
WREG32(0x24AC, 0);
|
||||
}
|
||||
/* Wait to prevent race in RBBM_STATUS */
|
||||
mdelay(1);
|
||||
tmp = RREG32(RBBM_STATUS);
|
||||
if (!(tmp & ((1 << 20) | (1 << 26)))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
tmp = RREG32(RBBM_STATUS);
|
||||
if (!(tmp & ((1 << 20) | (1 << 26)))) {
|
||||
DRM_INFO("GA reset succeed (RBBM_STATUS=0x%08X)\n",
|
||||
tmp);
|
||||
DRM_INFO("GA_IDLE=0x%08X\n", RREG32(0x425C));
|
||||
DRM_INFO("RB3D_RESET_STATUS=0x%08X\n", RREG32(0x46f0));
|
||||
DRM_INFO("ISYNC_CNTL=0x%08X\n", RREG32(0x1724));
|
||||
if (reinit_cp) {
|
||||
return r100_cp_init(rdev, rdev->cp.ring_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
DRM_UDELAY(1);
|
||||
}
|
||||
tmp = RREG32(RBBM_STATUS);
|
||||
DRM_ERROR("Failed to reset GA ! (RBBM_STATUS=0x%08X)\n", tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rv515_asic_reset(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
/* reset order likely matter */
|
||||
status = RREG32(RBBM_STATUS);
|
||||
/* reset HDP */
|
||||
r100_hdp_reset(rdev);
|
||||
/* reset rb2d */
|
||||
if (status & ((1 << 17) | (1 << 18) | (1 << 27))) {
|
||||
r100_rb2d_reset(rdev);
|
||||
}
|
||||
/* reset GA */
|
||||
if (status & ((1 << 20) | (1 << 26))) {
|
||||
rv515_ga_reset(rdev);
|
||||
}
|
||||
/* reset CP */
|
||||
status = RREG32(RBBM_STATUS);
|
||||
if (status & (1 << 16)) {
|
||||
r100_cp_reset(rdev);
|
||||
}
|
||||
/* Check if GPU is idle */
|
||||
status = RREG32(RBBM_STATUS);
|
||||
if (status & (1 << 31)) {
|
||||
DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
|
||||
return -1;
|
||||
}
|
||||
DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rv515_vram_get_type(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
@ -217,6 +217,52 @@
|
||||
#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
|
||||
|
||||
/* Registers */
|
||||
#define R_0000F0_RBBM_SOFT_RESET 0x0000F0
|
||||
#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0)
|
||||
#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE
|
||||
#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1)
|
||||
#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD
|
||||
#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2)
|
||||
#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB
|
||||
#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3)
|
||||
#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7
|
||||
#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4)
|
||||
#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF
|
||||
#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5)
|
||||
#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF
|
||||
#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6)
|
||||
#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF
|
||||
#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7)
|
||||
#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F
|
||||
#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8)
|
||||
#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF
|
||||
#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9)
|
||||
#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF
|
||||
#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10)
|
||||
#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF
|
||||
#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11)
|
||||
#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF
|
||||
#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12)
|
||||
#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF
|
||||
#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13)
|
||||
#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF
|
||||
#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14)
|
||||
#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1)
|
||||
#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF
|
||||
#define R_0000F8_CONFIG_MEMSIZE 0x0000F8
|
||||
#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
|
Loading…
Reference in New Issue
Block a user