11.2Sriastrad/* $NetBSD: r128_cce.c,v 1.3 2021/12/18 23:45:42 riastradh Exp $ */ 21.2Sriastrad 31.1Sriastrad/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- 41.1Sriastrad * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com 51.1Sriastrad */ 61.1Sriastrad/* 71.1Sriastrad * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 81.1Sriastrad * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 91.1Sriastrad * All Rights Reserved. 101.1Sriastrad * 111.1Sriastrad * Permission is hereby granted, free of charge, to any person obtaining a 121.1Sriastrad * copy of this software and associated documentation files (the "Software"), 131.1Sriastrad * to deal in the Software without restriction, including without limitation 141.1Sriastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 151.1Sriastrad * and/or sell copies of the Software, and to permit persons to whom the 161.1Sriastrad * Software is furnished to do so, subject to the following conditions: 171.1Sriastrad * 181.1Sriastrad * The above copyright notice and this permission notice (including the next 191.1Sriastrad * paragraph) shall be included in all copies or substantial portions of the 201.1Sriastrad * Software. 211.1Sriastrad * 221.1Sriastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 231.1Sriastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 241.1Sriastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 251.1Sriastrad * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 261.1Sriastrad * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 271.1Sriastrad * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 281.1Sriastrad * DEALINGS IN THE SOFTWARE. 291.1Sriastrad * 301.1Sriastrad * Authors: 311.1Sriastrad * Gareth Hughes <gareth@valinux.com> 321.1Sriastrad */ 331.1Sriastrad 341.2Sriastrad#include <sys/cdefs.h> 351.2Sriastrad__KERNEL_RCSID(0, "$NetBSD: r128_cce.c,v 1.3 2021/12/18 23:45:42 riastradh Exp $"); 361.2Sriastrad 371.3Sriastrad#include <linux/delay.h> 381.3Sriastrad#include <linux/dma-mapping.h> 391.1Sriastrad#include <linux/firmware.h> 401.3Sriastrad#include <linux/module.h> 411.1Sriastrad#include <linux/platform_device.h> 421.1Sriastrad#include <linux/slab.h> 431.3Sriastrad#include <linux/uaccess.h> 441.1Sriastrad 451.3Sriastrad#include <drm/drm_agpsupport.h> 461.3Sriastrad#include <drm/drm_device.h> 471.3Sriastrad#include <drm/drm_file.h> 481.3Sriastrad#include <drm/drm_irq.h> 491.3Sriastrad#include <drm/drm_print.h> 501.1Sriastrad#include <drm/r128_drm.h> 511.3Sriastrad 521.1Sriastrad#include "r128_drv.h" 531.1Sriastrad 541.1Sriastrad#define R128_FIFO_DEBUG 0 551.1Sriastrad 561.1Sriastrad#define FIRMWARE_NAME "r128/r128_cce.bin" 571.1Sriastrad 581.1SriastradMODULE_FIRMWARE(FIRMWARE_NAME); 591.1Sriastrad 601.1Sriastradstatic int R128_READ_PLL(struct drm_device *dev, int addr) 611.1Sriastrad{ 621.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 631.1Sriastrad 641.1Sriastrad R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); 651.1Sriastrad return R128_READ(R128_CLOCK_CNTL_DATA); 661.1Sriastrad} 671.1Sriastrad 681.1Sriastrad#if R128_FIFO_DEBUG 691.1Sriastradstatic void r128_status(drm_r128_private_t *dev_priv) 701.1Sriastrad{ 711.1Sriastrad printk("GUI_STAT = 0x%08x\n", 721.1Sriastrad (unsigned int)R128_READ(R128_GUI_STAT)); 731.1Sriastrad printk("PM4_STAT = 0x%08x\n", 741.1Sriastrad (unsigned int)R128_READ(R128_PM4_STAT)); 751.1Sriastrad printk("PM4_BUFFER_DL_WPTR = 0x%08x\n", 761.1Sriastrad (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR)); 771.1Sriastrad printk("PM4_BUFFER_DL_RPTR = 0x%08x\n", 781.1Sriastrad (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR)); 791.1Sriastrad printk("PM4_MICRO_CNTL = 0x%08x\n", 801.1Sriastrad (unsigned int)R128_READ(R128_PM4_MICRO_CNTL)); 811.1Sriastrad printk("PM4_BUFFER_CNTL = 0x%08x\n", 821.1Sriastrad (unsigned int)R128_READ(R128_PM4_BUFFER_CNTL)); 831.1Sriastrad} 841.1Sriastrad#endif 851.1Sriastrad 861.1Sriastrad/* ================================================================ 871.1Sriastrad * Engine, FIFO control 881.1Sriastrad */ 891.1Sriastrad 901.1Sriastradstatic int r128_do_pixcache_flush(drm_r128_private_t *dev_priv) 911.1Sriastrad{ 921.1Sriastrad u32 tmp; 931.1Sriastrad int i; 941.1Sriastrad 951.1Sriastrad tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL; 961.1Sriastrad R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); 971.1Sriastrad 981.1Sriastrad for (i = 0; i < dev_priv->usec_timeout; i++) { 991.1Sriastrad if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) 1001.1Sriastrad return 0; 1011.3Sriastrad udelay(1); 1021.1Sriastrad } 1031.1Sriastrad 1041.1Sriastrad#if R128_FIFO_DEBUG 1051.1Sriastrad DRM_ERROR("failed!\n"); 1061.1Sriastrad#endif 1071.1Sriastrad return -EBUSY; 1081.1Sriastrad} 1091.1Sriastrad 1101.1Sriastradstatic int r128_do_wait_for_fifo(drm_r128_private_t *dev_priv, int entries) 1111.1Sriastrad{ 1121.1Sriastrad int i; 1131.1Sriastrad 1141.1Sriastrad for (i = 0; i < dev_priv->usec_timeout; i++) { 1151.1Sriastrad int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; 1161.1Sriastrad if (slots >= entries) 1171.1Sriastrad return 0; 1181.3Sriastrad udelay(1); 1191.1Sriastrad } 1201.1Sriastrad 1211.1Sriastrad#if R128_FIFO_DEBUG 1221.1Sriastrad DRM_ERROR("failed!\n"); 1231.1Sriastrad#endif 1241.1Sriastrad return -EBUSY; 1251.1Sriastrad} 1261.1Sriastrad 1271.1Sriastradstatic int r128_do_wait_for_idle(drm_r128_private_t *dev_priv) 1281.1Sriastrad{ 1291.1Sriastrad int i, ret; 1301.1Sriastrad 1311.1Sriastrad ret = r128_do_wait_for_fifo(dev_priv, 64); 1321.1Sriastrad if (ret) 1331.1Sriastrad return ret; 1341.1Sriastrad 1351.1Sriastrad for (i = 0; i < dev_priv->usec_timeout; i++) { 1361.1Sriastrad if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) { 1371.1Sriastrad r128_do_pixcache_flush(dev_priv); 1381.1Sriastrad return 0; 1391.1Sriastrad } 1401.3Sriastrad udelay(1); 1411.1Sriastrad } 1421.1Sriastrad 1431.1Sriastrad#if R128_FIFO_DEBUG 1441.1Sriastrad DRM_ERROR("failed!\n"); 1451.1Sriastrad#endif 1461.1Sriastrad return -EBUSY; 1471.1Sriastrad} 1481.1Sriastrad 1491.1Sriastrad/* ================================================================ 1501.1Sriastrad * CCE control, initialization 1511.1Sriastrad */ 1521.1Sriastrad 1531.1Sriastrad/* Load the microcode for the CCE */ 1541.1Sriastradstatic int r128_cce_load_microcode(drm_r128_private_t *dev_priv) 1551.1Sriastrad{ 1561.1Sriastrad struct platform_device *pdev; 1571.1Sriastrad const struct firmware *fw; 1581.1Sriastrad const __be32 *fw_data; 1591.1Sriastrad int rc, i; 1601.1Sriastrad 1611.1Sriastrad DRM_DEBUG("\n"); 1621.1Sriastrad 1631.1Sriastrad pdev = platform_device_register_simple("r128_cce", 0, NULL, 0); 1641.1Sriastrad if (IS_ERR(pdev)) { 1651.3Sriastrad pr_err("r128_cce: Failed to register firmware\n"); 1661.1Sriastrad return PTR_ERR(pdev); 1671.1Sriastrad } 1681.1Sriastrad rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev); 1691.1Sriastrad platform_device_unregister(pdev); 1701.1Sriastrad if (rc) { 1711.3Sriastrad pr_err("r128_cce: Failed to load firmware \"%s\"\n", 1721.1Sriastrad FIRMWARE_NAME); 1731.1Sriastrad return rc; 1741.1Sriastrad } 1751.1Sriastrad 1761.1Sriastrad if (fw->size != 256 * 8) { 1771.3Sriastrad pr_err("r128_cce: Bogus length %zu in firmware \"%s\"\n", 1781.1Sriastrad fw->size, FIRMWARE_NAME); 1791.1Sriastrad rc = -EINVAL; 1801.1Sriastrad goto out_release; 1811.1Sriastrad } 1821.1Sriastrad 1831.1Sriastrad r128_do_wait_for_idle(dev_priv); 1841.1Sriastrad 1851.1Sriastrad fw_data = (const __be32 *)fw->data; 1861.1Sriastrad R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); 1871.1Sriastrad for (i = 0; i < 256; i++) { 1881.1Sriastrad R128_WRITE(R128_PM4_MICROCODE_DATAH, 1891.1Sriastrad be32_to_cpup(&fw_data[i * 2])); 1901.1Sriastrad R128_WRITE(R128_PM4_MICROCODE_DATAL, 1911.1Sriastrad be32_to_cpup(&fw_data[i * 2 + 1])); 1921.1Sriastrad } 1931.1Sriastrad 1941.1Sriastradout_release: 1951.1Sriastrad release_firmware(fw); 1961.1Sriastrad return rc; 1971.1Sriastrad} 1981.1Sriastrad 1991.1Sriastrad/* Flush any pending commands to the CCE. This should only be used just 2001.1Sriastrad * prior to a wait for idle, as it informs the engine that the command 2011.1Sriastrad * stream is ending. 2021.1Sriastrad */ 2031.1Sriastradstatic void r128_do_cce_flush(drm_r128_private_t *dev_priv) 2041.1Sriastrad{ 2051.1Sriastrad u32 tmp; 2061.1Sriastrad 2071.1Sriastrad tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE; 2081.1Sriastrad R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp); 2091.1Sriastrad} 2101.1Sriastrad 2111.1Sriastrad/* Wait for the CCE to go idle. 2121.1Sriastrad */ 2131.1Sriastradint r128_do_cce_idle(drm_r128_private_t *dev_priv) 2141.1Sriastrad{ 2151.1Sriastrad int i; 2161.1Sriastrad 2171.1Sriastrad for (i = 0; i < dev_priv->usec_timeout; i++) { 2181.1Sriastrad if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) { 2191.1Sriastrad int pm4stat = R128_READ(R128_PM4_STAT); 2201.1Sriastrad if (((pm4stat & R128_PM4_FIFOCNT_MASK) >= 2211.1Sriastrad dev_priv->cce_fifo_size) && 2221.1Sriastrad !(pm4stat & (R128_PM4_BUSY | 2231.1Sriastrad R128_PM4_GUI_ACTIVE))) { 2241.1Sriastrad return r128_do_pixcache_flush(dev_priv); 2251.1Sriastrad } 2261.1Sriastrad } 2271.3Sriastrad udelay(1); 2281.1Sriastrad } 2291.1Sriastrad 2301.1Sriastrad#if R128_FIFO_DEBUG 2311.1Sriastrad DRM_ERROR("failed!\n"); 2321.1Sriastrad r128_status(dev_priv); 2331.1Sriastrad#endif 2341.1Sriastrad return -EBUSY; 2351.1Sriastrad} 2361.1Sriastrad 2371.1Sriastrad/* Start the Concurrent Command Engine. 2381.1Sriastrad */ 2391.1Sriastradstatic void r128_do_cce_start(drm_r128_private_t *dev_priv) 2401.1Sriastrad{ 2411.1Sriastrad r128_do_wait_for_idle(dev_priv); 2421.1Sriastrad 2431.1Sriastrad R128_WRITE(R128_PM4_BUFFER_CNTL, 2441.1Sriastrad dev_priv->cce_mode | dev_priv->ring.size_l2qw 2451.1Sriastrad | R128_PM4_BUFFER_CNTL_NOUPDATE); 2461.1Sriastrad R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */ 2471.1Sriastrad R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN); 2481.1Sriastrad 2491.1Sriastrad dev_priv->cce_running = 1; 2501.1Sriastrad} 2511.1Sriastrad 2521.1Sriastrad/* Reset the Concurrent Command Engine. This will not flush any pending 2531.1Sriastrad * commands, so you must wait for the CCE command stream to complete 2541.1Sriastrad * before calling this routine. 2551.1Sriastrad */ 2561.1Sriastradstatic void r128_do_cce_reset(drm_r128_private_t *dev_priv) 2571.1Sriastrad{ 2581.1Sriastrad R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); 2591.1Sriastrad R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); 2601.1Sriastrad dev_priv->ring.tail = 0; 2611.1Sriastrad} 2621.1Sriastrad 2631.1Sriastrad/* Stop the Concurrent Command Engine. This will not flush any pending 2641.1Sriastrad * commands, so you must flush the command stream and wait for the CCE 2651.1Sriastrad * to go idle before calling this routine. 2661.1Sriastrad */ 2671.1Sriastradstatic void r128_do_cce_stop(drm_r128_private_t *dev_priv) 2681.1Sriastrad{ 2691.1Sriastrad R128_WRITE(R128_PM4_MICRO_CNTL, 0); 2701.1Sriastrad R128_WRITE(R128_PM4_BUFFER_CNTL, 2711.1Sriastrad R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE); 2721.1Sriastrad 2731.1Sriastrad dev_priv->cce_running = 0; 2741.1Sriastrad} 2751.1Sriastrad 2761.1Sriastrad/* Reset the engine. This will stop the CCE if it is running. 2771.1Sriastrad */ 2781.1Sriastradstatic int r128_do_engine_reset(struct drm_device *dev) 2791.1Sriastrad{ 2801.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 2811.1Sriastrad u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; 2821.1Sriastrad 2831.1Sriastrad r128_do_pixcache_flush(dev_priv); 2841.1Sriastrad 2851.1Sriastrad clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX); 2861.1Sriastrad mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL); 2871.1Sriastrad 2881.1Sriastrad R128_WRITE_PLL(R128_MCLK_CNTL, 2891.1Sriastrad mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); 2901.1Sriastrad 2911.1Sriastrad gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL); 2921.1Sriastrad 2931.1Sriastrad /* Taken from the sample code - do not change */ 2941.1Sriastrad R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); 2951.1Sriastrad R128_READ(R128_GEN_RESET_CNTL); 2961.1Sriastrad R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); 2971.1Sriastrad R128_READ(R128_GEN_RESET_CNTL); 2981.1Sriastrad 2991.1Sriastrad R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl); 3001.1Sriastrad R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index); 3011.1Sriastrad R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl); 3021.1Sriastrad 3031.1Sriastrad /* Reset the CCE ring */ 3041.1Sriastrad r128_do_cce_reset(dev_priv); 3051.1Sriastrad 3061.1Sriastrad /* The CCE is no longer running after an engine reset */ 3071.1Sriastrad dev_priv->cce_running = 0; 3081.1Sriastrad 3091.1Sriastrad /* Reset any pending vertex, indirect buffers */ 3101.1Sriastrad r128_freelist_reset(dev); 3111.1Sriastrad 3121.1Sriastrad return 0; 3131.1Sriastrad} 3141.1Sriastrad 3151.1Sriastradstatic void r128_cce_init_ring_buffer(struct drm_device *dev, 3161.1Sriastrad drm_r128_private_t *dev_priv) 3171.1Sriastrad{ 3181.1Sriastrad u32 ring_start; 3191.1Sriastrad u32 tmp; 3201.1Sriastrad 3211.1Sriastrad DRM_DEBUG("\n"); 3221.1Sriastrad 3231.1Sriastrad /* The manual (p. 2) says this address is in "VM space". This 3241.1Sriastrad * means it's an offset from the start of AGP space. 3251.1Sriastrad */ 3261.2Sriastrad#if IS_ENABLED(CONFIG_AGP) 3271.1Sriastrad if (!dev_priv->is_pci) 3281.1Sriastrad ring_start = dev_priv->cce_ring->offset - dev->agp->base; 3291.1Sriastrad else 3301.1Sriastrad#endif 3311.1Sriastrad ring_start = dev_priv->cce_ring->offset - 3321.1Sriastrad (unsigned long)dev->sg->virtual; 3331.1Sriastrad 3341.1Sriastrad R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET); 3351.1Sriastrad 3361.1Sriastrad R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); 3371.1Sriastrad R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); 3381.1Sriastrad 3391.1Sriastrad /* Set watermark control */ 3401.1Sriastrad R128_WRITE(R128_PM4_BUFFER_WM_CNTL, 3411.1Sriastrad ((R128_WATERMARK_L / 4) << R128_WMA_SHIFT) 3421.1Sriastrad | ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT) 3431.1Sriastrad | ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT) 3441.1Sriastrad | ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT)); 3451.1Sriastrad 3461.1Sriastrad /* Force read. Why? Because it's in the examples... */ 3471.1Sriastrad R128_READ(R128_PM4_BUFFER_ADDR); 3481.1Sriastrad 3491.1Sriastrad /* Turn on bus mastering */ 3501.1Sriastrad tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS; 3511.1Sriastrad R128_WRITE(R128_BUS_CNTL, tmp); 3521.1Sriastrad} 3531.1Sriastrad 3541.1Sriastradstatic int r128_do_init_cce(struct drm_device *dev, drm_r128_init_t *init) 3551.1Sriastrad{ 3561.1Sriastrad drm_r128_private_t *dev_priv; 3571.1Sriastrad int rc; 3581.1Sriastrad 3591.1Sriastrad DRM_DEBUG("\n"); 3601.1Sriastrad 3611.1Sriastrad if (dev->dev_private) { 3621.1Sriastrad DRM_DEBUG("called when already initialized\n"); 3631.1Sriastrad return -EINVAL; 3641.1Sriastrad } 3651.1Sriastrad 3661.1Sriastrad dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL); 3671.1Sriastrad if (dev_priv == NULL) 3681.1Sriastrad return -ENOMEM; 3691.1Sriastrad 3701.1Sriastrad dev_priv->is_pci = init->is_pci; 3711.1Sriastrad 3721.1Sriastrad if (dev_priv->is_pci && !dev->sg) { 3731.1Sriastrad DRM_ERROR("PCI GART memory not allocated!\n"); 3741.1Sriastrad dev->dev_private = (void *)dev_priv; 3751.1Sriastrad r128_do_cleanup_cce(dev); 3761.1Sriastrad return -EINVAL; 3771.1Sriastrad } 3781.1Sriastrad 3791.1Sriastrad dev_priv->usec_timeout = init->usec_timeout; 3801.1Sriastrad if (dev_priv->usec_timeout < 1 || 3811.1Sriastrad dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) { 3821.1Sriastrad DRM_DEBUG("TIMEOUT problem!\n"); 3831.1Sriastrad dev->dev_private = (void *)dev_priv; 3841.1Sriastrad r128_do_cleanup_cce(dev); 3851.1Sriastrad return -EINVAL; 3861.1Sriastrad } 3871.1Sriastrad 3881.1Sriastrad dev_priv->cce_mode = init->cce_mode; 3891.1Sriastrad 3901.1Sriastrad /* GH: Simple idle check. 3911.1Sriastrad */ 3921.1Sriastrad atomic_set(&dev_priv->idle_count, 0); 3931.1Sriastrad 3941.1Sriastrad /* We don't support anything other than bus-mastering ring mode, 3951.1Sriastrad * but the ring can be in either AGP or PCI space for the ring 3961.1Sriastrad * read pointer. 3971.1Sriastrad */ 3981.1Sriastrad if ((init->cce_mode != R128_PM4_192BM) && 3991.1Sriastrad (init->cce_mode != R128_PM4_128BM_64INDBM) && 4001.1Sriastrad (init->cce_mode != R128_PM4_64BM_128INDBM) && 4011.1Sriastrad (init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) { 4021.1Sriastrad DRM_DEBUG("Bad cce_mode!\n"); 4031.1Sriastrad dev->dev_private = (void *)dev_priv; 4041.1Sriastrad r128_do_cleanup_cce(dev); 4051.1Sriastrad return -EINVAL; 4061.1Sriastrad } 4071.1Sriastrad 4081.1Sriastrad switch (init->cce_mode) { 4091.1Sriastrad case R128_PM4_NONPM4: 4101.1Sriastrad dev_priv->cce_fifo_size = 0; 4111.1Sriastrad break; 4121.1Sriastrad case R128_PM4_192PIO: 4131.1Sriastrad case R128_PM4_192BM: 4141.1Sriastrad dev_priv->cce_fifo_size = 192; 4151.1Sriastrad break; 4161.1Sriastrad case R128_PM4_128PIO_64INDBM: 4171.1Sriastrad case R128_PM4_128BM_64INDBM: 4181.1Sriastrad dev_priv->cce_fifo_size = 128; 4191.1Sriastrad break; 4201.1Sriastrad case R128_PM4_64PIO_128INDBM: 4211.1Sriastrad case R128_PM4_64BM_128INDBM: 4221.1Sriastrad case R128_PM4_64PIO_64VCBM_64INDBM: 4231.1Sriastrad case R128_PM4_64BM_64VCBM_64INDBM: 4241.1Sriastrad case R128_PM4_64PIO_64VCPIO_64INDPIO: 4251.1Sriastrad dev_priv->cce_fifo_size = 64; 4261.1Sriastrad break; 4271.1Sriastrad } 4281.1Sriastrad 4291.1Sriastrad switch (init->fb_bpp) { 4301.1Sriastrad case 16: 4311.1Sriastrad dev_priv->color_fmt = R128_DATATYPE_RGB565; 4321.1Sriastrad break; 4331.1Sriastrad case 32: 4341.1Sriastrad default: 4351.1Sriastrad dev_priv->color_fmt = R128_DATATYPE_ARGB8888; 4361.1Sriastrad break; 4371.1Sriastrad } 4381.1Sriastrad dev_priv->front_offset = init->front_offset; 4391.1Sriastrad dev_priv->front_pitch = init->front_pitch; 4401.1Sriastrad dev_priv->back_offset = init->back_offset; 4411.1Sriastrad dev_priv->back_pitch = init->back_pitch; 4421.1Sriastrad 4431.1Sriastrad switch (init->depth_bpp) { 4441.1Sriastrad case 16: 4451.1Sriastrad dev_priv->depth_fmt = R128_DATATYPE_RGB565; 4461.1Sriastrad break; 4471.1Sriastrad case 24: 4481.1Sriastrad case 32: 4491.1Sriastrad default: 4501.1Sriastrad dev_priv->depth_fmt = R128_DATATYPE_ARGB8888; 4511.1Sriastrad break; 4521.1Sriastrad } 4531.1Sriastrad dev_priv->depth_offset = init->depth_offset; 4541.1Sriastrad dev_priv->depth_pitch = init->depth_pitch; 4551.1Sriastrad dev_priv->span_offset = init->span_offset; 4561.1Sriastrad 4571.1Sriastrad dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) | 4581.1Sriastrad (dev_priv->front_offset >> 5)); 4591.1Sriastrad dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) | 4601.1Sriastrad (dev_priv->back_offset >> 5)); 4611.1Sriastrad dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | 4621.1Sriastrad (dev_priv->depth_offset >> 5) | 4631.1Sriastrad R128_DST_TILE); 4641.1Sriastrad dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | 4651.1Sriastrad (dev_priv->span_offset >> 5)); 4661.1Sriastrad 4671.2Sriastrad dev_priv->sarea = drm_legacy_getsarea(dev); 4681.1Sriastrad if (!dev_priv->sarea) { 4691.1Sriastrad DRM_ERROR("could not find sarea!\n"); 4701.1Sriastrad dev->dev_private = (void *)dev_priv; 4711.1Sriastrad r128_do_cleanup_cce(dev); 4721.1Sriastrad return -EINVAL; 4731.1Sriastrad } 4741.1Sriastrad 4751.2Sriastrad dev_priv->mmio = drm_legacy_findmap(dev, init->mmio_offset); 4761.1Sriastrad if (!dev_priv->mmio) { 4771.1Sriastrad DRM_ERROR("could not find mmio region!\n"); 4781.1Sriastrad dev->dev_private = (void *)dev_priv; 4791.1Sriastrad r128_do_cleanup_cce(dev); 4801.1Sriastrad return -EINVAL; 4811.1Sriastrad } 4821.2Sriastrad dev_priv->cce_ring = drm_legacy_findmap(dev, init->ring_offset); 4831.1Sriastrad if (!dev_priv->cce_ring) { 4841.1Sriastrad DRM_ERROR("could not find cce ring region!\n"); 4851.1Sriastrad dev->dev_private = (void *)dev_priv; 4861.1Sriastrad r128_do_cleanup_cce(dev); 4871.1Sriastrad return -EINVAL; 4881.1Sriastrad } 4891.2Sriastrad dev_priv->ring_rptr = drm_legacy_findmap(dev, init->ring_rptr_offset); 4901.1Sriastrad if (!dev_priv->ring_rptr) { 4911.1Sriastrad DRM_ERROR("could not find ring read pointer!\n"); 4921.1Sriastrad dev->dev_private = (void *)dev_priv; 4931.1Sriastrad r128_do_cleanup_cce(dev); 4941.1Sriastrad return -EINVAL; 4951.1Sriastrad } 4961.1Sriastrad dev->agp_buffer_token = init->buffers_offset; 4971.2Sriastrad dev->agp_buffer_map = drm_legacy_findmap(dev, init->buffers_offset); 4981.1Sriastrad if (!dev->agp_buffer_map) { 4991.1Sriastrad DRM_ERROR("could not find dma buffer region!\n"); 5001.1Sriastrad dev->dev_private = (void *)dev_priv; 5011.1Sriastrad r128_do_cleanup_cce(dev); 5021.1Sriastrad return -EINVAL; 5031.1Sriastrad } 5041.1Sriastrad 5051.1Sriastrad if (!dev_priv->is_pci) { 5061.1Sriastrad dev_priv->agp_textures = 5071.2Sriastrad drm_legacy_findmap(dev, init->agp_textures_offset); 5081.1Sriastrad if (!dev_priv->agp_textures) { 5091.1Sriastrad DRM_ERROR("could not find agp texture region!\n"); 5101.1Sriastrad dev->dev_private = (void *)dev_priv; 5111.1Sriastrad r128_do_cleanup_cce(dev); 5121.1Sriastrad return -EINVAL; 5131.1Sriastrad } 5141.1Sriastrad } 5151.1Sriastrad 5161.1Sriastrad dev_priv->sarea_priv = 5171.1Sriastrad (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle + 5181.1Sriastrad init->sarea_priv_offset); 5191.1Sriastrad 5201.2Sriastrad#if IS_ENABLED(CONFIG_AGP) 5211.1Sriastrad if (!dev_priv->is_pci) { 5221.2Sriastrad drm_legacy_ioremap_wc(dev_priv->cce_ring, dev); 5231.2Sriastrad drm_legacy_ioremap_wc(dev_priv->ring_rptr, dev); 5241.2Sriastrad drm_legacy_ioremap_wc(dev->agp_buffer_map, dev); 5251.1Sriastrad if (!dev_priv->cce_ring->handle || 5261.1Sriastrad !dev_priv->ring_rptr->handle || 5271.1Sriastrad !dev->agp_buffer_map->handle) { 5281.1Sriastrad DRM_ERROR("Could not ioremap agp regions!\n"); 5291.1Sriastrad dev->dev_private = (void *)dev_priv; 5301.1Sriastrad r128_do_cleanup_cce(dev); 5311.1Sriastrad return -ENOMEM; 5321.1Sriastrad } 5331.1Sriastrad } else 5341.1Sriastrad#endif 5351.1Sriastrad { 5361.1Sriastrad dev_priv->cce_ring->handle = 5371.1Sriastrad (void *)(unsigned long)dev_priv->cce_ring->offset; 5381.1Sriastrad dev_priv->ring_rptr->handle = 5391.1Sriastrad (void *)(unsigned long)dev_priv->ring_rptr->offset; 5401.1Sriastrad dev->agp_buffer_map->handle = 5411.1Sriastrad (void *)(unsigned long)dev->agp_buffer_map->offset; 5421.1Sriastrad } 5431.1Sriastrad 5441.2Sriastrad#if IS_ENABLED(CONFIG_AGP) 5451.1Sriastrad if (!dev_priv->is_pci) 5461.1Sriastrad dev_priv->cce_buffers_offset = dev->agp->base; 5471.1Sriastrad else 5481.1Sriastrad#endif 5491.1Sriastrad dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual; 5501.1Sriastrad 5511.1Sriastrad dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle; 5521.1Sriastrad dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle 5531.1Sriastrad + init->ring_size / sizeof(u32)); 5541.1Sriastrad dev_priv->ring.size = init->ring_size; 5551.2Sriastrad dev_priv->ring.size_l2qw = order_base_2(init->ring_size / 8); 5561.1Sriastrad 5571.1Sriastrad dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; 5581.1Sriastrad 5591.1Sriastrad dev_priv->ring.high_mark = 128; 5601.1Sriastrad 5611.1Sriastrad dev_priv->sarea_priv->last_frame = 0; 5621.1Sriastrad R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); 5631.1Sriastrad 5641.1Sriastrad dev_priv->sarea_priv->last_dispatch = 0; 5651.1Sriastrad R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch); 5661.1Sriastrad 5671.2Sriastrad#if IS_ENABLED(CONFIG_AGP) 5681.1Sriastrad if (dev_priv->is_pci) { 5691.1Sriastrad#endif 5701.1Sriastrad dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); 5711.1Sriastrad dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; 5721.1Sriastrad dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; 5731.1Sriastrad dev_priv->gart_info.addr = NULL; 5741.1Sriastrad dev_priv->gart_info.bus_addr = 0; 5751.1Sriastrad dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; 5761.3Sriastrad rc = drm_ati_pcigart_init(dev, &dev_priv->gart_info); 5771.3Sriastrad if (rc) { 5781.1Sriastrad DRM_ERROR("failed to init PCI GART!\n"); 5791.1Sriastrad dev->dev_private = (void *)dev_priv; 5801.1Sriastrad r128_do_cleanup_cce(dev); 5811.3Sriastrad return rc; 5821.1Sriastrad } 5831.1Sriastrad R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); 5841.2Sriastrad#if IS_ENABLED(CONFIG_AGP) 5851.1Sriastrad } 5861.1Sriastrad#endif 5871.1Sriastrad 5881.1Sriastrad r128_cce_init_ring_buffer(dev, dev_priv); 5891.1Sriastrad rc = r128_cce_load_microcode(dev_priv); 5901.1Sriastrad 5911.1Sriastrad dev->dev_private = (void *)dev_priv; 5921.1Sriastrad 5931.1Sriastrad r128_do_engine_reset(dev); 5941.1Sriastrad 5951.1Sriastrad if (rc) { 5961.1Sriastrad DRM_ERROR("Failed to load firmware!\n"); 5971.1Sriastrad r128_do_cleanup_cce(dev); 5981.1Sriastrad } 5991.1Sriastrad 6001.1Sriastrad return rc; 6011.1Sriastrad} 6021.1Sriastrad 6031.1Sriastradint r128_do_cleanup_cce(struct drm_device *dev) 6041.1Sriastrad{ 6051.1Sriastrad 6061.1Sriastrad /* Make sure interrupts are disabled here because the uninstall ioctl 6071.1Sriastrad * may not have been called from userspace and after dev_private 6081.1Sriastrad * is freed, it's too late. 6091.1Sriastrad */ 6101.1Sriastrad if (dev->irq_enabled) 6111.1Sriastrad drm_irq_uninstall(dev); 6121.1Sriastrad 6131.1Sriastrad if (dev->dev_private) { 6141.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 6151.1Sriastrad 6161.2Sriastrad#if IS_ENABLED(CONFIG_AGP) 6171.1Sriastrad if (!dev_priv->is_pci) { 6181.1Sriastrad if (dev_priv->cce_ring != NULL) 6191.2Sriastrad drm_legacy_ioremapfree(dev_priv->cce_ring, dev); 6201.1Sriastrad if (dev_priv->ring_rptr != NULL) 6211.2Sriastrad drm_legacy_ioremapfree(dev_priv->ring_rptr, dev); 6221.1Sriastrad if (dev->agp_buffer_map != NULL) { 6231.2Sriastrad drm_legacy_ioremapfree(dev->agp_buffer_map, dev); 6241.1Sriastrad dev->agp_buffer_map = NULL; 6251.1Sriastrad } 6261.1Sriastrad } else 6271.1Sriastrad#endif 6281.1Sriastrad { 6291.1Sriastrad if (dev_priv->gart_info.bus_addr) 6301.1Sriastrad if (!drm_ati_pcigart_cleanup(dev, 6311.1Sriastrad &dev_priv->gart_info)) 6321.1Sriastrad DRM_ERROR 6331.1Sriastrad ("failed to cleanup PCI GART!\n"); 6341.1Sriastrad } 6351.1Sriastrad 6361.1Sriastrad kfree(dev->dev_private); 6371.1Sriastrad dev->dev_private = NULL; 6381.1Sriastrad } 6391.1Sriastrad 6401.1Sriastrad return 0; 6411.1Sriastrad} 6421.1Sriastrad 6431.1Sriastradint r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv) 6441.1Sriastrad{ 6451.1Sriastrad drm_r128_init_t *init = data; 6461.1Sriastrad 6471.1Sriastrad DRM_DEBUG("\n"); 6481.1Sriastrad 6491.1Sriastrad LOCK_TEST_WITH_RETURN(dev, file_priv); 6501.1Sriastrad 6511.1Sriastrad switch (init->func) { 6521.1Sriastrad case R128_INIT_CCE: 6531.1Sriastrad return r128_do_init_cce(dev, init); 6541.1Sriastrad case R128_CLEANUP_CCE: 6551.1Sriastrad return r128_do_cleanup_cce(dev); 6561.1Sriastrad } 6571.1Sriastrad 6581.1Sriastrad return -EINVAL; 6591.1Sriastrad} 6601.1Sriastrad 6611.1Sriastradint r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv) 6621.1Sriastrad{ 6631.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 6641.1Sriastrad DRM_DEBUG("\n"); 6651.1Sriastrad 6661.1Sriastrad LOCK_TEST_WITH_RETURN(dev, file_priv); 6671.1Sriastrad 6681.1Sriastrad DEV_INIT_TEST_WITH_RETURN(dev_priv); 6691.1Sriastrad 6701.1Sriastrad if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { 6711.1Sriastrad DRM_DEBUG("while CCE running\n"); 6721.1Sriastrad return 0; 6731.1Sriastrad } 6741.1Sriastrad 6751.1Sriastrad r128_do_cce_start(dev_priv); 6761.1Sriastrad 6771.1Sriastrad return 0; 6781.1Sriastrad} 6791.1Sriastrad 6801.1Sriastrad/* Stop the CCE. The engine must have been idled before calling this 6811.1Sriastrad * routine. 6821.1Sriastrad */ 6831.1Sriastradint r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) 6841.1Sriastrad{ 6851.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 6861.1Sriastrad drm_r128_cce_stop_t *stop = data; 6871.1Sriastrad int ret; 6881.1Sriastrad DRM_DEBUG("\n"); 6891.1Sriastrad 6901.1Sriastrad LOCK_TEST_WITH_RETURN(dev, file_priv); 6911.1Sriastrad 6921.1Sriastrad DEV_INIT_TEST_WITH_RETURN(dev_priv); 6931.1Sriastrad 6941.1Sriastrad /* Flush any pending CCE commands. This ensures any outstanding 6951.1Sriastrad * commands are exectuted by the engine before we turn it off. 6961.1Sriastrad */ 6971.1Sriastrad if (stop->flush) 6981.1Sriastrad r128_do_cce_flush(dev_priv); 6991.1Sriastrad 7001.1Sriastrad /* If we fail to make the engine go idle, we return an error 7011.1Sriastrad * code so that the DRM ioctl wrapper can try again. 7021.1Sriastrad */ 7031.1Sriastrad if (stop->idle) { 7041.1Sriastrad ret = r128_do_cce_idle(dev_priv); 7051.1Sriastrad if (ret) 7061.1Sriastrad return ret; 7071.1Sriastrad } 7081.1Sriastrad 7091.1Sriastrad /* Finally, we can turn off the CCE. If the engine isn't idle, 7101.1Sriastrad * we will get some dropped triangles as they won't be fully 7111.1Sriastrad * rendered before the CCE is shut down. 7121.1Sriastrad */ 7131.1Sriastrad r128_do_cce_stop(dev_priv); 7141.1Sriastrad 7151.1Sriastrad /* Reset the engine */ 7161.1Sriastrad r128_do_engine_reset(dev); 7171.1Sriastrad 7181.1Sriastrad return 0; 7191.1Sriastrad} 7201.1Sriastrad 7211.1Sriastrad/* Just reset the CCE ring. Called as part of an X Server engine reset. 7221.1Sriastrad */ 7231.1Sriastradint r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) 7241.1Sriastrad{ 7251.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 7261.1Sriastrad DRM_DEBUG("\n"); 7271.1Sriastrad 7281.1Sriastrad LOCK_TEST_WITH_RETURN(dev, file_priv); 7291.1Sriastrad 7301.1Sriastrad DEV_INIT_TEST_WITH_RETURN(dev_priv); 7311.1Sriastrad 7321.1Sriastrad r128_do_cce_reset(dev_priv); 7331.1Sriastrad 7341.1Sriastrad /* The CCE is no longer running after an engine reset */ 7351.1Sriastrad dev_priv->cce_running = 0; 7361.1Sriastrad 7371.1Sriastrad return 0; 7381.1Sriastrad} 7391.1Sriastrad 7401.1Sriastradint r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) 7411.1Sriastrad{ 7421.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 7431.1Sriastrad DRM_DEBUG("\n"); 7441.1Sriastrad 7451.1Sriastrad LOCK_TEST_WITH_RETURN(dev, file_priv); 7461.1Sriastrad 7471.1Sriastrad DEV_INIT_TEST_WITH_RETURN(dev_priv); 7481.1Sriastrad 7491.1Sriastrad if (dev_priv->cce_running) 7501.1Sriastrad r128_do_cce_flush(dev_priv); 7511.1Sriastrad 7521.1Sriastrad return r128_do_cce_idle(dev_priv); 7531.1Sriastrad} 7541.1Sriastrad 7551.1Sriastradint r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) 7561.1Sriastrad{ 7571.1Sriastrad DRM_DEBUG("\n"); 7581.1Sriastrad 7591.1Sriastrad LOCK_TEST_WITH_RETURN(dev, file_priv); 7601.1Sriastrad 7611.1Sriastrad DEV_INIT_TEST_WITH_RETURN(dev->dev_private); 7621.1Sriastrad 7631.1Sriastrad return r128_do_engine_reset(dev); 7641.1Sriastrad} 7651.1Sriastrad 7661.1Sriastradint r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) 7671.1Sriastrad{ 7681.1Sriastrad return -EINVAL; 7691.1Sriastrad} 7701.1Sriastrad 7711.1Sriastrad/* ================================================================ 7721.1Sriastrad * Freelist management 7731.1Sriastrad */ 7741.1Sriastrad#define R128_BUFFER_USED 0xffffffff 7751.1Sriastrad#define R128_BUFFER_FREE 0 7761.1Sriastrad 7771.1Sriastrad#if 0 7781.1Sriastradstatic int r128_freelist_init(struct drm_device *dev) 7791.1Sriastrad{ 7801.1Sriastrad struct drm_device_dma *dma = dev->dma; 7811.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 7821.1Sriastrad struct drm_buf *buf; 7831.1Sriastrad drm_r128_buf_priv_t *buf_priv; 7841.1Sriastrad drm_r128_freelist_t *entry; 7851.1Sriastrad int i; 7861.1Sriastrad 7871.1Sriastrad dev_priv->head = kzalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL); 7881.1Sriastrad if (dev_priv->head == NULL) 7891.1Sriastrad return -ENOMEM; 7901.1Sriastrad 7911.1Sriastrad dev_priv->head->age = R128_BUFFER_USED; 7921.1Sriastrad 7931.1Sriastrad for (i = 0; i < dma->buf_count; i++) { 7941.1Sriastrad buf = dma->buflist[i]; 7951.1Sriastrad buf_priv = buf->dev_private; 7961.1Sriastrad 7971.1Sriastrad entry = kmalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL); 7981.1Sriastrad if (!entry) 7991.1Sriastrad return -ENOMEM; 8001.1Sriastrad 8011.1Sriastrad entry->age = R128_BUFFER_FREE; 8021.1Sriastrad entry->buf = buf; 8031.1Sriastrad entry->prev = dev_priv->head; 8041.1Sriastrad entry->next = dev_priv->head->next; 8051.1Sriastrad if (!entry->next) 8061.1Sriastrad dev_priv->tail = entry; 8071.1Sriastrad 8081.1Sriastrad buf_priv->discard = 0; 8091.1Sriastrad buf_priv->dispatched = 0; 8101.1Sriastrad buf_priv->list_entry = entry; 8111.1Sriastrad 8121.1Sriastrad dev_priv->head->next = entry; 8131.1Sriastrad 8141.1Sriastrad if (dev_priv->head->next) 8151.1Sriastrad dev_priv->head->next->prev = entry; 8161.1Sriastrad } 8171.1Sriastrad 8181.1Sriastrad return 0; 8191.1Sriastrad 8201.1Sriastrad} 8211.1Sriastrad#endif 8221.1Sriastrad 8231.1Sriastradstatic struct drm_buf *r128_freelist_get(struct drm_device * dev) 8241.1Sriastrad{ 8251.1Sriastrad struct drm_device_dma *dma = dev->dma; 8261.1Sriastrad drm_r128_private_t *dev_priv = dev->dev_private; 8271.1Sriastrad drm_r128_buf_priv_t *buf_priv; 8281.1Sriastrad struct drm_buf *buf; 8291.1Sriastrad int i, t; 8301.1Sriastrad 8311.1Sriastrad /* FIXME: Optimize -- use freelist code */ 8321.1Sriastrad 8331.1Sriastrad for (i = 0; i < dma->buf_count; i++) { 8341.1Sriastrad buf = dma->buflist[i]; 8351.1Sriastrad buf_priv = buf->dev_private; 8361.1Sriastrad if (!buf->file_priv) 8371.1Sriastrad return buf; 8381.1Sriastrad } 8391.1Sriastrad 8401.1Sriastrad for (t = 0; t < dev_priv->usec_timeout; t++) { 8411.1Sriastrad u32 done_age = R128_READ(R128_LAST_DISPATCH_REG); 8421.1Sriastrad 8431.1Sriastrad for (i = 0; i < dma->buf_count; i++) { 8441.1Sriastrad buf = dma->buflist[i]; 8451.1Sriastrad buf_priv = buf->dev_private; 8461.1Sriastrad if (buf->pending && buf_priv->age <= done_age) { 8471.1Sriastrad /* The buffer has been processed, so it 8481.1Sriastrad * can now be used. 8491.1Sriastrad */ 8501.1Sriastrad buf->pending = 0; 8511.1Sriastrad return buf; 8521.1Sriastrad } 8531.1Sriastrad } 8541.3Sriastrad udelay(1); 8551.1Sriastrad } 8561.1Sriastrad 8571.1Sriastrad DRM_DEBUG("returning NULL!\n"); 8581.1Sriastrad return NULL; 8591.1Sriastrad} 8601.1Sriastrad 8611.1Sriastradvoid r128_freelist_reset(struct drm_device *dev) 8621.1Sriastrad{ 8631.1Sriastrad struct drm_device_dma *dma = dev->dma; 8641.1Sriastrad int i; 8651.1Sriastrad 8661.1Sriastrad for (i = 0; i < dma->buf_count; i++) { 8671.1Sriastrad struct drm_buf *buf = dma->buflist[i]; 8681.1Sriastrad drm_r128_buf_priv_t *buf_priv = buf->dev_private; 8691.1Sriastrad buf_priv->age = 0; 8701.1Sriastrad } 8711.1Sriastrad} 8721.1Sriastrad 8731.1Sriastrad/* ================================================================ 8741.1Sriastrad * CCE command submission 8751.1Sriastrad */ 8761.1Sriastrad 8771.1Sriastradint r128_wait_ring(drm_r128_private_t *dev_priv, int n) 8781.1Sriastrad{ 8791.1Sriastrad drm_r128_ring_buffer_t *ring = &dev_priv->ring; 8801.1Sriastrad int i; 8811.1Sriastrad 8821.1Sriastrad for (i = 0; i < dev_priv->usec_timeout; i++) { 8831.1Sriastrad r128_update_ring_snapshot(dev_priv); 8841.1Sriastrad if (ring->space >= n) 8851.1Sriastrad return 0; 8861.3Sriastrad udelay(1); 8871.1Sriastrad } 8881.1Sriastrad 8891.1Sriastrad /* FIXME: This is being ignored... */ 8901.1Sriastrad DRM_ERROR("failed!\n"); 8911.1Sriastrad return -EBUSY; 8921.1Sriastrad} 8931.1Sriastrad 8941.1Sriastradstatic int r128_cce_get_buffers(struct drm_device *dev, 8951.1Sriastrad struct drm_file *file_priv, 8961.1Sriastrad struct drm_dma *d) 8971.1Sriastrad{ 8981.1Sriastrad int i; 8991.1Sriastrad struct drm_buf *buf; 9001.1Sriastrad 9011.1Sriastrad for (i = d->granted_count; i < d->request_count; i++) { 9021.1Sriastrad buf = r128_freelist_get(dev); 9031.1Sriastrad if (!buf) 9041.1Sriastrad return -EAGAIN; 9051.1Sriastrad 9061.1Sriastrad buf->file_priv = file_priv; 9071.1Sriastrad 9081.2Sriastrad if (copy_to_user(&d->request_indices[i], &buf->idx, 9091.1Sriastrad sizeof(buf->idx))) 9101.1Sriastrad return -EFAULT; 9111.2Sriastrad if (copy_to_user(&d->request_sizes[i], &buf->total, 9121.1Sriastrad sizeof(buf->total))) 9131.1Sriastrad return -EFAULT; 9141.1Sriastrad 9151.1Sriastrad d->granted_count++; 9161.1Sriastrad } 9171.1Sriastrad return 0; 9181.1Sriastrad} 9191.1Sriastrad 9201.1Sriastradint r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) 9211.1Sriastrad{ 9221.1Sriastrad struct drm_device_dma *dma = dev->dma; 9231.1Sriastrad int ret = 0; 9241.1Sriastrad struct drm_dma *d = data; 9251.1Sriastrad 9261.1Sriastrad LOCK_TEST_WITH_RETURN(dev, file_priv); 9271.1Sriastrad 9281.1Sriastrad /* Please don't send us buffers. 9291.1Sriastrad */ 9301.1Sriastrad if (d->send_count != 0) { 9311.1Sriastrad DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", 9321.3Sriastrad task_pid_nr(current), d->send_count); 9331.1Sriastrad return -EINVAL; 9341.1Sriastrad } 9351.1Sriastrad 9361.1Sriastrad /* We'll send you buffers. 9371.1Sriastrad */ 9381.1Sriastrad if (d->request_count < 0 || d->request_count > dma->buf_count) { 9391.1Sriastrad DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", 9401.3Sriastrad task_pid_nr(current), d->request_count, dma->buf_count); 9411.1Sriastrad return -EINVAL; 9421.1Sriastrad } 9431.1Sriastrad 9441.1Sriastrad d->granted_count = 0; 9451.1Sriastrad 9461.1Sriastrad if (d->request_count) 9471.1Sriastrad ret = r128_cce_get_buffers(dev, file_priv, d); 9481.1Sriastrad 9491.1Sriastrad return ret; 9501.1Sriastrad} 951