]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/char/drm/radeon_cp.c
radeon: setup the ring buffer fetcher to be less agressive.
[net-next-2.6.git] / drivers / char / drm / radeon_cp.c
index af5790f8fd53a2631478c77d0aa433de65c66995..020323bd16260387ce9f58741025beed18f50d7e 100644 (file)
@@ -889,7 +889,7 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
        DRM_ERROR("failed!\n");
        radeon_status(dev_priv);
 #endif
-       return DRM_ERR(EBUSY);
+       return -EBUSY;
 }
 
 static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
@@ -910,7 +910,7 @@ static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
        DRM_ERROR("failed!\n");
        radeon_status(dev_priv);
 #endif
-       return DRM_ERR(EBUSY);
+       return -EBUSY;
 }
 
 static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
@@ -936,7 +936,7 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
        DRM_ERROR("failed!\n");
        radeon_status(dev_priv);
 #endif
-       return DRM_ERR(EBUSY);
+       return -EBUSY;
 }
 
 /* ================================================================
@@ -1127,7 +1127,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
 {
        u32 ring_start, cur_read_ptr;
        u32 tmp;
-       
+
        /* Initialize the memory controller. With new memory map, the fb location
         * is not changed, it should have been properly initialized already. Part
         * of the problem is that the code below is bogus, assuming the GART is
@@ -1190,9 +1190,15 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
        /* Set ring buffer size */
 #ifdef __BIG_ENDIAN
        RADEON_WRITE(RADEON_CP_RB_CNTL,
-                    dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
+                    RADEON_BUF_SWAP_32BIT |
+                    (dev_priv->ring.fetch_size_l2ow << 18) |
+                    (dev_priv->ring.rptr_update_l2qw << 8) |
+                    dev_priv->ring.size_l2qw);
 #else
-       RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
+       RADEON_WRITE(RADEON_CP_RB_CNTL,
+                    (dev_priv->ring.fetch_size_l2ow << 18) |
+                    (dev_priv->ring.rptr_update_l2qw << 8) |
+                    dev_priv->ring.size_l2qw);
 #endif
 
        /* Start with assuming that writeback doesn't work */
@@ -1358,7 +1364,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
                return;
        }
 
