Loading drivers/gpu/drm/radeon/evergreen.c +3 −3 Original line number Diff line number Diff line Loading @@ -804,7 +804,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev) } } static int evergreen_mc_wait_for_idle(struct radeon_device *rdev) int evergreen_mc_wait_for_idle(struct radeon_device *rdev) { unsigned i; u32 tmp; Loading Loading @@ -957,7 +957,7 @@ void evergreen_agp_enable(struct radeon_device *rdev) WREG32(VM_CONTEXT1_CNTL, 0); } static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) { save->vga_control[0] = RREG32(D1VGA_CONTROL); save->vga_control[1] = RREG32(D2VGA_CONTROL); Loading Loading @@ -1011,7 +1011,7 @@ static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa WREG32(EVERGREEN_D6VGA_CONTROL, 0); } static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) { WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, upper_32_bits(rdev->mc.vram_start)); Loading drivers/gpu/drm/radeon/ni.c +97 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,10 @@ #include "ni_reg.h" #include "cayman_blit_shaders.h" extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); #define EVERGREEN_PFP_UCODE_SIZE 1120 #define EVERGREEN_PM4_UCODE_SIZE 1376 #define EVERGREEN_RLC_UCODE_SIZE 768 Loading Loading @@ -1249,3 +1253,96 @@ int cayman_cp_resume(struct radeon_device *rdev) return 0; } bool cayman_gpu_is_lockup(struct radeon_device *rdev) { u32 srbm_status; u32 grbm_status; u32 grbm_status_se0, grbm_status_se1; struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup; int r; srbm_status = RREG32(SRBM_STATUS); grbm_status = RREG32(GRBM_STATUS); grbm_status_se0 = RREG32(GRBM_STATUS_SE0); grbm_status_se1 = RREG32(GRBM_STATUS_SE1); if (!(grbm_status & GUI_ACTIVE)) { r100_gpu_lockup_update(lockup, &rdev->cp); return false; } /* force CP activities */ r = radeon_ring_lock(rdev, 2); if (!r) { /* PACKET2 NOP */ radeon_ring_write(rdev, 0x80000000); radeon_ring_write(rdev, 0x80000000); radeon_ring_unlock_commit(rdev); } /* XXX deal with CP0,1,2 */ rdev->cp.rptr = RREG32(CP_RB0_RPTR); return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); } static int cayman_gpu_soft_reset(struct radeon_device *rdev) { struct evergreen_mc_save save; u32 grbm_reset = 0; if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) return 0; dev_info(rdev->dev, "GPU softreset \n"); dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", RREG32(GRBM_STATUS)); dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", RREG32(GRBM_STATUS_SE0)); dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", RREG32(GRBM_STATUS_SE1)); dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", RREG32(SRBM_STATUS)); evergreen_mc_stop(rdev, &save); if (evergreen_mc_wait_for_idle(rdev)) { dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); } /* Disable CP parsing/prefetching */ WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); /* reset all the gfx blocks */ grbm_reset = (SOFT_RESET_CP | SOFT_RESET_CB | SOFT_RESET_DB | SOFT_RESET_GDS | SOFT_RESET_PA | SOFT_RESET_SC | SOFT_RESET_SPI | SOFT_RESET_SH | SOFT_RESET_SX | SOFT_RESET_TC | SOFT_RESET_TA | SOFT_RESET_VGT | SOFT_RESET_IA); dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset); WREG32(GRBM_SOFT_RESET, grbm_reset); (void)RREG32(GRBM_SOFT_RESET); udelay(50); WREG32(GRBM_SOFT_RESET, 0); (void)RREG32(GRBM_SOFT_RESET); /* Wait a little for things to settle down */ udelay(50); dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", RREG32(GRBM_STATUS)); dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", RREG32(GRBM_STATUS_SE0)); dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", RREG32(GRBM_STATUS_SE1)); dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", RREG32(SRBM_STATUS)); evergreen_mc_resume(rdev, &save); return 0; } int cayman_asic_reset(struct radeon_device *rdev) { return cayman_gpu_soft_reset(rdev); } drivers/gpu/drm/radeon/nid.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #define CAYMAN_MAX_TCC_MASK 0xFF #define DMIF_ADDR_CONFIG 0xBD4 #define SRBM_STATUS 0x0E50 #define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 #define REQUEST_TYPE(x) (((x) & 0xf) << 0) Loading Loading
drivers/gpu/drm/radeon/evergreen.c +3 −3 Original line number Diff line number Diff line Loading @@ -804,7 +804,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev) } } static int evergreen_mc_wait_for_idle(struct radeon_device *rdev) int evergreen_mc_wait_for_idle(struct radeon_device *rdev) { unsigned i; u32 tmp; Loading Loading @@ -957,7 +957,7 @@ void evergreen_agp_enable(struct radeon_device *rdev) WREG32(VM_CONTEXT1_CNTL, 0); } static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) { save->vga_control[0] = RREG32(D1VGA_CONTROL); save->vga_control[1] = RREG32(D2VGA_CONTROL); Loading Loading @@ -1011,7 +1011,7 @@ static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa WREG32(EVERGREEN_D6VGA_CONTROL, 0); } static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) { WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, upper_32_bits(rdev->mc.vram_start)); Loading
drivers/gpu/drm/radeon/ni.c +97 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,10 @@ #include "ni_reg.h" #include "cayman_blit_shaders.h" extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); #define EVERGREEN_PFP_UCODE_SIZE 1120 #define EVERGREEN_PM4_UCODE_SIZE 1376 #define EVERGREEN_RLC_UCODE_SIZE 768 Loading Loading @@ -1249,3 +1253,96 @@ int cayman_cp_resume(struct radeon_device *rdev) return 0; } bool cayman_gpu_is_lockup(struct radeon_device *rdev) { u32 srbm_status; u32 grbm_status; u32 grbm_status_se0, grbm_status_se1; struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup; int r; srbm_status = RREG32(SRBM_STATUS); grbm_status = RREG32(GRBM_STATUS); grbm_status_se0 = RREG32(GRBM_STATUS_SE0); grbm_status_se1 = RREG32(GRBM_STATUS_SE1); if (!(grbm_status & GUI_ACTIVE)) { r100_gpu_lockup_update(lockup, &rdev->cp); return false; } /* force CP activities */ r = radeon_ring_lock(rdev, 2); if (!r) { /* PACKET2 NOP */ radeon_ring_write(rdev, 0x80000000); radeon_ring_write(rdev, 0x80000000); radeon_ring_unlock_commit(rdev); } /* XXX deal with CP0,1,2 */ rdev->cp.rptr = RREG32(CP_RB0_RPTR); return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); } static int cayman_gpu_soft_reset(struct radeon_device *rdev) { struct evergreen_mc_save save; u32 grbm_reset = 0; if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) return 0; dev_info(rdev->dev, "GPU softreset \n"); dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", RREG32(GRBM_STATUS)); dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", RREG32(GRBM_STATUS_SE0)); dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", RREG32(GRBM_STATUS_SE1)); dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", RREG32(SRBM_STATUS)); evergreen_mc_stop(rdev, &save); if (evergreen_mc_wait_for_idle(rdev)) { dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); } /* Disable CP parsing/prefetching */ WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); /* reset all the gfx blocks */ grbm_reset = (SOFT_RESET_CP | SOFT_RESET_CB | SOFT_RESET_DB | SOFT_RESET_GDS | SOFT_RESET_PA | SOFT_RESET_SC | SOFT_RESET_SPI | SOFT_RESET_SH | SOFT_RESET_SX | SOFT_RESET_TC | SOFT_RESET_TA | SOFT_RESET_VGT | SOFT_RESET_IA); dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset); WREG32(GRBM_SOFT_RESET, grbm_reset); (void)RREG32(GRBM_SOFT_RESET); udelay(50); WREG32(GRBM_SOFT_RESET, 0); (void)RREG32(GRBM_SOFT_RESET); /* Wait a little for things to settle down */ udelay(50); dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", RREG32(GRBM_STATUS)); dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", RREG32(GRBM_STATUS_SE0)); dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", RREG32(GRBM_STATUS_SE1)); dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", RREG32(SRBM_STATUS)); evergreen_mc_resume(rdev, &save); return 0; } int cayman_asic_reset(struct radeon_device *rdev) { return cayman_gpu_soft_reset(rdev); }
drivers/gpu/drm/radeon/nid.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #define CAYMAN_MAX_TCC_MASK 0xFF #define DMIF_ADDR_CONFIG 0xBD4 #define SRBM_STATUS 0x0E50 #define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 #define REQUEST_TYPE(x) (((x) & 0xf) << 0) Loading