Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus
[safe/jmp/linux-2.6] / drivers / gpu / drm / radeon / radeon_cp.c
index 77a7a4d..2f042a3 100644 (file)
 #include "radeon_drv.h"
 #include "r300_reg.h"
 
-#include "radeon_microcode.h"
-
 #define RADEON_FIFO_DEBUG      0
 
+/* Firmware Names */
+#define FIRMWARE_R100          "radeon/R100_cp.bin"
+#define FIRMWARE_R200          "radeon/R200_cp.bin"
+#define FIRMWARE_R300          "radeon/R300_cp.bin"
+#define FIRMWARE_R420          "radeon/R420_cp.bin"
+#define FIRMWARE_RS690         "radeon/RS690_cp.bin"
+#define FIRMWARE_RS600         "radeon/RS600_cp.bin"
+#define FIRMWARE_R520          "radeon/R520_cp.bin"
+
+MODULE_FIRMWARE(FIRMWARE_R100);
+MODULE_FIRMWARE(FIRMWARE_R200);
+MODULE_FIRMWARE(FIRMWARE_R300);
+MODULE_FIRMWARE(FIRMWARE_R420);
+MODULE_FIRMWARE(FIRMWARE_RS690);
+MODULE_FIRMWARE(FIRMWARE_RS600);
+MODULE_FIRMWARE(FIRMWARE_R520);
+
 static int radeon_do_cleanup_cp(struct drm_device * dev);
 static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
 
@@ -402,21 +417,37 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
        return -EBUSY;
 }
 
-static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
+static void radeon_init_pipes(struct drm_device *dev)
 {
+       drm_radeon_private_t *dev_priv = dev->dev_private;
        uint32_t gb_tile_config, gb_pipe_sel = 0;
 
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
+               uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2);
+               if ((z_pipe_sel & 3) == 3)
+                       dev_priv->num_z_pipes = 2;
+               else
+                       dev_priv->num_z_pipes = 1;
+       } else
+               dev_priv->num_z_pipes = 1;
+
        /* RS4xx/RS6xx/R4xx/R5xx */
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
                gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
                dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+               /* SE cards have 1 pipe */
+               if ((dev->pdev->device == 0x5e4c) ||
+                   (dev->pdev->device == 0x5e4f))
+                       dev_priv->num_gb_pipes = 1;
        } else {
                /* R3xx */
-               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
-                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
+                    dev->pdev->device != 0x4144) ||
+                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 &&
+                    dev->pdev->device != 0x4148)) {
                        dev_priv->num_gb_pipes = 2;
                } else {
-                       /* R3Vxx */
+                       /* RV3xx/R300 AD/R350 AH */
                        dev_priv->num_gb_pipes = 1;
                }
        }
@@ -451,37 +482,34 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
  */
 
 /* Load the microcode for the CP */
-static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
+static int radeon_cp_init_microcode(drm_radeon_private_t *dev_priv)
 {
-       int i;
+       struct platform_device *pdev;
+       const char *fw_name = NULL;
+       int err;
+
        DRM_DEBUG("\n");
 
-       radeon_do_wait_for_idle(dev_priv);
+       pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
+       err = IS_ERR(pdev);
+       if (err) {
+               printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
+               return -EINVAL;
+       }
 
-       RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
        if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) ||
            ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) ||
            ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) ||
            ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) ||
            ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) {
                DRM_INFO("Loading R100 Microcode\n");
-               for (i = 0; i < 256; i++) {
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    R100_cp_microcode[i][1]);
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    R100_cp_microcode[i][0]);
-               }
+               fw_name = FIRMWARE_R100;
        } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) {
                DRM_INFO("Loading R200 Microcode\n");
-               for (i = 0; i < 256; i++) {
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    R200_cp_microcode[i][1]);
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    R200_cp_microcode[i][0]);
-               }
+               fw_name = FIRMWARE_R200;
        } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
@@ -489,39 +517,19 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
                DRM_INFO("Loading R300 Microcode\n");
-               for (i = 0; i < 256; i++) {
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    R300_cp_microcode[i][1]);
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    R300_cp_microcode[i][0]);
-               }
+               fw_name = FIRMWARE_R300;
        } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) {
                DRM_INFO("Loading R400 Microcode\n");
-               for (i = 0; i < 256; i++) {
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    R420_cp_microcode[i][1]);
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    R420_cp_microcode[i][0]);
-               }
+               fw_name = FIRMWARE_R420;
        } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
                DRM_INFO("Loading RS690/RS740 Microcode\n");
