aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/Kconfig1
-rw-r--r--drivers/gpu/drm/r128/r128_cce.c98
2 files changed, 49 insertions, 50 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 10edc9b0022f..a07abb818f5c 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -36,6 +36,7 @@ config DRM_TDFX
36config DRM_R128 36config DRM_R128
37 tristate "ATI Rage 128" 37 tristate "ATI Rage 128"
38 depends on DRM && PCI 38 depends on DRM && PCI
39 select FW_LOADER
39 help 40 help
40 Choose this option if you have an ATI Rage 128 graphics card. If M 41 Choose this option if you have an ATI Rage 128 graphics card. If M
41 is selected, the module will be called r128. AGP support for 42 is selected, the module will be called r128. AGP support for
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index c75fd3564040..15252f60bbd3 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -29,6 +29,9 @@
29 * Gareth Hughes <gareth@valinux.com> 29 * Gareth Hughes <gareth@valinux.com>
30 */ 30 */
31 31
32#include <linux/firmware.h>
33#include <linux/platform_device.h>
34
32#include "drmP.h" 35#include "drmP.h"
33#include "drm.h" 36#include "drm.h"
34#include "r128_drm.h" 37#include "r128_drm.h"
@@ -36,50 +39,9 @@
36 39
37#define R128_FIFO_DEBUG 0 40#define R128_FIFO_DEBUG 0
38 41
39/* CCE microcode (from ATI) */ 42#define FIRMWARE_NAME "r128/r128_cce.bin"
40static u32 r128_cce_microcode[] = { 43
41 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 44MODULE_FIRMWARE(FIRMWARE_NAME);
42 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0,
43 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1,
44 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11,
45 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28,
46 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9,
47 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656,
48 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1,
49 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071,
50 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2,
51 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1,
52 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
53 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1,
54 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2,
55 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1,
56 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82,
57 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729,
58 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008,
59 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
60 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1,
61 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1,
62 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0,
63 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370,
64 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1,
65 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793,
66 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
67 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1,
68 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1,
69 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1,
70 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894,
71 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14,
72 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1,
73 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1,
74 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1,
75 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
82};
83 45
84static int R128_READ_PLL(struct drm_device * dev, int addr) 46static int R128_READ_PLL(struct drm_device * dev, int addr)
85{ 47{
@@ -176,20 +138,50 @@ static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv)
176 */ 138 */
177 139
178/* Load the microcode for the CCE */ 140/* Load the microcode for the CCE */
179static void r128_cce_load_microcode(drm_r128_private_t * dev_priv) 141static int r128_cce_load_microcode(drm_r128_private_t *dev_priv)
180{ 142{
181 int i; 143 struct platform_device *pdev;
144 const struct firmware *fw;
145 const __be32 *fw_data;
146 int rc, i;
182 147
183 DRM_DEBUG("\n"); 148 DRM_DEBUG("\n");
184 149
150 pdev = platform_device_register_simple("r128_cce", 0, NULL, 0);
151 if (IS_ERR(pdev)) {
152 printk(KERN_ERR "r128_cce: Failed to register firmware\n");
153 return PTR_ERR(pdev);
154 }
155 rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev);
156 platform_device_unregister(pdev);
157 if (rc) {
158 printk(KERN_ERR "r128_cce: Failed to load firmware \"%s\"\n",
159 FIRMWARE_NAME);
160 return rc;
161 }
162
163 if (fw->size != 256 * 8) {
164 printk(KERN_ERR
165 "r128_cce: Bogus length %zu in firmware \"%s\"\n",
166 fw->size, FIRMWARE_NAME);
167 rc = -EINVAL;
168 goto out_release;
169 }
170
185 r128_do_wait_for_idle(dev_priv); 171 r128_do_wait_for_idle(dev_priv);
186 172
173 fw_data = (const __be32 *)fw->data;
187 R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); 174 R128_WRITE(R128_PM4_MICROCODE_ADDR, 0);
188 for (i = 0; i < 256; i++) { 175 for (i = 0; i < 256; i++) {
189 R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]); 176 R128_WRITE(R128_PM4_MICROCODE_DATAH,
177 be32_to_cpup(&fw_data[i * 2]));
190 R128_WRITE(R128_PM4_MICROCODE_DATAL, 178 R128_WRITE(R128_PM4_MICROCODE_DATAL,
191 r128_cce_microcode[i * 2 + 1]); 179 be32_to_cpup(&fw_data[i * 2 + 1]));
192 } 180 }
181
182out_release:
183 release_firmware(fw);
184 return rc;
193} 185}
194 186
195/* Flush any pending commands to the CCE. This should only be used just 187/* Flush any pending commands to the CCE. This should only be used just
@@ -350,6 +342,7 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev,
350static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) 342static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
351{ 343{
352 drm_r128_private_t *dev_priv; 344 drm_r128_private_t *dev_priv;
345 int rc;
353 346
354 DRM_DEBUG("\n"); 347 DRM_DEBUG("\n");
355 348
@@ -575,13 +568,18 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
575#endif 568#endif
576 569
577 r128_cce_init_ring_buffer(dev, dev_priv); 570 r128_cce_init_ring_buffer(dev, dev_priv);
578 r128_cce_load_microcode(dev_priv); 571 rc = r128_cce_load_microcode(dev_priv);
579 572
580 dev->dev_private = (void *)dev_priv; 573 dev->dev_private = (void *)dev_priv;
581 574
582 r128_do_engine_reset(dev); 575 r128_do_engine_reset(dev);
583 576
584 return 0; 577 if (rc) {
578 DRM_ERROR("Failed to load firmware!\n");
579 r128_do_cleanup_cce(dev);
580 }
581
582 return rc;
585} 583}
586 584
587int r128_do_cleanup_cce(struct drm_device * dev) 585int r128_do_cleanup_cce(struct drm_device * dev)