-       tmp = RADEON_READ(RADEON_AIC_CNTL);
+       tmp = RADEON_READ(RADEON_AIC_CNTL);
 
        if (on) {
                RADEON_WRITE(RADEON_AIC_CNTL,
@@ -1394,7 +1400,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
        if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
                DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
        if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) {
@@ -1409,7 +1415,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
        if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) {
                DRM_ERROR("PCI GART memory not allocated!\n");
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
        dev_priv->usec_timeout = init->usec_timeout;
@@ -1417,7 +1423,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
            dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
                DRM_DEBUG("TIMEOUT problem!\n");
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
        /* Enable vblank on CRTC1 for older X servers
@@ -1446,7 +1452,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
            (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
                DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
        switch (init->fb_bpp) {
@@ -1515,27 +1521,27 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
        if (!dev_priv->sarea) {
                DRM_ERROR("could not find sarea!\n");
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
        dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
        if (!dev_priv->cp_ring) {
                DRM_ERROR("could not find cp ring region!\n");
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
        dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
        if (!dev_priv->ring_rptr) {
                DRM_ERROR("could not find ring read pointer!\n");
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
        dev->agp_buffer_token = init->buffers_offset;
        dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
        if (!dev->agp_buffer_map) {
                DRM_ERROR("could not find dma buffer region!\n");
                radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
        if (init->gart_textures_offset) {
@@ -1544,7 +1550,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
                if (!dev_priv->gart_textures) {
                        DRM_ERROR("could not find GART texture region!\n");
                        radeon_do_cleanup_cp(dev);
-                       return DRM_ERR(EINVAL);
+                       return -EINVAL;
                }
        }
 
@@ -1562,7 +1568,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
                    !dev->agp_buffer_map->handle) {
                        DRM_ERROR("could not find ioremap agp regions!\n");
                        radeon_do_cleanup_cp(dev);
-                       return DRM_ERR(EINVAL);
+                       return -EINVAL;
                }
        } else
 #endif
@@ -1583,7 +1589,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
 
        dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
                                 & 0xffff) << 16;
-       dev_priv->fb_size = 
+       dev_priv->fb_size =
                ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000)
                - dev_priv->fb_location;
 
@@ -1630,7 +1636,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
                            ((base + dev_priv->gart_size) & 0xfffffffful) < base)
                                base = dev_priv->fb_location
                                        - dev_priv->gart_size;
-               }               
+               }
                dev_priv->gart_vm_start = base & 0xffc00000u;
                if (dev_priv->gart_vm_start != base)
                        DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
@@ -1663,6 +1669,11 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
        dev_priv->ring.size = init->ring_size;
        dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
 
+       dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
+       dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8);
+
+       dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
+       dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16);
        dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
 
        dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
@@ -1679,7 +1690,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
                        dev_priv->gart_info.bus_addr =
                            dev_priv->pcigart_offset + dev_priv->fb_location;
                        dev_priv->gart_info.mapping.offset =
-                           dev_priv->gart_info.bus_addr;
+                           dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
                        dev_priv->gart_info.mapping.size =
                            dev_priv->gart_info.table_size;
 
@@ -1710,14 +1721,14 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
                                DRM_ERROR
                                    ("Cannot use PCI Express without GART in FB memory\n");
                                radeon_do_cleanup_cp(dev);
-                               return DRM_ERR(EINVAL);
+                               return -EINVAL;
                        }
                }
 
                if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
                        DRM_ERROR("failed to init PCI GART!\n");
                        radeon_do_cleanup_cp(dev);
-                       return DRM_ERR(ENOMEM);
+                       return -ENOMEM;
                }
 
                /* Turn on PCI GART */
@@ -1797,7 +1808,7 @@ static int radeon_do_resume_cp(struct drm_device * dev)
 
        if (!dev_priv) {
                DRM_ERROR("Called with no initialization\n");
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
 
        DRM_DEBUG("Starting radeon_do_resume_cp()\n");
@@ -1823,46 +1834,41 @@ static int radeon_do_resume_cp(struct drm_device * dev)
        return 0;
 }
 
-int radeon_cp_init(DRM_IOCTL_ARGS)
+int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
-       drm_radeon_init_t init;
+       drm_radeon_init_t *init = data;
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-       DRM_COPY_FROM_USER_IOCTL(init, (drm_radeon_init_t __user *) data,
-                                sizeof(init));
-
-       if (init.func == RADEON_INIT_R300_CP)
+       if (init->func == RADEON_INIT_R300_CP)
                r300_init_reg_flags();
 
-       switch (init.func) {
+       switch (init->func) {
        case RADEON_INIT_CP:
        case RADEON_INIT_R200_CP:
        case RADEON_INIT_R300_CP:
-               return radeon_do_init_cp(dev, &init);
+               return radeon_do_init_cp(dev, init);
        case RADEON_CLEANUP_CP:
                return radeon_do_cleanup_cp(dev);
        }
 
-       return DRM_ERR(EINVAL);
+       return -EINVAL;
 }
 
-int radeon_cp_start(DRM_IOCTL_ARGS)
+int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        drm_radeon_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG("\n");
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        if (dev_priv->cp_running) {
-               DRM_DEBUG("%s while CP running\n", __FUNCTION__);
+               DRM_DEBUG("while CP running\n");
                return 0;
        }
        if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
-               DRM_DEBUG("%s called with bogus CP mode (%d)\n",
-                         __FUNCTION__, dev_priv->cp_mode);
+               DRM_DEBUG("called with bogus CP mode (%d)\n",
+                         dev_priv->cp_mode);
                return 0;
        }
 
@@ -1874,18 +1880,14 @@ int radeon_cp_start(DRM_IOCTL_ARGS)
 /* Stop the CP.  The engine must have been idled before calling this
  * routine.
  */
-int radeon_cp_stop(DRM_IOCTL_ARGS)
+int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_cp_stop_t stop;
+       drm_radeon_cp_stop_t *stop = data;
        int ret;
        DRM_DEBUG("\n");
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
-
-       DRM_COPY_FROM_USER_IOCTL(stop, (drm_radeon_cp_stop_t __user *) data,
-                                sizeof(stop));
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        if (!dev_priv->cp_running)
                return 0;
@@ -1893,14 +1895,14 @@ int radeon_cp_stop(DRM_IOCTL_ARGS)
        /* Flush any pending CP commands.  This ensures any outstanding
         * commands are exectuted by the engine before we turn it off.
         */
-       if (stop.flush) {
+       if (stop->flush) {
                radeon_do_cp_flush(dev_priv);
        }
 
        /* If we fail to make the engine go idle, we return an error
         * code so that the DRM ioctl wrapper can try again.
         */
-       if (stop.idle) {
+       if (stop->idle) {
                ret = radeon_do_cp_idle(dev_priv);
                if (ret)
                        return ret;
@@ -1963,17 +1965,16 @@ void radeon_do_release(struct drm_device * dev)
 
 /* Just reset the CP ring.  Called as part of an X Server engine reset.
  */
-int radeon_cp_reset(DRM_IOCTL_ARGS)
+int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        drm_radeon_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG("\n");
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        if (!dev_priv) {
-               DRM_DEBUG("%s called before init done\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               DRM_DEBUG("called before init done\n");
+               return -EINVAL;
        }
 
        radeon_do_cp_reset(dev_priv);
@@ -1984,32 +1985,29 @@ int radeon_cp_reset(DRM_IOCTL_ARGS)
        return 0;
 }
 
-int radeon_cp_idle(DRM_IOCTL_ARGS)
+int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        drm_radeon_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG("\n");
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        return radeon_do_cp_idle(dev_priv);
 }
 
 /* Added by Charl P. Botha to call radeon_do_resume_cp().
  */
-int radeon_cp_resume(DRM_IOCTL_ARGS)
+int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
 
        return radeon_do_resume_cp(dev);
 }
 
-int radeon_engine_reset(DRM_IOCTL_ARGS)
+int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        DRM_DEBUG("\n");
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        return radeon_do_engine_reset(dev);
 }
@@ -2020,7 +2018,7 @@ int radeon_engine_reset(DRM_IOCTL_ARGS)
 
 /* KW: Deprecated to say the least:
  */
-int radeon_fullscreen(DRM_IOCTL_ARGS)
+int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        return 0;
 }
