Here's a patch to make r128 use request_firmware. This is compile-tested only as I don't have appropriate hardware. The firmware file can be produced by writing the array as 32-bit little-endian values. However, there is still a problem with its licence.
Ben. diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig index 610d6fd..ea26dfd 100644 --- a/drivers/char/drm/Kconfig +++ b/drivers/char/drm/Kconfig @@ -26,6 +26,7 @@ config DRM_TDFX config DRM_R128 tristate "ATI Rage 128" depends on DRM && PCI + select FW_LOADER help Choose this option if you have an ATI Rage 128 graphics card. If M is selected, the module will be called r128. AGP support for diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index c31afbd..e29c082 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c @@ -29,6 +29,8 @@ * Gareth Hughes <[EMAIL PROTECTED]> */ +#include <linux/firmware.h> + #include "drmP.h" #include "drm.h" #include "r128_drm.h" @@ -36,51 +38,6 @@ #define R128_FIFO_DEBUG 0 -/* CCE microcode (from ATI) */ -static u32 r128_cce_microcode[] = { - 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, - 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, - 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1, - 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11, - 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28, - 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, - 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, - 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, - 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071, - 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2, - 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1, - 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, - 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, - 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, - 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1, - 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82, - 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729, - 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008, - 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, - 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, - 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, - 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0, - 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370, - 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1, - 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793, - 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, - 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, - 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1, - 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1, - 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894, - 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14, - 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1, - 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, - 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, - 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - static int R128_READ_PLL(struct drm_device * dev, int addr) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -176,20 +133,36 @@ static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) */ /* Load the microcode for the CCE */ -static void r128_cce_load_microcode(drm_r128_private_t * dev_priv) +static int +r128_cce_load_microcode(struct drm_device *dev, drm_r128_private_t *dev_priv) { - int i; + const struct firmware *fw; + const __le32 *microcode; + int rc, i; # DRM_DEBUG("\n"); + rc = request_firmware(&fw, "r128/cce_ucode.bin", &dev->pdev->dev); + if (rc) + return rc; + if (fw->size != 256 * 8) { + release_firmware(fw); + return -EINVAL; + } + microcode = (const __le32 *)fw->data; + r128_do_wait_for_idle(dev_priv); R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); for (i = 0; i < 256; i++) { - R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]); + R128_WRITE(R128_PM4_MICROCODE_DATAH, + le32_to_cpu(microcode[i * 2])); R128_WRITE(R128_PM4_MICROCODE_DATAL, - r128_cce_microcode[i * 2 + 1]); + le32_to_cpu(microcode[i * 2 + 1])); } + + release_firmware(fw); + return 0; } /* Flush any pending commands to the CCE. This should only be used just @@ -350,6 +323,7 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev, static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) { drm_r128_private_t *dev_priv; + int rc; DRM_DEBUG("\n"); @@ -576,13 +550,18 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) #endif r128_cce_init_ring_buffer(dev, dev_priv); - r128_cce_load_microcode(dev_priv); + rc = r128_cce_load_microcode(dev, dev_priv); dev->dev_private = (void *)dev_priv; r128_do_engine_reset(dev); - return 0; + if (rc) { + DRM_ERROR("failed to load microcode\n"); + r128_do_cleanup_cce(dev); + } + + return rc; } int r128_do_cleanup_cce(struct drm_device * dev) diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index 6108e75..cb080f8 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c @@ -101,3 +101,4 @@ module_exit(r128_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL and additional rights"); +MODULE_FIRMWARE("r128/cce_ucode.bin"); --- END ---
signature.asc
Description: This is a digitally signed message part