mirror of
https://github.com/torvalds/linux.git
synced 2024-12-18 00:53:40 +00:00
drm/radeon/kms: add cayman asic reset support
Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
127278099f
commit
b9952a8ae5
@ -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;
|
||||
@ -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);
|
||||
@ -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));
|
||||
|
@ -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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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…
Reference in New Issue
Block a user