aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2011-03-02 20:07:33 -0500
committerDave Airlie <airlied@redhat.com>2011-03-02 20:51:21 -0500
commitb9952a8ae5814b0ef2a6596c7443efd85b92e069 (patch)
tree2e259e9cde37c717a2f45c88c0084e2c23f141de /drivers/gpu/drm/radeon
parent127278099f25a14b00c502f64b120472b512528d (diff)
drm/radeon/kms: add cayman asic reset support
Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c6
-rw-r--r--drivers/gpu/drm/radeon/ni.c97
-rw-r--r--drivers/gpu/drm/radeon/nid.h1
3 files changed, 101 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index ffdc8332b76e..0a3d6fc13c2d 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -804,7 +804,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev)
804 } 804 }
805} 805}
806 806
807static int evergreen_mc_wait_for_idle(struct radeon_device *rdev) 807int evergreen_mc_wait_for_idle(struct radeon_device *rdev)
808{ 808{
809 unsigned i; 809 unsigned i;
810 u32 tmp; 810 u32 tmp;
@@ -957,7 +957,7 @@ void evergreen_agp_enable(struct radeon_device *rdev)
957 WREG32(VM_CONTEXT1_CNTL, 0); 957 WREG32(VM_CONTEXT1_CNTL, 0);
958} 958}
959 959
960static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) 960void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
961{ 961{
962 save->vga_control[0] = RREG32(D1VGA_CONTROL); 962 save->vga_control[0] = RREG32(D1VGA_CONTROL);
963 save->vga_control[1] = RREG32(D2VGA_CONTROL); 963 save->vga_control[1] = RREG32(D2VGA_CONTROL);
@@ -1011,7 +1011,7 @@ static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa
1011 WREG32(EVERGREEN_D6VGA_CONTROL, 0); 1011 WREG32(EVERGREEN_D6VGA_CONTROL, 0);
1012} 1012}
1013 1013
1014static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) 1014void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
1015{ 1015{
1016 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, 1016 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
1017 upper_32_bits(rdev->mc.vram_start)); 1017 upper_32_bits(rdev->mc.vram_start));
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 0fecad240007..3a3fdf5b5dd2 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -33,6 +33,10 @@
33#include "ni_reg.h" 33#include "ni_reg.h"
34#include "cayman_blit_shaders.h" 34#include "cayman_blit_shaders.h"
35 35
36extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
37extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
38extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
39
36#define EVERGREEN_PFP_UCODE_SIZE 1120 40#define EVERGREEN_PFP_UCODE_SIZE 1120
37#define EVERGREEN_PM4_UCODE_SIZE 1376 41#define EVERGREEN_PM4_UCODE_SIZE 1376
38#define EVERGREEN_RLC_UCODE_SIZE 768 42#define EVERGREEN_RLC_UCODE_SIZE 768
@@ -1249,3 +1253,96 @@ int cayman_cp_resume(struct radeon_device *rdev)
1249 return 0; 1253 return 0;
1250} 1254}
1251 1255
1256bool cayman_gpu_is_lockup(struct radeon_device *rdev)
1257{
1258 u32 srbm_status;
1259 u32 grbm_status;
1260 u32 grbm_status_se0, grbm_status_se1;
1261 struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup;
1262 int r;
1263
1264 srbm_status = RREG32(SRBM_STATUS);
1265 grbm_status = RREG32(GRBM_STATUS);
1266 grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
1267 grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
1268 if (!(grbm_status & GUI_ACTIVE)) {
1269 r100_gpu_lockup_update(lockup, &rdev->cp);
1270 return false;
1271 }
1272 /* force CP activities */
1273 r = radeon_ring_lock(rdev, 2);
1274 if (!r) {
1275 /* PACKET2 NOP */
1276 radeon_ring_write(rdev, 0x80000000);
1277 radeon_ring_write(rdev, 0x80000000);
1278 radeon_ring_unlock_commit(rdev);
1279 }
1280 /* XXX deal with CP0,1,2 */
1281 rdev->cp.rptr = RREG32(CP_RB0_RPTR);
1282 return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp);
1283}
1284
1285static int cayman_gpu_soft_reset(struct radeon_device *rdev)
1286{
1287 struct evergreen_mc_save save;
1288 u32 grbm_reset = 0;
1289
1290 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
1291 return 0;
1292
1293 dev_info(rdev->dev, "GPU softreset \n");
1294 dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
1295 RREG32(GRBM_STATUS));
1296 dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n",
1297 RREG32(GRBM_STATUS_SE0));
1298 dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n",
1299 RREG32(GRBM_STATUS_SE1));
1300 dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n",
1301 RREG32(SRBM_STATUS));
1302 evergreen_mc_stop(rdev, &save);
1303 if (evergreen_mc_wait_for_idle(rdev)) {
1304 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1305 }
1306 /* Disable CP parsing/prefetching */
1307 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1308
1309 /* reset all the gfx blocks */
1310 grbm_reset = (SOFT_RESET_CP |
1311 SOFT_RESET_CB |
1312 SOFT_RESET_DB |
1313 SOFT_RESET_GDS |
1314 SOFT_RESET_PA |
1315 SOFT_RESET_SC |
1316 SOFT_RESET_SPI |
1317 SOFT_RESET_SH |
1318 SOFT_RESET_SX |
1319 SOFT_RESET_TC |
1320 SOFT_RESET_TA |
1321 SOFT_RESET_VGT |
1322 SOFT_RESET_IA);
1323
1324 dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset);
1325 WREG32(GRBM_SOFT_RESET, grbm_reset);
1326 (void)RREG32(GRBM_SOFT_RESET);
1327 udelay(50);
1328 WREG32(GRBM_SOFT_RESET, 0);
1329 (void)RREG32(GRBM_SOFT_RESET);
1330 /* Wait a little for things to settle down */
1331 udelay(50);
1332 dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
1333 RREG32(GRBM_STATUS));
1334 dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n",
1335 RREG32(GRBM_STATUS_SE0));
1336 dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n",
1337 RREG32(GRBM_STATUS_SE1));
1338 dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n",
1339 RREG32(SRBM_STATUS));
1340 evergreen_mc_resume(rdev, &save);
1341 return 0;
1342}
1343
1344int cayman_asic_reset(struct radeon_device *rdev)
1345{
1346 return cayman_gpu_soft_reset(rdev);
1347}
1348
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 57062f14acc9..0f9a08b53fbd 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -42,6 +42,7 @@
42#define CAYMAN_MAX_TCC_MASK 0xFF 42#define CAYMAN_MAX_TCC_MASK 0xFF
43 43
44#define DMIF_ADDR_CONFIG 0xBD4 44#define DMIF_ADDR_CONFIG 0xBD4
45#define SRBM_STATUS 0x0E50
45 46
46#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 47#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470
47#define REQUEST_TYPE(x) (((x) & 0xf) << 0) 48#define REQUEST_TYPE(x) (((x) & 0xf) << 0)