-               for (i = 0; i < 256; i++) {
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    RS690_cp_microcode[i][1]);
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    RS690_cp_microcode[i][0]);
-               }
+               fw_name = FIRMWARE_RS690;
        } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
                DRM_INFO("Loading RS600 Microcode\n");
-               for (i = 0; i < 256; i++) {
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    RS600_cp_microcode[i][1]);
-                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    RS600_cp_microcode[i][0]);
-               }
+               fw_name = FIRMWARE_RS600;
        } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
@@ -529,11 +537,41 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) ||
                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) {
                DRM_INFO("Loading R500 Microcode\n");
-               for (i = 0; i < 256; i++) {
+               fw_name = FIRMWARE_R520;
+       }
+
+       err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev);
+       platform_device_unregister(pdev);
+       if (err) {
+               printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
+                      fw_name);
+       } else if (dev_priv->me_fw->size % 8) {
+               printk(KERN_ERR
+                      "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
+                      dev_priv->me_fw->size, fw_name);
+               err = -EINVAL;
+               release_firmware(dev_priv->me_fw);
+               dev_priv->me_fw = NULL;
+       }
+       return err;
+}
+
+static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+       const __be32 *fw_data;
+       int i, size;
+
+       radeon_do_wait_for_idle(dev_priv);
+
+       if (dev_priv->me_fw) {
+               size = dev_priv->me_fw->size / 4;
+               fw_data = (const __be32 *)&dev_priv->me_fw->data[0];
+               RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
+               for (i = 0; i < size; i += 2) {
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    R520_cp_microcode[i][1]);
+                                    be32_to_cpup(&fw_data[i]));
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    R520_cp_microcode[i][0]);
+                                    be32_to_cpup(&fw_data[i + 1]));
                }
        }
 }
@@ -585,6 +623,18 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
 
        dev_priv->cp_running = 1;
 
+       /* on r420, any DMA from CP to system memory while 2D is active
+        * can cause a hang.  workaround is to queue a CP RESYNC token
+        */
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
+               BEGIN_RING(3);
+               OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
+               OUT_RING(5); /* scratch reg 5 */
+               OUT_RING(0xdeadbeef);
+               ADVANCE_RING();
+               COMMIT_RING();
+       }
+
        BEGIN_RING(8);
        /* isync can only be written through cp on r5xx write it here */
        OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
@@ -622,8 +672,19 @@ static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
  */
 static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
 {
+       RING_LOCALS;
        DRM_DEBUG("\n");
 
+       /* finish the pending CP_RESYNC token */
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
+               BEGIN_RING(2);
+               OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+               OUT_RING(R300_RB3D_DC_FINISH);
+               ADVANCE_RING();
+               COMMIT_RING();
+               radeon_do_wait_for_idle(dev_priv);
+       }
+
        RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
 
        dev_priv->cp_running = 0;
@@ -682,7 +743,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)
 
        /* setup the raster pipes */
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
-           radeon_init_pipes(dev_priv);
+           radeon_init_pipes(dev);
 
        /* Reset the CP ring */
        radeon_do_cp_reset(dev_priv);
@@ -1486,6 +1547,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
                radeon_set_pcigart(dev_priv, 1);
        }
 
+       if (!dev_priv->me_fw) {
+               int err = radeon_cp_init_microcode(dev_priv);
+               if (err) {
+                       DRM_ERROR("Failed to load firmware!\n");
+                       radeon_do_cleanup_cp(dev);
+                       return err;
+               }
+       }
        radeon_cp_load_microcode(dev_priv);
        radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
 
@@ -1582,6 +1651,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri
        radeon_cp_load_microcode(dev_priv);
        radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
 
+       dev_priv->have_z_offset = 0;
        radeon_do_engine_reset(dev);
        radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
 
@@ -1755,6 +1825,14 @@ void radeon_do_release(struct drm_device * dev)
                        r600_do_cleanup_cp(dev);
                else
                        radeon_do_cleanup_cp(dev);