@@ -2066,8 +2064,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
                for (i = start; i < dma->buf_count; i++) {
                        buf = dma->buflist[i];
                        buf_priv = buf->dev_private;
-                       if (buf->filp == 0 || (buf->pending &&
-                                              buf_priv->age <= done_age)) {
+                       if (buf->file_priv == NULL || (buf->pending &&
+                                                      buf_priv->age <=
+                                                      done_age)) {
                                dev_priv->stats.requested_bufs++;
                                buf->pending = 0;
                                return buf;
@@ -2106,8 +2105,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
                for (i = start; i < dma->buf_count; i++) {
                        buf = dma->buflist[i];
                        buf_priv = buf->dev_private;
-                       if (buf->filp == 0 || (buf->pending &&
-                                              buf_priv->age <= done_age)) {
+                       if (buf->file_priv == 0 || (buf->pending &&
+                                                   buf_priv->age <=
+                                                   done_age)) {
                                dev_priv->stats.requested_bufs++;
                                buf->pending = 0;
                                return buf;
@@ -2167,10 +2167,11 @@ int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n)
        radeon_status(dev_priv);
        DRM_ERROR("failed!\n");
 #endif
-       return DRM_ERR(EBUSY);
+       return -EBUSY;
 }
 
-static int radeon_cp_get_buffers(DRMFILE filp, struct drm_device * dev,
+static int radeon_cp_get_buffers(struct drm_device *dev,
+                                struct drm_file *file_priv,
                                 struct drm_dma * d)
 {
        int i;
@@ -2179,58 +2180,52 @@ static int radeon_cp_get_buffers(DRMFILE filp, struct drm_device * dev,
        for (i = d->granted_count; i < d->request_count; i++) {
                buf = radeon_freelist_get(dev);
                if (!buf)
-                       return DRM_ERR(EBUSY);  /* NOTE: broken client */
+                       return -EBUSY;  /* NOTE: broken client */
 
-               buf->filp = filp;
+               buf->file_priv = file_priv;
 
                if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
                                     sizeof(buf->idx)))
-                       return DRM_ERR(EFAULT);
+                       return -EFAULT;
                if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
                                     sizeof(buf->total)))
-                       return DRM_ERR(EFAULT);
+                       return -EFAULT;
 
                d->granted_count++;
        }
        return 0;
 }
 
-int radeon_cp_buffers(DRM_IOCTL_ARGS)
+int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-       DRM_DEVICE;
        struct drm_device_dma *dma = dev->dma;
        int ret = 0;
-       struct drm_dma __user *argp = (void __user *)data;
-       struct drm_dma d;
+       struct drm_dma *d = data;
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
-
-       DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        /* Please don't send us buffers.
         */
-       if (d.send_count != 0) {
+       if (d->send_count != 0) {
                DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
-                         DRM_CURRENTPID, d.send_count);
-               return DRM_ERR(EINVAL);
+                         DRM_CURRENTPID, d->send_count);
+               return -EINVAL;
        }
 
        /* We'll send you buffers.
         */
-       if (d.request_count < 0 || d.request_count > dma->buf_count) {
+       if (d->request_count < 0 || d->request_count > dma->buf_count) {
                DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
-                         DRM_CURRENTPID, d.request_count, dma->buf_count);
-               return DRM_ERR(EINVAL);
+                         DRM_CURRENTPID, d->request_count, dma->buf_count);
+               return -EINVAL;
        }
 
-       d.granted_count = 0;
+       d->granted_count = 0;
 
-       if (d.request_count) {
-               ret = radeon_cp_get_buffers(filp, dev, &d);
+       if (d->request_count) {
+               ret = radeon_cp_get_buffers(dev, file_priv, d);
        }
 
-       DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
-
        return ret;
 }
 
@@ -2241,7 +2236,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
 
        dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
        if (dev_priv == NULL)
-               return DRM_ERR(ENOMEM);
+               return -ENOMEM;
 
        memset(dev_priv, 0, sizeof(drm_radeon_private_t));
        dev->dev_private = (void *)dev_priv;
@@ -2291,7 +2286,8 @@ int radeon_driver_firstopen(struct drm_device *dev)
        if (ret != 0)
                return ret;
 
-       ret = drm_addmap(dev, drm_get_resource_start(dev, 0),
+       dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
+       ret = drm_addmap(dev, dev_priv->fb_aper_offset,
                         drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
                         _DRM_WRITE_COMBINING, &map);
        if (ret != 0)