aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/evergreen.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-03-24 13:36:43 -0400
committerDave Airlie <airlied@redhat.com>2010-04-08 20:16:04 -0400
commitfe251e2fffa1ebc17c8e6e895b0374ae4e732fa5 (patch)
tree995060a10005d4a284bebcd0412fabfd0805de89 /drivers/gpu/drm/radeon/evergreen.c
parent32fcdbf4084544c3d8fa413004d57e5dc6f2eefe (diff)
drm/radeon/kms/evergreen: setup and enable the CP
The command processor (CP) fetches command buffers and feeds the GPU. This patch requires the evergreen family me and pfp ucode files. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c117
1 files changed, 96 insertions, 21 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 26b219bb1388..57fe569682df 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -32,6 +32,9 @@
32#include "avivod.h" 32#include "avivod.h"
33#include "evergreen_reg.h" 33#include "evergreen_reg.h"
34 34
35#define EVERGREEN_PFP_UCODE_SIZE 1120
36#define EVERGREEN_PM4_UCODE_SIZE 1376
37
35static void evergreen_gpu_init(struct radeon_device *rdev); 38static void evergreen_gpu_init(struct radeon_device *rdev);
36void evergreen_fini(struct radeon_device *rdev); 39void evergreen_fini(struct radeon_device *rdev);
37 40
@@ -418,23 +421,91 @@ static void evergreen_mc_program(struct radeon_device *rdev)
418 rv515_vga_render_disable(rdev); 421 rv515_vga_render_disable(rdev);
419} 422}
420 423
421#if 0
422/* 424/*
423 * CP. 425 * CP.
424 */ 426 */
425static void evergreen_cp_stop(struct radeon_device *rdev)
426{
427 /* XXX */
428}
429
430 427
431static int evergreen_cp_load_microcode(struct radeon_device *rdev) 428static int evergreen_cp_load_microcode(struct radeon_device *rdev)
432{ 429{
433 /* XXX */ 430 const __be32 *fw_data;
431 int i;
432
433 if (!rdev->me_fw || !rdev->pfp_fw)
434 return -EINVAL;
434 435
436 r700_cp_stop(rdev);
437 WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0));
438
439 fw_data = (const __be32 *)rdev->pfp_fw->data;
440 WREG32(CP_PFP_UCODE_ADDR, 0);
441 for (i = 0; i < EVERGREEN_PFP_UCODE_SIZE; i++)
442 WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
443 WREG32(CP_PFP_UCODE_ADDR, 0);
444
445 fw_data = (const __be32 *)rdev->me_fw->data;
446 WREG32(CP_ME_RAM_WADDR, 0);
447 for (i = 0; i < EVERGREEN_PM4_UCODE_SIZE; i++)
448 WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
449
450 WREG32(CP_PFP_UCODE_ADDR, 0);
451 WREG32(CP_ME_RAM_WADDR, 0);
452 WREG32(CP_ME_RAM_RADDR, 0);
435 return 0; 453 return 0;
436} 454}
455
456int evergreen_cp_resume(struct radeon_device *rdev)
457{
458 u32 tmp;
459 u32 rb_bufsz;
460 int r;
461
462 /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
463 WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
464 SOFT_RESET_PA |
465 SOFT_RESET_SH |
466 SOFT_RESET_VGT |
467 SOFT_RESET_SX));
468 RREG32(GRBM_SOFT_RESET);
469 mdelay(15);
470 WREG32(GRBM_SOFT_RESET, 0);
471 RREG32(GRBM_SOFT_RESET);
472
473 /* Set ring buffer size */
474 rb_bufsz = drm_order(rdev->cp.ring_size / 8);
475 tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
476#ifdef __BIG_ENDIAN
477 tmp |= BUF_SWAP_32BIT;
437#endif 478#endif
479 WREG32(CP_RB_CNTL, tmp);
480 WREG32(CP_SEM_WAIT_TIMER, 0x4);
481
482 /* Set the write pointer delay */
483 WREG32(CP_RB_WPTR_DELAY, 0);
484
485 /* Initialize the ring buffer's read and write pointers */
486 WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
487 WREG32(CP_RB_RPTR_WR, 0);
488 WREG32(CP_RB_WPTR, 0);
489 WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF);
490 WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr));
491 mdelay(1);
492 WREG32(CP_RB_CNTL, tmp);
493
494 WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8);
495 WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
496
497 rdev->cp.rptr = RREG32(CP_RB_RPTR);
498 rdev->cp.wptr = RREG32(CP_RB_WPTR);
499
500 r600_cp_start(rdev);
501 rdev->cp.ready = true;
502 r = radeon_ring_test(rdev);
503 if (r) {
504 rdev->cp.ready = false;
505 return r;
506 }
507 return 0;
508}
438 509
439/* 510/*
440 * Core functions 511 * Core functions
@@ -1138,15 +1209,15 @@ static int evergreen_startup(struct radeon_device *rdev)
1138{ 1209{
1139 int r; 1210 int r;
1140 1211
1141#if 0 1212 /* XXX until interrupts are supported */
1142 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { 1213 if (!rdev->me_fw || !rdev->pfp_fw /*|| !rdev->rlc_fw*/) {
1143 r = r600_init_microcode(rdev); 1214 r = r600_init_microcode(rdev);
1144 if (r) { 1215 if (r) {
1145 DRM_ERROR("Failed to load firmware!\n"); 1216 DRM_ERROR("Failed to load firmware!\n");
1146 return r; 1217 return r;
1147 } 1218 }
1148 } 1219 }
1149#endif 1220
1150 evergreen_mc_program(rdev); 1221 evergreen_mc_program(rdev);
1151 if (rdev->flags & RADEON_IS_AGP) { 1222 if (rdev->flags & RADEON_IS_AGP) {
1152 evergreen_agp_enable(rdev); 1223 evergreen_agp_enable(rdev);
@@ -1184,6 +1255,7 @@ static int evergreen_startup(struct radeon_device *rdev)
1184 return r; 1255 return r;
1185 } 1256 }
1186 r600_irq_set(rdev); 1257 r600_irq_set(rdev);
1258#endif
1187 1259
1188 r = radeon_ring_init(rdev, rdev->cp.ring_size); 1260 r = radeon_ring_init(rdev, rdev->cp.ring_size);
1189 if (r) 1261 if (r)
@@ -1191,12 +1263,12 @@ static int evergreen_startup(struct radeon_device *rdev)
1191 r = evergreen_cp_load_microcode(rdev); 1263 r = evergreen_cp_load_microcode(rdev);
1192 if (r) 1264 if (r)
1193 return r; 1265 return r;
1194 r = r600_cp_resume(rdev); 1266 r = evergreen_cp_resume(rdev);
1195 if (r) 1267 if (r)
1196 return r; 1268 return r;
1197 /* write back buffer are not vital so don't worry about failure */ 1269 /* write back buffer are not vital so don't worry about failure */
1198 r600_wb_enable(rdev); 1270 r600_wb_enable(rdev);
1199#endif 1271
1200 return 0; 1272 return 0;
1201} 1273}
1202 1274
@@ -1221,13 +1293,13 @@ int evergreen_resume(struct radeon_device *rdev)
1221 DRM_ERROR("r600 startup failed on resume\n"); 1293 DRM_ERROR("r600 startup failed on resume\n");
1222 return r; 1294 return r;
1223 } 1295 }
1224#if 0 1296
1225 r = r600_ib_test(rdev); 1297 r = r600_ib_test(rdev);
1226 if (r) { 1298 if (r) {
1227 DRM_ERROR("radeon: failled testing IB (%d).\n", r); 1299 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1228 return r; 1300 return r;
1229 } 1301 }
1230#endif 1302
1231 return r; 1303 return r;
1232 1304
1233} 1305}
@@ -1236,12 +1308,11 @@ int evergreen_suspend(struct radeon_device *rdev)
1236{ 1308{
1237#if 0 1309#if 0
1238 int r; 1310 int r;
1239 1311#endif
1240 /* FIXME: we should wait for ring to be empty */ 1312 /* FIXME: we should wait for ring to be empty */
1241 r700_cp_stop(rdev); 1313 r700_cp_stop(rdev);
1242 rdev->cp.ready = false; 1314 rdev->cp.ready = false;
1243 r600_wb_disable(rdev); 1315 r600_wb_disable(rdev);
1244#endif
1245 1316
1246 evergreen_pcie_gart_disable(rdev); 1317 evergreen_pcie_gart_disable(rdev);
1247#if 0 1318#if 0
@@ -1348,10 +1419,10 @@ int evergreen_init(struct radeon_device *rdev)
1348 r = radeon_irq_kms_init(rdev); 1419 r = radeon_irq_kms_init(rdev);
1349 if (r) 1420 if (r)
1350 return r; 1421 return r;
1351 1422#endif
1352 rdev->cp.ring_obj = NULL; 1423 rdev->cp.ring_obj = NULL;
1353 r600_ring_init(rdev, 1024 * 1024); 1424 r600_ring_init(rdev, 1024 * 1024);
1354 1425#if 0
1355 rdev->ih.ring_obj = NULL; 1426 rdev->ih.ring_obj = NULL;
1356 r600_ih_ring_init(rdev, 64 * 1024); 1427 r600_ih_ring_init(rdev, 64 * 1024);
1357#endif 1428#endif
@@ -1362,9 +1433,13 @@ int evergreen_init(struct radeon_device *rdev)
1362 rdev->accel_working = false; 1433 rdev->accel_working = false;
1363 r = evergreen_startup(rdev); 1434 r = evergreen_startup(rdev);
1364 if (r) { 1435 if (r) {
1365 evergreen_suspend(rdev); 1436 dev_err(rdev->dev, "disabling GPU acceleration\n");
1366 /*r600_wb_fini(rdev);*/ 1437 r700_cp_fini(rdev);
1367 /*radeon_ring_fini(rdev);*/ 1438 r600_wb_fini(rdev);
1439#if 0
1440 r600_irq_fini(rdev);
1441 radeon_irq_kms_fini(rdev);
1442#endif
1368 evergreen_pcie_gart_fini(rdev); 1443 evergreen_pcie_gart_fini(rdev);
1369 rdev->accel_working = false; 1444 rdev->accel_working = false;
1370 } 1445 }