diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cp.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cp.c | 128 |
1 files changed, 83 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index d8356827ef17..6b6cc8434d3c 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -36,10 +36,25 @@ | |||
36 | #include "radeon_drv.h" | 36 | #include "radeon_drv.h" |
37 | #include "r300_reg.h" | 37 | #include "r300_reg.h" |
38 | 38 | ||
39 | #include "radeon_microcode.h" | ||
40 | |||
41 | #define RADEON_FIFO_DEBUG 0 | 39 | #define RADEON_FIFO_DEBUG 0 |
42 | 40 | ||
41 | /* Firmware Names */ | ||
42 | #define FIRMWARE_R100 "radeon/R100_cp.bin" | ||
43 | #define FIRMWARE_R200 "radeon/R200_cp.bin" | ||
44 | #define FIRMWARE_R300 "radeon/R300_cp.bin" | ||
45 | #define FIRMWARE_R420 "radeon/R420_cp.bin" | ||
46 | #define FIRMWARE_RS690 "radeon/RS690_cp.bin" | ||
47 | #define FIRMWARE_RS600 "radeon/RS600_cp.bin" | ||
48 | #define FIRMWARE_R520 "radeon/R520_cp.bin" | ||
49 | |||
50 | MODULE_FIRMWARE(FIRMWARE_R100); | ||
51 | MODULE_FIRMWARE(FIRMWARE_R200); | ||
52 | MODULE_FIRMWARE(FIRMWARE_R300); | ||
53 | MODULE_FIRMWARE(FIRMWARE_R420); | ||
54 | MODULE_FIRMWARE(FIRMWARE_RS690); | ||
55 | MODULE_FIRMWARE(FIRMWARE_RS600); | ||
56 | MODULE_FIRMWARE(FIRMWARE_R520); | ||
57 | |||
43 | static int radeon_do_cleanup_cp(struct drm_device * dev); | 58 | static int radeon_do_cleanup_cp(struct drm_device * dev); |
44 | static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); | 59 | static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); |
45 | 60 | ||
@@ -451,37 +466,34 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) | |||
451 | */ | 466 | */ |
452 | 467 | ||
453 | /* Load the microcode for the CP */ | 468 | /* Load the microcode for the CP */ |
454 | static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) | 469 | static int radeon_cp_init_microcode(drm_radeon_private_t *dev_priv) |
455 | { | 470 | { |
456 | int i; | 471 | struct platform_device *pdev; |
472 | const char *fw_name = NULL; | ||
473 | int err; | ||
474 | |||
457 | DRM_DEBUG("\n"); | 475 | DRM_DEBUG("\n"); |
458 | 476 | ||
459 | radeon_do_wait_for_idle(dev_priv); | 477 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); |
478 | err = IS_ERR(pdev); | ||
479 | if (err) { | ||
480 | printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); | ||
481 | return -EINVAL; | ||
482 | } | ||
460 | 483 | ||
461 | RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); | ||
462 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || | 484 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || |
463 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || | 485 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || |
464 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || | 486 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || |
465 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) || | 487 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) || |
466 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) { | 488 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) { |
467 | DRM_INFO("Loading R100 Microcode\n"); | 489 | DRM_INFO("Loading R100 Microcode\n"); |
468 | for (i = 0; i < 256; i++) { | 490 | fw_name = FIRMWARE_R100; |
469 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | ||
470 | R100_cp_microcode[i][1]); | ||
471 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | ||
472 | R100_cp_microcode[i][0]); | ||
473 | } | ||
474 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) || | 491 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) || |
475 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) || | 492 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) || |
476 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) || | 493 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) || |
477 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) { | 494 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) { |
478 | DRM_INFO("Loading R200 Microcode\n"); | 495 | DRM_INFO("Loading R200 Microcode\n"); |
479 | for (i = 0; i < 256; i++) { | 496 | fw_name = FIRMWARE_R200; |
480 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | ||
481 | R200_cp_microcode[i][1]); | ||
482 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | ||
483 | R200_cp_microcode[i][0]); | ||
484 | } | ||
485 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || | 497 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || |
486 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || | 498 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || |
487 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || | 499 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || |
@@ -489,39 +501,19 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) | |||
489 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || | 501 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || |
490 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { | 502 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { |
491 | DRM_INFO("Loading R300 Microcode\n"); | 503 | DRM_INFO("Loading R300 Microcode\n"); |
492 | for (i = 0; i < 256; i++) { | 504 | fw_name = FIRMWARE_R300; |
493 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | ||
494 | R300_cp_microcode[i][1]); | ||
495 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | ||
496 | R300_cp_microcode[i][0]); | ||
497 | } | ||
498 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || | 505 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || |
499 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || | 506 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || |
500 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { | 507 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { |
501 | DRM_INFO("Loading R400 Microcode\n"); | 508 | DRM_INFO("Loading R400 Microcode\n"); |
502 | for (i = 0; i < 256; i++) { | 509 | fw_name = FIRMWARE_R420; |
503 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | ||
504 | R420_cp_microcode[i][1]); | ||
505 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | ||
506 | R420_cp_microcode[i][0]); | ||
507 | } | ||
508 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | 510 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
509 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { | 511 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { |
510 | DRM_INFO("Loading RS690/RS740 Microcode\n"); | 512 | DRM_INFO("Loading RS690/RS740 Microcode\n"); |
511 | for (i = 0; i < 256; i++) { | 513 | fw_name = FIRMWARE_RS690; |
512 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | ||
513 | RS690_cp_microcode[i][1]); | ||
514 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | ||
515 | RS690_cp_microcode[i][0]); | ||
516 | } | ||
517 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { | 514 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { |
518 | DRM_INFO("Loading RS600 Microcode\n"); | 515 | DRM_INFO("Loading RS600 Microcode\n"); |
519 | for (i = 0; i < 256; i++) { | 516 | fw_name = FIRMWARE_RS600; |
520 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | ||
521 | RS600_cp_microcode[i][1]); | ||
522 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | ||
523 | RS600_cp_microcode[i][0]); | ||
524 | } | ||
525 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || | 517 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || |
526 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || | 518 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || |
527 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || | 519 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || |
@@ -529,11 +521,41 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) | |||
529 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) || | 521 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) || |
530 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) { | 522 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) { |
531 | DRM_INFO("Loading R500 Microcode\n"); | 523 | DRM_INFO("Loading R500 Microcode\n"); |
532 | for (i = 0; i < 256; i++) { | 524 | fw_name = FIRMWARE_R520; |
525 | } | ||
526 | |||
527 | err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev); | ||
528 | platform_device_unregister(pdev); | ||
529 | if (err) { | ||
530 | printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", | ||
531 | fw_name); | ||
532 | } else if (dev_priv->me_fw->size % 8) { | ||
533 | printk(KERN_ERR | ||
534 | "radeon_cp: Bogus length %zu in firmware \"%s\"\n", | ||
535 | dev_priv->me_fw->size, fw_name); | ||
536 | err = -EINVAL; | ||
537 | release_firmware(dev_priv->me_fw); | ||
538 | dev_priv->me_fw = NULL; | ||
539 | } | ||
540 | return err; | ||
541 | } | ||
542 | |||
543 | static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv) | ||
544 | { | ||
545 | const __be32 *fw_data; | ||
546 | int i, size; | ||
547 | |||
548 | radeon_do_wait_for_idle(dev_priv); | ||
549 | |||
550 | if (dev_priv->me_fw) { | ||
551 | size = dev_priv->me_fw->size / 4; | ||
552 | fw_data = (const __be32 *)&dev_priv->me_fw->data[0]; | ||
553 | RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); | ||
554 | for (i = 0; i < size; i += 2) { | ||
533 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | 555 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, |
534 | R520_cp_microcode[i][1]); | 556 | be32_to_cpup(&fw_data[i])); |
535 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | 557 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, |
536 | R520_cp_microcode[i][0]); | 558 | be32_to_cpup(&fw_data[i + 1])); |
537 | } | 559 | } |
538 | } | 560 | } |
539 | } | 561 | } |
@@ -1486,6 +1508,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | |||
1486 | radeon_set_pcigart(dev_priv, 1); | 1508 | radeon_set_pcigart(dev_priv, 1); |
1487 | } | 1509 | } |
1488 | 1510 | ||
1511 | if (!dev_priv->me_fw) { | ||
1512 | int err = radeon_cp_init_microcode(dev_priv); | ||
1513 | if (err) { | ||
1514 | DRM_ERROR("Failed to load firmware!\n"); | ||
1515 | radeon_do_cleanup_cp(dev); | ||
1516 | return err; | ||
1517 | } | ||
1518 | } | ||
1489 | radeon_cp_load_microcode(dev_priv); | 1519 | radeon_cp_load_microcode(dev_priv); |
1490 | radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); | 1520 | radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); |
1491 | 1521 | ||
@@ -1755,6 +1785,14 @@ void radeon_do_release(struct drm_device * dev) | |||
1755 | r600_do_cleanup_cp(dev); | 1785 | r600_do_cleanup_cp(dev); |
1756 | else | 1786 | else |
1757 | radeon_do_cleanup_cp(dev); | 1787 | radeon_do_cleanup_cp(dev); |
1788 | if (dev_priv->me_fw) { | ||
1789 | release_firmware(dev_priv->me_fw); | ||
1790 | dev_priv->me_fw = NULL; | ||
1791 | } | ||
1792 | if (dev_priv->pfp_fw) { | ||
1793 | release_firmware(dev_priv->pfp_fw); | ||
1794 | dev_priv->pfp_fw = NULL; | ||
1795 | } | ||
1758 | } | 1796 | } |
1759 | } | 1797 | } |
1760 | 1798 | ||