aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cp.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c128
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
50MODULE_FIRMWARE(FIRMWARE_R100);
51MODULE_FIRMWARE(FIRMWARE_R200);
52MODULE_FIRMWARE(FIRMWARE_R300);
53MODULE_FIRMWARE(FIRMWARE_R420);
54MODULE_FIRMWARE(FIRMWARE_RS690);
55MODULE_FIRMWARE(FIRMWARE_RS600);
56MODULE_FIRMWARE(FIRMWARE_R520);
57
43static int radeon_do_cleanup_cp(struct drm_device * dev); 58static int radeon_do_cleanup_cp(struct drm_device * dev);
44static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); 59static 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 */
454static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) 469static 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
543static 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