aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r100.c
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2009-08-29 09:53:51 -0400
committerDave Airlie <airlied@redhat.com>2009-08-30 19:09:30 -0400
commit70967ab9c0c9017645d167d33675eab996633631 (patch)
tree5ec85349ccbf2bd21ab4929223d94ac11d17fa44 /drivers/gpu/drm/radeon/r100.c
parent1ae70072f0699916c1a77a9bacad958ee46f7395 (diff)
radeon: Use request_firmware()
Loosely based on a patch by Jaswinder Singh Rajput <jaswinderlinux@gmail.com>. KMS support by Dave Airlie <airlied@redhat.com>. For Radeon 100- to 500-series, firmware blobs look like: struct { __be32 datah; __be32 datal; } cp_ucode[256]; For Radeon 600-series, there are two separate firmware blobs: __be32 me_ucode[PM4_UCODE_SIZE * 3]; __be32 pfp_ucode[PFP_UCODE_SIZE]; For Radeon 700-series, likewise: __be32 me_ucode[R700_PM4_UCODE_SIZE]; __be32 pfp_ucode[R700_PFP_UCODE_SIZE]; Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r--drivers/gpu/drm/radeon/r100.c119
1 files changed, 84 insertions, 35 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 90ff8e0ac04e..639d5b216eed 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -29,9 +29,27 @@
29#include "drmP.h" 29#include "drmP.h"
30#include "drm.h" 30#include "drm.h"
31#include "radeon_drm.h" 31#include "radeon_drm.h"
32#include "radeon_microcode.h"
33#include "radeon_reg.h" 32#include "radeon_reg.h"
34#include "radeon.h" 33#include "radeon.h"
34#include <linux/firmware.h>
35#include <linux/platform_device.h>
36
37/* Firmware Names */
38#define FIRMWARE_R100 "radeon/R100_cp.bin"
39#define FIRMWARE_R200 "radeon/R200_cp.bin"
40#define FIRMWARE_R300 "radeon/R300_cp.bin"
41#define FIRMWARE_R420 "radeon/R420_cp.bin"
42#define FIRMWARE_RS690 "radeon/RS690_cp.bin"
43#define FIRMWARE_RS600 "radeon/RS600_cp.bin"
44#define FIRMWARE_R520 "radeon/R520_cp.bin"
45
46MODULE_FIRMWARE(FIRMWARE_R100);
47MODULE_FIRMWARE(FIRMWARE_R200);
48MODULE_FIRMWARE(FIRMWARE_R300);
49MODULE_FIRMWARE(FIRMWARE_R420);
50MODULE_FIRMWARE(FIRMWARE_RS690);
51MODULE_FIRMWARE(FIRMWARE_RS600);
52MODULE_FIRMWARE(FIRMWARE_R520);
35 53
36/* This files gather functions specifics to: 54/* This files gather functions specifics to:
37 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 55 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
@@ -478,33 +496,33 @@ void r100_ring_start(struct radeon_device *rdev)
478 radeon_ring_unlock_commit(rdev); 496 radeon_ring_unlock_commit(rdev);
479} 497}
480 498
481static void r100_cp_load_microcode(struct radeon_device *rdev) 499
500/* Load the microcode for the CP */
501static int r100_cp_init_microcode(struct radeon_device *rdev)
482{ 502{
483 int i; 503 struct platform_device *pdev;
504 const char *fw_name = NULL;
505 int err;
484 506
485 if (r100_gui_wait_for_idle(rdev)) { 507 DRM_DEBUG("\n");
486 printk(KERN_WARNING "Failed to wait GUI idle while "
487 "programming pipes. Bad things might happen.\n");
488 }
489 508
490 WREG32(RADEON_CP_ME_RAM_ADDR, 0); 509 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
510 err = IS_ERR(pdev);
511 if (err) {
512 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
513 return -EINVAL;
514 }
491 if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || 515 if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
492 (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || 516 (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
493 (rdev->family == CHIP_RS200)) { 517 (rdev->family == CHIP_RS200)) {
494 DRM_INFO("Loading R100 Microcode\n"); 518 DRM_INFO("Loading R100 Microcode\n");
495 for (i = 0; i < 256; i++) { 519 fw_name = FIRMWARE_R100;
496 WREG32(RADEON_CP_ME_RAM_DATAH, R100_cp_microcode[i][1]);
497 WREG32(RADEON_CP_ME_RAM_DATAL, R100_cp_microcode[i][0]);
498 }
499 } else if ((rdev->family == CHIP_R200) || 520 } else if ((rdev->family == CHIP_R200) ||
500 (rdev->family == CHIP_RV250) || 521 (rdev->family == CHIP_RV250) ||
501 (rdev->family == CHIP_RV280) || 522 (rdev->family == CHIP_RV280) ||
502 (rdev->family == CHIP_RS300)) { 523 (rdev->family == CHIP_RS300)) {
503 DRM_INFO("Loading R200 Microcode\n"); 524 DRM_INFO("Loading R200 Microcode\n");
504 for (i = 0; i < 256; i++) { 525 fw_name = FIRMWARE_R200;
505 WREG32(RADEON_CP_ME_RAM_DATAH, R200_cp_microcode[i][1]);
506 WREG32(RADEON_CP_ME_RAM_DATAL, R200_cp_microcode[i][0]);
507 }
508 } else if ((rdev->family == CHIP_R300) || 526 } else if ((rdev->family == CHIP_R300) ||
509 (rdev->family == CHIP_R350) || 527 (rdev->family == CHIP_R350) ||
510 (rdev->family == CHIP_RV350) || 528 (rdev->family == CHIP_RV350) ||
@@ -512,31 +530,19 @@ static void r100_cp_load_microcode(struct radeon_device *rdev)
512 (rdev->family == CHIP_RS400) || 530 (rdev->family == CHIP_RS400) ||
513 (rdev->family == CHIP_RS480)) { 531 (rdev->family == CHIP_RS480)) {
514 DRM_INFO("Loading R300 Microcode\n"); 532 DRM_INFO("Loading R300 Microcode\n");
515 for (i = 0; i < 256; i++) { 533 fw_name = FIRMWARE_R300;
516 WREG32(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]);
517 WREG32(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]);
518 }
519 } else if ((rdev->family == CHIP_R420) || 534 } else if ((rdev->family == CHIP_R420) ||
520 (rdev->family == CHIP_R423) || 535 (rdev->family == CHIP_R423) ||
521 (rdev->family == CHIP_RV410)) { 536 (rdev->family == CHIP_RV410)) {
522 DRM_INFO("Loading R400 Microcode\n"); 537 DRM_INFO("Loading R400 Microcode\n");
523 for (i = 0; i < 256; i++) { 538 fw_name = FIRMWARE_R420;
524 WREG32(RADEON_CP_ME_RAM_DATAH, R420_cp_microcode[i][1]);
525 WREG32(RADEON_CP_ME_RAM_DATAL, R420_cp_microcode[i][0]);
526 }
527 } else if ((rdev->family == CHIP_RS690) || 539 } else if ((rdev->family == CHIP_RS690) ||
528 (rdev->family == CHIP_RS740)) { 540 (rdev->family == CHIP_RS740)) {
529 DRM_INFO("Loading RS690/RS740 Microcode\n"); 541 DRM_INFO("Loading RS690/RS740 Microcode\n");
530 for (i = 0; i < 256; i++) { 542 fw_name = FIRMWARE_RS690;
531 WREG32(RADEON_CP_ME_RAM_DATAH, RS690_cp_microcode[i][1]);
532 WREG32(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]);
533 }
534 } else if (rdev->family == CHIP_RS600) { 543 } else if (rdev->family == CHIP_RS600) {
535 DRM_INFO("Loading RS600 Microcode\n"); 544 DRM_INFO("Loading RS600 Microcode\n");
536 for (i = 0; i < 256; i++) { 545 fw_name = FIRMWARE_RS600;
537 WREG32(RADEON_CP_ME_RAM_DATAH, RS600_cp_microcode[i][1]);
538 WREG32(RADEON_CP_ME_RAM_DATAL, RS600_cp_microcode[i][0]);
539 }
540 } else if ((rdev->family == CHIP_RV515) || 546 } else if ((rdev->family == CHIP_RV515) ||
541 (rdev->family == CHIP_R520) || 547 (rdev->family == CHIP_R520) ||
542 (rdev->family == CHIP_RV530) || 548 (rdev->family == CHIP_RV530) ||
@@ -544,9 +550,43 @@ static void r100_cp_load_microcode(struct radeon_device *rdev)
544 (rdev->family == CHIP_RV560) || 550 (rdev->family == CHIP_RV560) ||
545 (rdev->family == CHIP_RV570)) { 551 (rdev->family == CHIP_RV570)) {
546 DRM_INFO("Loading R500 Microcode\n"); 552 DRM_INFO("Loading R500 Microcode\n");
547 for (i = 0; i < 256; i++) { 553 fw_name = FIRMWARE_R520;
548 WREG32(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]); 554 }
549 WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]); 555
556 err = request_firmware(&rdev->fw, fw_name, &pdev->dev);
557 platform_device_unregister(pdev);
558 if (err) {
559 printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
560 fw_name);
561 } else if (rdev->fw->size % 8) {
562 printk(KERN_ERR
563 "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
564 rdev->fw->size, fw_name);
565 err = -EINVAL;
566 release_firmware(rdev->fw);
567 rdev->fw = NULL;
568 }
569 return err;
570}
571static void r100_cp_load_microcode(struct radeon_device *rdev)
572{
573 const __be32 *fw_data;
574 int i, size;
575
576 if (r100_gui_wait_for_idle(rdev)) {
577 printk(KERN_WARNING "Failed to wait GUI idle while "
578 "programming pipes. Bad things might happen.\n");
579 }
580
581 if (rdev->fw) {
582 size = rdev->fw->size / 4;
583 fw_data = (const __be32 *)&rdev->fw->data[0];
584 WREG32(RADEON_CP_ME_RAM_ADDR, 0);
585 for (i = 0; i < size; i += 2) {
586 WREG32(RADEON_CP_ME_RAM_DATAH,
587 be32_to_cpup(&fw_data[i]));
588 WREG32(RADEON_CP_ME_RAM_DATAL,
589 be32_to_cpup(&fw_data[i + 1]));
550 } 590 }
551 } 591 }
552} 592}
@@ -585,6 +625,15 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
585 } else { 625 } else {
586 DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); 626 DRM_INFO("radeon: cp idle (0x%08X)\n", tmp);
587 } 627 }
628
629 if (!rdev->fw) {
630 r = r100_cp_init_microcode(rdev);
631 if (r) {
632 DRM_ERROR("Failed to load firmware!\n");
633 return r;
634 }
635 }
636
588 /* Align ring size */ 637 /* Align ring size */
589 rb_bufsz = drm_order(ring_size / 8); 638 rb_bufsz = drm_order(ring_size / 8);
590 ring_size = (1 << (rb_bufsz + 1)) * 4; 639 ring_size = (1 << (rb_bufsz + 1)) * 4;