mga_dma.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:29k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*-
  2.  * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
  3.  *
  4.  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  5.  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  6.  * All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the "Software"),
  10.  * to deal in the Software without restriction, including without limitation
  11.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12.  * and/or sell copies of the Software, and to permit persons to whom the
  13.  * Software is furnished to do so, subject to the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice (including the next
  16.  * paragraph) shall be included in all copies or substantial portions of the
  17.  * Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  25.  * DEALINGS IN THE SOFTWARE.
  26.  *
  27.  * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
  28.  *     Jeff Hartmann <jhartmann@valinux.com>
  29.  *     Keith Whitwell <keithw@valinux.com>
  30.  *
  31.  */
  32. #define __NO_VERSION__
  33. #include "drmP.h"
  34. #include "mga_drv.h"
  35. #include <linux/interrupt.h> /* For task queue support */
  36. #define MGA_REG(reg) 2
  37. #define MGA_BASE(reg) ((unsigned long) 
  38. ((drm_device_t *)dev)->maplist[MGA_REG(reg)]->handle)
  39. #define MGA_ADDR(reg) (MGA_BASE(reg) + reg)
  40. #define MGA_DEREF(reg) *(__volatile__ int *)MGA_ADDR(reg)
  41. #define MGA_READ(reg) MGA_DEREF(reg)
  42. #define MGA_WRITE(reg,val)  do { MGA_DEREF(reg) = val; } while (0)
  43. #define PDEA_pagpxfer_enable       0x2
  44. static int mga_flush_queue(drm_device_t *dev);
  45. static unsigned long mga_alloc_page(drm_device_t *dev)
  46. {
  47. unsigned long address;
  48. address = __get_free_page(GFP_KERNEL);
  49. if(address == 0UL) {
  50. return 0;
  51. }
  52. atomic_inc(&virt_to_page(address)->count);
  53. set_bit(PG_reserved, &virt_to_page(address)->flags);
  54. return address;
  55. }
  56. static void mga_free_page(drm_device_t *dev, unsigned long page)
  57. {
  58. if(!page) return;
  59. atomic_dec(&virt_to_page(page)->count);
  60. clear_bit(PG_reserved, &virt_to_page(page)->flags);
  61. free_page(page);
  62. return;
  63. }
  64. static void mga_delay(void)
  65. {
  66. return;
  67. }
  68. /* These are two age tags that will never be sent to
  69.  * the hardware */
  70. #define MGA_BUF_USED  0xffffffff
  71. #define MGA_BUF_FREE 0
  72. static int mga_freelist_init(drm_device_t *dev)
  73. {
  74.        drm_device_dma_t *dma = dev->dma;
  75.     drm_buf_t *buf;
  76.     drm_mga_buf_priv_t *buf_priv;
  77.        drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  78.     drm_mga_freelist_t *item;
  79.     int i;
  80.     dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
  81. if(dev_priv->head == NULL) return -ENOMEM;
  82.     memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
  83.     dev_priv->head->age = MGA_BUF_USED;
  84.     for (i = 0; i < dma->buf_count; i++) {
  85.     buf = dma->buflist[ i ];
  86.         buf_priv = buf->dev_private;
  87. item = drm_alloc(sizeof(drm_mga_freelist_t),
  88.  DRM_MEM_DRIVER);
  89.     if(item == NULL) return -ENOMEM;
  90.     memset(item, 0, sizeof(drm_mga_freelist_t));
  91.    item->age = MGA_BUF_FREE;
  92.     item->prev = dev_priv->head;
  93.     item->next = dev_priv->head->next;
  94.     if(dev_priv->head->next != NULL)
  95. dev_priv->head->next->prev = item;
  96.     if(item->next == NULL) dev_priv->tail = item;
  97.     item->buf = buf;
  98.     buf_priv->my_freelist = item;
  99. buf_priv->discard = 0;
  100. buf_priv->dispatched = 0;
  101.     dev_priv->head->next = item;
  102. }
  103.     return 0;
  104. }
  105. static void mga_freelist_cleanup(drm_device_t *dev)
  106. {
  107.        drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  108.     drm_mga_freelist_t *item;
  109.     drm_mga_freelist_t *prev;
  110.     item = dev_priv->head;
  111.     while(item) {
  112.     prev = item;
  113.     item = item->next;
  114.     drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
  115. }
  116.     dev_priv->head = dev_priv->tail = NULL;
  117. }
  118. /* Frees dispatch lock */
  119. static inline void mga_dma_quiescent(drm_device_t *dev)
  120. {
  121. drm_device_dma_t  *dma      = dev->dma;
  122. drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  123. drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
  124.     unsigned long end;
  125. int i;
  126. DRM_DEBUG("dispatch_status = 0x%02lxn", dev_priv->dispatch_status);
  127. end = jiffies + (HZ*3);
  128.      while(1) {
  129. if(!test_and_set_bit(MGA_IN_DISPATCH,
  130.      &dev_priv->dispatch_status)) {
  131. break;
  132. }
  133.     if((signed)(end - jiffies) <= 0) {
  134. DRM_ERROR("irqs: %d wanted %dn",
  135.   atomic_read(&dev->total_irq),
  136.   atomic_read(&dma->total_lost));
  137. DRM_ERROR("lockup: dispatch_status = 0x%02lx,"
  138.   " jiffies = %lu, end = %lun",
  139.   dev_priv->dispatch_status, jiffies, end);
  140. return;
  141. }
  142. for (i = 0 ; i < 2000 ; i++) mga_delay();
  143. }
  144. end = jiffies + (HZ*3);
  145.      DRM_DEBUG("quiescent status : %xn", MGA_READ(MGAREG_STATUS));
  146.      while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
  147. if((signed)(end - jiffies) <= 0) {
  148. DRM_ERROR("irqs: %d wanted %dn",
  149.   atomic_read(&dev->total_irq),
  150.   atomic_read(&dma->total_lost));
  151. DRM_ERROR("lockupn");
  152. clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
  153. return;
  154. }
  155. for (i = 0 ; i < 2000 ; i++) mga_delay();
  156. }
  157.      sarea_priv->dirty |= MGA_DMA_FLUSH;
  158.      clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
  159. DRM_DEBUG("exit, dispatch_status = 0x%02lxn",
  160.   dev_priv->dispatch_status);
  161. }
  162. static void mga_reset_freelist(drm_device_t *dev)
  163. {
  164.     drm_device_dma_t  *dma      = dev->dma;
  165.     drm_buf_t *buf;
  166.     drm_mga_buf_priv_t *buf_priv;
  167. int i;
  168.     for (i = 0; i < dma->buf_count; i++) {
  169.     buf = dma->buflist[ i ];
  170.         buf_priv = buf->dev_private;
  171. buf_priv->my_freelist->age = MGA_BUF_FREE;
  172. }
  173. }
  174. /* Least recently used :
  175.  * These operations are not atomic b/c they are protected by the
  176.  * hardware lock */
  177. drm_buf_t *mga_freelist_get(drm_device_t *dev)
  178. {
  179.     DECLARE_WAITQUEUE(entry, current);
  180.     drm_mga_private_t *dev_priv =
  181.       (drm_mga_private_t *) dev->dev_private;
  182. drm_mga_freelist_t *prev;
  183.     drm_mga_freelist_t *next;
  184. static int failed = 0;
  185. int return_null = 0;
  186. if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
  187. DRM_DEBUG("Waiting on freelist,"
  188.   " tail->age = %d, last_prim_age= %dn",
  189.   dev_priv->tail->age,
  190.   dev_priv->last_prim_age);
  191.     add_wait_queue(&dev_priv->buf_queue, &entry);
  192. set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
  193.     for (;;) {
  194. current->state = TASK_INTERRUPTIBLE;
  195.     mga_dma_schedule(dev, 0);
  196. if(dev_priv->tail->age < dev_priv->last_prim_age)
  197. break;
  198.     atomic_inc(&dev->total_sleeps);
  199.     schedule();
  200.     if (signal_pending(current)) {
  201. ++return_null;
  202. break;
  203. }
  204. }
  205. clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
  206. current->state = TASK_RUNNING;
  207.     remove_wait_queue(&dev_priv->buf_queue, &entry);
  208. if (return_null) return NULL;
  209. }
  210.     if(dev_priv->tail->age < dev_priv->last_prim_age) {
  211. prev = dev_priv->tail->prev;
  212.     next = dev_priv->tail;
  213.     prev->next = NULL;
  214.     next->prev = next->next = NULL;
  215.     dev_priv->tail = prev;
  216.     next->age = MGA_BUF_USED;
  217. failed = 0;
  218.     return next->buf;
  219. }
  220. failed++;
  221.     return NULL;
  222. }
  223. int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
  224. {
  225.        drm_mga_private_t *dev_priv =
  226.       (drm_mga_private_t *) dev->dev_private;
  227.     drm_mga_buf_priv_t *buf_priv = buf->dev_private;
  228. drm_mga_freelist_t *prev;
  229.     drm_mga_freelist_t *head;
  230.     drm_mga_freelist_t *next;
  231.     if(buf_priv->my_freelist->age == MGA_BUF_USED) {
  232. /* Discarded buffer, put it on the tail */
  233. next = buf_priv->my_freelist;
  234. next->age = MGA_BUF_FREE;
  235. prev = dev_priv->tail;
  236. prev->next = next;
  237. next->prev = prev;
  238. next->next = NULL;
  239. dev_priv->tail = next;
  240. } else {
  241. /* Normally aged buffer, put it on the head + 1,
  242.  * as the real head is a sentinal element
  243.  */
  244. next = buf_priv->my_freelist;
  245. head = dev_priv->head;
  246. prev = head->next;
  247. head->next = next;
  248. prev->prev = next;
  249. next->prev = head;
  250. next->next = prev;
  251. }
  252.     return 0;
  253. }
  254. static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
  255. {
  256.     drm_mga_private_t *dev_priv = dev->dev_private;
  257. drm_mga_prim_buf_t *prim_buffer;
  258.     int i, temp, size_of_buf;
  259.     int offset = init->reserved_map_agpstart;
  260.     dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
  261.   PAGE_SIZE) * PAGE_SIZE;
  262.     size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
  263. dev_priv->warp_ucode_size = init->warp_ucode_size;
  264.     dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
  265. (MGA_NUM_PRIM_BUFS + 1),
  266. DRM_MEM_DRIVER);
  267.     if(dev_priv->prim_bufs == NULL) {
  268. DRM_ERROR("Unable to allocate memory for prim_bufn");
  269. return -ENOMEM;
  270. }
  271.     memset(dev_priv->prim_bufs,
  272.        0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
  273.     temp = init->warp_ucode_size + dev_priv->primary_size;
  274. temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
  275. dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
  276. temp);
  277. if(dev_priv->ioremap == NULL) {
  278. DRM_ERROR("Ioremap failedn");
  279. return -ENOMEM;
  280. }
  281.     init_waitqueue_head(&dev_priv->wait_queue);
  282.     for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
  283.     prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
  284. DRM_MEM_DRIVER);
  285.     if(prim_buffer == NULL) return -ENOMEM;
  286.     memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
  287.     prim_buffer->phys_head = offset + dev->agp->base;
  288.     prim_buffer->current_dma_ptr =
  289. prim_buffer->head =
  290. (u32 *) (dev_priv->ioremap +
  291.  offset -
  292.  init->reserved_map_agpstart);
  293.     prim_buffer->num_dwords = 0;
  294.     prim_buffer->max_dwords = size_of_buf / sizeof(u32);
  295.     prim_buffer->max_dwords -= 5; /* Leave room for the softrap */
  296.     prim_buffer->sec_used = 0;
  297.     prim_buffer->idx = i;
  298. prim_buffer->prim_age = i + 1;
  299.     offset = offset + size_of_buf;
  300.     dev_priv->prim_bufs[i] = prim_buffer;
  301. }
  302. dev_priv->current_prim_idx = 0;
  303.         dev_priv->next_prim =
  304. dev_priv->last_prim =
  305. dev_priv->current_prim =
  306.          dev_priv->prim_bufs[0];
  307. dev_priv->next_prim_age = 2;
  308. dev_priv->last_prim_age = 1;
  309.     set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status);
  310.     return 0;
  311. }
  312. void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
  313. {
  314.         drm_mga_private_t *dev_priv = dev->dev_private;
  315.        drm_device_dma_t  *dma     = dev->dma;
  316.         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
  317.   int use_agp = PDEA_pagpxfer_enable;
  318. unsigned long end;
  319.     int i;
  320.     int next_idx;
  321.         PRIMLOCALS;
  322.     dev_priv->last_prim = prim;
  323.   /* We never check for overflow, b/c there is always room */
  324.      PRIMPTR(prim);
  325.     if(num_dwords <= 0) {
  326. DRM_ERROR("num_dwords == 0 when dispatchedn");
  327. goto out_prim_wait;
  328. }
  329.   PRIMOUTREG( MGAREG_DMAPAD, 0);
  330.   PRIMOUTREG( MGAREG_DMAPAD, 0);
  331.         PRIMOUTREG( MGAREG_DMAPAD, 0);
  332.     PRIMOUTREG( MGAREG_SOFTRAP, 0);
  333.      PRIMFINISH(prim);
  334. end = jiffies + (HZ*3);
  335.      if(sarea_priv->dirty & MGA_DMA_FLUSH) {
  336. while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
  337. if((signed)(end - jiffies) <= 0) {
  338. DRM_ERROR("irqs: %d wanted %dn",
  339.   atomic_read(&dev->total_irq),
  340.   atomic_read(&dma->total_lost));
  341. DRM_ERROR("lockup (flush)n");
  342. goto out_prim_wait;
  343. }
  344. for (i = 0 ; i < 4096 ; i++) mga_delay();
  345. }
  346. sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
  347. } else {
  348. while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) {
  349. if((signed)(end - jiffies) <= 0) {
  350. DRM_ERROR("irqs: %d wanted %dn",
  351.   atomic_read(&dev->total_irq),
  352.   atomic_read(&dma->total_lost));
  353. DRM_ERROR("lockup (wait)n");
  354. goto out_prim_wait;
  355. }
  356. for (i = 0 ; i < 4096 ; i++) mga_delay();
  357. }
  358. }
  359.     mga_flush_write_combine();
  360.      atomic_inc(&dev_priv->pending_bufs);
  361.         MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
  362.   MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
  363.     prim->num_dwords = 0;
  364. sarea_priv->last_enqueue = prim->prim_age;
  365.     next_idx = prim->idx + 1;
  366.      if(next_idx >= MGA_NUM_PRIM_BUFS)
  367. next_idx = 0;
  368.      dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
  369. return;
  370.  out_prim_wait:
  371. prim->num_dwords = 0;
  372. prim->sec_used = 0;
  373. clear_bit(MGA_BUF_IN_USE, &prim->buffer_status);
  374.     wake_up_interruptible(&dev_priv->wait_queue);
  375. clear_bit(MGA_BUF_SWAP_PENDING, &prim->buffer_status);
  376. clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
  377. }
  378. int mga_advance_primary(drm_device_t *dev)
  379. {
  380.     DECLARE_WAITQUEUE(entry, current);
  381.     drm_mga_private_t *dev_priv = dev->dev_private;
  382.     drm_mga_prim_buf_t *prim_buffer;
  383.     drm_device_dma_t  *dma      = dev->dma;
  384.     int next_prim_idx;
  385.     int ret = 0;
  386.     /* This needs to reset the primary buffer if available,
  387.  * we should collect stats on how many times it bites
  388.  * it's tail */
  389.     next_prim_idx = dev_priv->current_prim_idx + 1;
  390.     if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
  391.       next_prim_idx = 0;
  392.     prim_buffer = dev_priv->prim_bufs[next_prim_idx];
  393. set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
  394.        /* In use is cleared in interrupt handler */
  395.     if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
  396.     add_wait_queue(&dev_priv->wait_queue, &entry);
  397.     for (;;) {
  398. current->state = TASK_INTERRUPTIBLE;
  399.     mga_dma_schedule(dev, 0);
  400.     if(!test_and_set_bit(MGA_BUF_IN_USE,
  401.      &prim_buffer->buffer_status))
  402. break;
  403.     atomic_inc(&dev->total_sleeps);
  404.     atomic_inc(&dma->total_missed_sched);
  405.     schedule();
  406.     if (signal_pending(current)) {
  407.     ret = -ERESTARTSYS;
  408.     break;
  409. }
  410. }
  411. current->state = TASK_RUNNING;
  412.     remove_wait_queue(&dev_priv->wait_queue, &entry);
  413.     if(ret) return ret;
  414. }
  415. clear_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
  416.     /* This primary buffer is now free to use */
  417.     prim_buffer->current_dma_ptr = prim_buffer->head;
  418.     prim_buffer->num_dwords = 0;
  419.     prim_buffer->sec_used = 0;
  420. prim_buffer->prim_age = dev_priv->next_prim_age++;
  421. if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) {
  422. mga_flush_queue(dev);
  423. mga_dma_quiescent(dev);
  424. mga_reset_freelist(dev);
  425. prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
  426. }
  427. /* Reset all buffer status stuff */
  428. clear_bit(MGA_BUF_NEEDS_OVERFLOW, &prim_buffer->buffer_status);
  429. clear_bit(MGA_BUF_FORCE_FIRE, &prim_buffer->buffer_status);
  430. clear_bit(MGA_BUF_SWAP_PENDING, &prim_buffer->buffer_status);
  431.     dev_priv->current_prim = prim_buffer;
  432.     dev_priv->current_prim_idx = next_prim_idx;
  433.     return 0;
  434. }
  435. /* More dynamic performance decisions */
  436. static inline int mga_decide_to_fire(drm_device_t *dev)
  437. {
  438.     drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  439.     if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
  440.     return 1;
  441. }
  442. if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
  443.     dev_priv->next_prim->num_dwords) {
  444.     return 1;
  445. }
  446. if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
  447.     dev_priv->next_prim->num_dwords) {
  448.     return 1;
  449. }
  450.     if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
  451. if(test_bit(MGA_BUF_SWAP_PENDING,
  452.     &dev_priv->next_prim->buffer_status)) {
  453. return 1;
  454. }
  455. }
  456.     if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) {
  457. if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) {
  458. return 1;
  459. }
  460. }
  461.     if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) {
  462. if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) {
  463. return 1;
  464. }
  465. }
  466.     return 0;
  467. }
  468. int mga_dma_schedule(drm_device_t *dev, int locked)
  469. {
  470.        drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  471. int               retval    = 0;
  472.     if (!dev_priv) return -EBUSY;
  473. if (test_and_set_bit(0, &dev->dma_flag)) {
  474. retval = -EBUSY;
  475. goto sch_out_wakeup;
  476. }
  477.     if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
  478.    test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) ||
  479.    test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
  480. locked = 1;
  481. }
  482.     if (!locked &&
  483.     !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
  484.     clear_bit(0, &dev->dma_flag);
  485. retval = -EBUSY;
  486. goto sch_out_wakeup;
  487. }
  488.     if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
  489.     /* Fire dma buffer */
  490.     if(mga_decide_to_fire(dev)) {
  491. clear_bit(MGA_BUF_FORCE_FIRE,
  492.   &dev_priv->next_prim->buffer_status);
  493.     if(dev_priv->current_prim == dev_priv->next_prim) {
  494. /* Schedule overflow for a later time */
  495. set_bit(MGA_BUF_NEEDS_OVERFLOW,
  496. &dev_priv->next_prim->buffer_status);
  497. }
  498.     mga_fire_primary(dev, dev_priv->next_prim);
  499. } else {
  500. clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
  501. }
  502. }
  503. if (!locked) {
  504. if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
  505.   DRM_KERNEL_CONTEXT)) {
  506. DRM_ERROR("n");
  507. }
  508. }
  509. clear_bit(0, &dev->dma_flag);
  510. sch_out_wakeup:
  511.        if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
  512.    atomic_read(&dev_priv->pending_bufs) == 0) {
  513. /* Everything has been processed by the hardware */
  514. clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
  515. wake_up_interruptible(&dev_priv->flush_queue);
  516. }
  517. if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)
  518.    && dev_priv->tail->age < dev_priv->last_prim_age)
  519. wake_up_interruptible(&dev_priv->buf_queue);
  520. return retval;
  521. }
  522. static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
  523. {
  524.      drm_device_t  *dev = (drm_device_t *)device;
  525.      drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  526.      drm_mga_prim_buf_t *last_prim_buffer;
  527.      atomic_inc(&dev->total_irq);
  528. if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
  529.        MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
  530.     last_prim_buffer = dev_priv->last_prim;
  531.      last_prim_buffer->num_dwords = 0;
  532.      last_prim_buffer->sec_used = 0;
  533. dev_priv->sarea_priv->last_dispatch =
  534. dev_priv->last_prim_age = last_prim_buffer->prim_age;
  535.        clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
  536.        clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
  537.        clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
  538.        atomic_dec(&dev_priv->pending_bufs);
  539.     queue_task(&dev->tq, &tq_immediate);
  540.     mark_bh(IMMEDIATE_BH);
  541.     wake_up_interruptible(&dev_priv->wait_queue);
  542. }
  543. static void mga_dma_task_queue(void *device)
  544. {
  545. mga_dma_schedule((drm_device_t *)device, 0);
  546. }
  547. int mga_dma_cleanup(drm_device_t *dev)
  548. {
  549. if(dev->dev_private) {
  550. drm_mga_private_t *dev_priv =
  551. (drm_mga_private_t *) dev->dev_private;
  552. if (dev->irq) mga_flush_queue(dev);
  553. mga_dma_quiescent(dev);
  554. if(dev_priv->ioremap) {
  555. int temp = (dev_priv->warp_ucode_size +
  556.     dev_priv->primary_size +
  557.     PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
  558. drm_ioremapfree((void *) dev_priv->ioremap, temp);
  559. }
  560.     if(dev_priv->status_page != NULL) {
  561.     iounmap(dev_priv->status_page);
  562. }
  563.     if(dev_priv->real_status_page != 0UL) {
  564.     mga_free_page(dev, dev_priv->real_status_page);
  565. }
  566.     if(dev_priv->prim_bufs != NULL) {
  567.     int i;
  568.     for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
  569.     if(dev_priv->prim_bufs[i] != NULL) {
  570.       drm_free(dev_priv->prim_bufs[i],
  571.  sizeof(drm_mga_prim_buf_t),
  572.  DRM_MEM_DRIVER);
  573. }
  574. }
  575.     drm_free(dev_priv->prim_bufs, sizeof(void *) *
  576.  (MGA_NUM_PRIM_BUFS + 1),
  577.  DRM_MEM_DRIVER);
  578. }
  579. if(dev_priv->head != NULL) {
  580.     mga_freelist_cleanup(dev);
  581. }
  582. drm_free(dev->dev_private, sizeof(drm_mga_private_t),
  583.  DRM_MEM_DRIVER);
  584. dev->dev_private = NULL;
  585. }
  586. return 0;
  587. }
  588. static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
  589. drm_mga_private_t *dev_priv;
  590. drm_map_t *sarea_map = NULL;
  591. dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
  592. if(dev_priv == NULL) return -ENOMEM;
  593. dev->dev_private = (void *) dev_priv;
  594. memset(dev_priv, 0, sizeof(drm_mga_private_t));
  595. if((init->reserved_map_idx >= dev->map_count) ||
  596.    (init->buffer_map_idx >= dev->map_count)) {
  597. mga_dma_cleanup(dev);
  598. return -EINVAL;
  599. }
  600. dev_priv->reserved_map_idx = init->reserved_map_idx;
  601. dev_priv->buffer_map_idx = init->buffer_map_idx;
  602. sarea_map = dev->maplist[0];
  603. dev_priv->sarea_priv = (drm_mga_sarea_t *)
  604. ((u8 *)sarea_map->handle +
  605.  init->sarea_priv_offset);
  606. /* Scale primary size to the next page */
  607. dev_priv->chipset = init->chipset;
  608. dev_priv->frontOffset = init->frontOffset;
  609. dev_priv->backOffset = init->backOffset;
  610. dev_priv->depthOffset = init->depthOffset;
  611. dev_priv->textureOffset = init->textureOffset;
  612. dev_priv->textureSize = init->textureSize;
  613. dev_priv->cpp = init->cpp;
  614. dev_priv->sgram = init->sgram;
  615. dev_priv->stride = init->stride;
  616. dev_priv->mAccess = init->mAccess;
  617.     init_waitqueue_head(&dev_priv->flush_queue);
  618. init_waitqueue_head(&dev_priv->buf_queue);
  619. dev_priv->WarpPipe = 0xff000000;
  620. dev_priv->vertexsize = 0;
  621.     DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x depthOffset=%xn",
  622.   dev_priv->chipset, dev_priv->warp_ucode_size,
  623.   dev_priv->backOffset, dev_priv->depthOffset);
  624.     DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %xn",
  625.   dev_priv->cpp, dev_priv->sgram, dev_priv->stride,
  626.   dev_priv->mAccess);
  627. memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
  628.        sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
  629.     if(mga_init_primary_bufs(dev, init) != 0) {
  630. DRM_ERROR("Can not initialize primary buffersn");
  631. mga_dma_cleanup(dev);
  632. return -ENOMEM;
  633. }
  634.     dev_priv->real_status_page = mga_alloc_page(dev);
  635.        if(dev_priv->real_status_page == 0UL) {
  636. mga_dma_cleanup(dev);
  637. DRM_ERROR("Can not allocate status pagen");
  638. return -ENOMEM;
  639. }
  640.     dev_priv->status_page =
  641. ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
  642. PAGE_SIZE);
  643.     if(dev_priv->status_page == NULL) {
  644. mga_dma_cleanup(dev);
  645. DRM_ERROR("Can not remap status pagen");
  646. return -ENOMEM;
  647. }
  648.     /* Write status page when secend or softrap occurs */
  649.     MGA_WRITE(MGAREG_PRIMPTR,
  650.   virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
  651. /* Private is now filled in, initialize the hardware */
  652. {
  653. PRIMLOCALS;
  654. PRIMGETPTR( dev_priv );
  655. PRIMOUTREG(MGAREG_DMAPAD, 0);
  656. PRIMOUTREG(MGAREG_DMAPAD, 0);
  657. PRIMOUTREG(MGAREG_DWGSYNC, 0x0100);
  658. PRIMOUTREG(MGAREG_SOFTRAP, 0);
  659. /* Poll for the first buffer to insure that
  660.  * the status register will be correct
  661.  */
  662. mga_flush_write_combine();
  663.     MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
  664. MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
  665.    PDEA_pagpxfer_enable));
  666.     while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
  667. }
  668. if(mga_freelist_init(dev) != 0) {
  669.     DRM_ERROR("Could not initialize freelistn");
  670.     mga_dma_cleanup(dev);
  671.     return -ENOMEM;
  672. }
  673. return 0;
  674. }
  675. int mga_dma_init(struct inode *inode, struct file *filp,
  676.  unsigned int cmd, unsigned long arg)
  677. {
  678. drm_file_t *priv = filp->private_data;
  679. drm_device_t *dev = priv->dev;
  680. drm_mga_init_t init;
  681. if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init)))
  682. return -EFAULT;
  683. switch(init.func) {
  684. case MGA_INIT_DMA:
  685. return mga_dma_initialize(dev, &init);
  686. case MGA_CLEANUP_DMA:
  687. return mga_dma_cleanup(dev);
  688. }
  689. return -EINVAL;
  690. }
  691. int mga_irq_install(drm_device_t *dev, int irq)
  692. {
  693. int retcode;
  694. if (!irq)     return -EINVAL;
  695. down(&dev->struct_sem);
  696. if (dev->irq) {
  697. up(&dev->struct_sem);
  698. return -EBUSY;
  699. }
  700. dev->irq = irq;
  701. up(&dev->struct_sem);
  702. DRM_DEBUG("install irq handler %dn", irq);
  703. dev->context_flag     = 0;
  704. dev->interrupt_flag   = 0;
  705. dev->dma_flag       = 0;
  706. dev->dma->next_buffer = NULL;
  707. dev->dma->next_queue  = NULL;
  708. dev->dma->this_buffer = NULL;
  709. INIT_LIST_HEAD(&dev->tq.list);
  710. dev->tq.sync       = 0;
  711. dev->tq.routine       = mga_dma_task_queue;
  712. dev->tq.data       = dev;
  713. /* Before installing handler */
  714. MGA_WRITE(MGAREG_IEN, 0);
  715.     /* Install handler */
  716. if ((retcode = request_irq(dev->irq,
  717.    mga_dma_service,
  718.    SA_SHIRQ,
  719.    dev->devname,
  720.    dev))) {
  721. down(&dev->struct_sem);
  722. dev->irq = 0;
  723. up(&dev->struct_sem);
  724. return retcode;
  725. }
  726. /* After installing handler */
  727.     MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
  728. MGA_WRITE(MGAREG_IEN, 0x00000001);
  729. return 0;
  730. }
  731. int mga_irq_uninstall(drm_device_t *dev)
  732. {
  733. int irq;
  734. down(&dev->struct_sem);
  735. irq  = dev->irq;
  736. dev->irq = 0;
  737. up(&dev->struct_sem);
  738. if (!irq) return -EINVAL;
  739.     DRM_DEBUG("remove irq handler %dn", irq);
  740.        MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
  741. MGA_WRITE(MGAREG_IEN, 0);
  742. free_irq(irq, dev);
  743. return 0;
  744. }
  745. int mga_control(struct inode *inode, struct file *filp, unsigned int cmd,
  746.   unsigned long arg)
  747. {
  748. drm_file_t *priv = filp->private_data;
  749. drm_device_t *dev = priv->dev;
  750. drm_control_t ctl;
  751. if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
  752. return -EFAULT;
  753. switch (ctl.func) {
  754. case DRM_INST_HANDLER:
  755. return mga_irq_install(dev, ctl.irq);
  756. case DRM_UNINST_HANDLER:
  757. return mga_irq_uninstall(dev);
  758. default:
  759. return -EINVAL;
  760. }
  761. }
  762. static int mga_flush_queue(drm_device_t *dev)
  763. {
  764.     DECLARE_WAITQUEUE(entry, current);
  765.    drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  766.     int ret = 0;
  767.     if(!dev_priv) return 0;
  768.     if(dev_priv->next_prim->num_dwords != 0) {
  769.     add_wait_queue(&dev_priv->flush_queue, &entry);
  770. if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status)) 
  771. DRM_ERROR("Incorrect mga_flush_queue logicn");
  772. set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
  773. mga_dma_schedule(dev, 0);
  774.     for (;;) {
  775. current->state = TASK_INTERRUPTIBLE;
  776.     if (!test_bit(MGA_IN_FLUSH,
  777.       &dev_priv->dispatch_status))
  778. break;
  779.     atomic_inc(&dev->total_sleeps);
  780.        schedule();
  781.        if (signal_pending(current)) {
  782.     ret = -EINTR; /* Can't restart */
  783. clear_bit(MGA_IN_FLUSH,
  784.   &dev_priv->dispatch_status);
  785.     break;
  786. }
  787. }
  788. current->state = TASK_RUNNING;
  789.     remove_wait_queue(&dev_priv->flush_queue, &entry);
  790. }
  791.     return ret;
  792. }
  793. /* Must be called with the lock held */
  794. void mga_reclaim_buffers(drm_device_t *dev, pid_t pid)
  795. {
  796. drm_device_dma_t *dma = dev->dma;
  797. int  i;
  798. if (!dma) return;
  799.        if(dev->dev_private == NULL) return;
  800. if(dma->buflist == NULL) return;
  801. DRM_DEBUG("buf_count=%dn", dma->buf_count);
  802.         mga_flush_queue(dev);
  803. for (i = 0; i < dma->buf_count; i++) {
  804.     drm_buf_t *buf = dma->buflist[ i ];
  805.     drm_mga_buf_priv_t *buf_priv = buf->dev_private;
  806. /* Only buffers that need to get reclaimed ever
  807.  * get set to free
  808.  */
  809. if (buf->pid == pid  && buf_priv) {
  810. if(buf_priv->my_freelist->age == MGA_BUF_USED)
  811.       buf_priv->my_freelist->age = MGA_BUF_FREE;
  812. }
  813. }
  814. }
  815. int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
  816.        unsigned long arg)
  817. {
  818. drm_file_t   *priv   = filp->private_data;
  819. drm_device_t   *dev   = priv->dev;
  820. DECLARE_WAITQUEUE(entry, current);
  821. int   ret = 0;
  822. drm_lock_t   lock;
  823. if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
  824. return -EFAULT;
  825. if (lock.context == DRM_KERNEL_CONTEXT) {
  826. DRM_ERROR("Process %d using kernel context %dn",
  827.   current->pid, lock.context);
  828. return -EINVAL;
  829. }
  830. if (lock.context < 0) return -EINVAL;
  831. /* Only one queue:
  832.  */
  833. if (!ret) {
  834. add_wait_queue(&dev->lock.lock_queue, &entry);
  835. for (;;) {
  836. current->state = TASK_INTERRUPTIBLE;
  837. if (!dev->lock.hw_lock) {
  838. /* Device has been unregistered */
  839. ret = -EINTR;
  840. break;
  841. }
  842. if (drm_lock_take(&dev->lock.hw_lock->lock,
  843.   lock.context)) {
  844. dev->lock.pid     = current->pid;
  845. dev->lock.lock_time = jiffies;
  846. atomic_inc(&dev->total_locks);
  847. break; /* Got lock */
  848. }
  849. /* Contention */
  850. atomic_inc(&dev->total_sleeps);
  851. schedule();
  852. if (signal_pending(current)) {
  853. ret = -ERESTARTSYS;
  854. break;
  855. }
  856. }
  857. current->state = TASK_RUNNING;
  858. remove_wait_queue(&dev->lock.lock_queue, &entry);
  859. }
  860. if (!ret) {
  861. sigemptyset(&dev->sigmask);
  862. sigaddset(&dev->sigmask, SIGSTOP);
  863. sigaddset(&dev->sigmask, SIGTSTP);
  864. sigaddset(&dev->sigmask, SIGTTIN);
  865. sigaddset(&dev->sigmask, SIGTTOU);
  866. dev->sigdata.context = lock.context;
  867. dev->sigdata.lock    = dev->lock.hw_lock;
  868. block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
  869. if (lock.flags & _DRM_LOCK_QUIESCENT) {
  870.    DRM_DEBUG("_DRM_LOCK_QUIESCENTn");
  871.    mga_flush_queue(dev);
  872.    mga_dma_quiescent(dev);
  873. }
  874. }
  875. if (ret) DRM_DEBUG("%d %sn", lock.context,
  876.    ret ? "interrupted" : "has lock");
  877. return ret;
  878. }
  879. int mga_flush_ioctl(struct inode *inode, struct file *filp,
  880.     unsigned int cmd, unsigned long arg)
  881. {
  882.         drm_file_t   *priv   = filp->private_data;
  883.      drm_device_t   *dev   = priv->dev;
  884. drm_lock_t   lock;
  885.        drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
  886. if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
  887. return -EFAULT;
  888. if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
  889. DRM_ERROR("lock not heldn");
  890. return -EINVAL;
  891. }
  892.     if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
  893. drm_mga_prim_buf_t *temp_buf;
  894. temp_buf = dev_priv->current_prim;
  895. if(temp_buf && temp_buf->num_dwords) {
  896. set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status);
  897. mga_advance_primary(dev);
  898.   }
  899. mga_dma_schedule(dev, 1);
  900. }
  901.     if(lock.flags & _DRM_LOCK_QUIESCENT) {
  902. mga_flush_queue(dev);
  903. mga_dma_quiescent(dev);
  904. }
  905.      return 0;
  906. }