+               if (dev_priv->me_fw) {
+                       release_firmware(dev_priv->me_fw);
+                       dev_priv->me_fw = NULL;
+               }
+               if (dev_priv->pfp_fw) {
+                       release_firmware(dev_priv->pfp_fw);
+                       dev_priv->pfp_fw = NULL;
+               }
        }
 }
 
@@ -1871,8 +1949,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
        for (t = 0; t < dev_priv->usec_timeout; t++) {
                u32 done_age = GET_SCRATCH(dev_priv, 1);
                DRM_DEBUG("done_age = %d\n", done_age);
-               for (i = start; i < dma->buf_count; i++) {
-                       buf = dma->buflist[i];
+               for (i = 0; i < dma->buf_count; i++) {
+                       buf = dma->buflist[start];
                        buf_priv = buf->dev_private;
                        if (buf->file_priv == NULL || (buf->pending &&
                                                       buf_priv->age <=
@@ -1881,7 +1959,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
                                buf->pending = 0;
                                return buf;
                        }
-                       start = 0;
+                       if (++start >= dma->buf_count)
+                               start = 0;
                }
 
                if (t) {
@@ -1890,47 +1969,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
                }
        }
 
-       DRM_DEBUG("returning NULL!\n");
        return NULL;
 }
 
-#if 0
-struct drm_buf *radeon_freelist_get(struct drm_device * dev)
-{
-       struct drm_device_dma *dma = dev->dma;
-       drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_buf_priv_t *buf_priv;
-       struct drm_buf *buf;
-       int i, t;
-       int start;
-       u32 done_age;
-
-       done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
-       if (++dev_priv->last_buf >= dma->buf_count)
-               dev_priv->last_buf = 0;
-
-       start = dev_priv->last_buf;
-       dev_priv->stats.freelist_loops++;
-
-       for (t = 0; t < 2; t++) {
-               for (i = start; i < dma->buf_count; i++) {
-                       buf = dma->buflist[i];
-                       buf_priv = buf->dev_private;
-                       if (buf->file_priv == 0 || (buf->pending &&
-                                                   buf_priv->age <=
-                                                   done_age)) {
-                               dev_priv->stats.requested_bufs++;
-                               buf->pending = 0;
-                               return buf;
-                       }
-               }
-               start = 0;
-       }
-
-       return NULL;
-}
-#endif
-
 void radeon_freelist_reset(struct drm_device * dev)
 {
        struct drm_device_dma *dma = dev->dma;
@@ -2045,11 +2086,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
        drm_radeon_private_t *dev_priv;
        int ret = 0;
 
-       dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
+       dev_priv = kzalloc(sizeof(drm_radeon_private_t), GFP_KERNEL);
        if (dev_priv == NULL)
                return -ENOMEM;
 
-       memset(dev_priv, 0, sizeof(drm_radeon_private_t));
        dev->dev_private = (void *)dev_priv;
        dev_priv->flags = flags;
 
@@ -2103,16 +2143,17 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master)
        unsigned long sareapage;
        int ret;
 
-       master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER);
+       master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL);
        if (!master_priv)
                return -ENOMEM;
 
        /* prebuild the SAREA */
        sareapage = max_t(unsigned long, SAREA_MAX, PAGE_SIZE);
-       ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER,
+       ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK,
                         &master_priv->sarea);
        if (ret) {
                DRM_ERROR("SAREA setup failed\n");
+               kfree(master_priv);
                return ret;
        }
        master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea);
@@ -2137,7 +2178,7 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master)
        if (master_priv->sarea)
                drm_rmmap_locked(dev, master_priv->sarea);
 
-       drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER);
+       kfree(master_priv);
 
        master->driver_priv = NULL;
 }
@@ -2171,7 +2212,7 @@ int radeon_driver_unload(struct drm_device *dev)
 
        drm_rmmap(dev, dev_priv->mmio);
 
-       drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+       kfree(dev_priv);
 
        dev->dev_private = NULL;
        return 0;
@@ -2185,9 +2226,9 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv)
 
        /* check if the ring is padded out to 16-dword alignment */
 
-       tail_aligned = dev_priv->ring.tail & 0xf;
+       tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN-1);
        if (tail_aligned) {
-               int num_p2 = 16 - tail_aligned;
+               int num_p2 = RADEON_RING_ALIGN - tail_aligned;
 
                ring = dev_priv->ring.start;
                /* pad with some CP_PACKET2 */