1 /* mach64_dma.c -- DMA support for mach64 (Rage Pro) driver -*- linux-c -*- */
2 /**
3  * \file mach64_dma.c
4  * DMA support for mach64 (Rage Pro) driver
5  *
6  * \author Gareth Hughes <gareth@valinux.com>
7  * \author Frank C. Earl <fearl@airmail.net>
8  * \author Leif Delgass <ldelgass@retinalburn.net>
9  * \author José Fonseca <j_r_fonseca@yahoo.co.uk>
10  */
11 
12 /*
13  * Copyright 2000 Gareth Hughes
14  * Copyright 2002 Frank C. Earl
15  * Copyright 2002-2003 Leif Delgass
16  * All Rights Reserved.
17  *
18  * Permission is hereby granted, free of charge, to any person obtaining a
19  * copy of this software and associated documentation files (the "Software"),
20  * to deal in the Software without restriction, including without limitation
21  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
22  * and/or sell copies of the Software, and to permit persons to whom the
23  * Software is furnished to do so, subject to the following conditions:
24  *
25  * The above copyright notice and this permission notice (including the next
26  * paragraph) shall be included in all copies or substantial portions of the
27  * Software.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
32  * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35  */
36 
37 #include "drmP.h"
38 #include "drm.h"
39 #include "mach64_drm.h"
40 #include "mach64_drv.h"
41 
42 /*******************************************************************/
43 /** \name Engine, FIFO control */
44 /*@{*/
45 
46 /**
47  * Waits for free entries in the FIFO.
48  *
49  * \note Most writes to Mach64 registers are automatically routed through
50  * command FIFO which is 16 entry deep. Prior to writing to any draw engine
51  * register one has to ensure that enough FIFO entries are available by calling
52  * this function.  Failure to do so may cause the engine to lock.
53  *
54  * \param dev_priv pointer to device private data structure.
55  * \param entries number of free entries in the FIFO to wait for.
56  *
57  * \returns zero on success, or -EBUSY if the timeout (specificed by
58  * drm_mach64_private::usec_timeout) occurs.
59  */
mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv,int entries)60 int mach64_do_wait_for_fifo(drm_mach64_private_t *dev_priv, int entries)
61 {
62           int slots = 0, i;
63 
64           for (i = 0; i < dev_priv->usec_timeout; i++) {
65                     slots = (MACH64_READ(MACH64_FIFO_STAT) & MACH64_FIFO_SLOT_MASK);
66                     if (slots <= (0x8000 >> entries))
67                               return 0;
68                     DRM_UDELAY(1);
69           }
70 
71           DRM_INFO("failed! slots=%d entries=%d\n", slots, entries);
72           return -EBUSY;
73 }
74 
75 /**
76  * Wait for the draw engine to be idle.
77  */
mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv)78 int mach64_do_wait_for_idle(drm_mach64_private_t *dev_priv)
79 {
80           int i, ret;
81 
82           ret = mach64_do_wait_for_fifo(dev_priv, 16);
83           if (ret < 0)
84                     return ret;
85 
86           for (i = 0; i < dev_priv->usec_timeout; i++) {
87                     if (!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE))
88                               return 0;
89                     DRM_UDELAY(1);
90           }
91 
92           DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT));
93           mach64_dump_ring_info(dev_priv);
94           return -EBUSY;
95 }
96 
97 /**
98  * Wait for free entries in the ring buffer.
99  *
100  * The Mach64 bus master can be configured to act as a virtual FIFO, using a
101  * circular buffer (commonly referred as "ring buffer" in other drivers) with
102  * pointers to engine commands. This allows the CPU to do other things while
103  * the graphics engine is busy, i.e., DMA mode.
104  *
105  * This function should be called before writing new entries to the ring
106  * buffer.
107  *
108  * \param dev_priv pointer to device private data structure.
109  * \param n number of free entries in the ring buffer to wait for.
110  *
111  * \returns zero on success, or -EBUSY if the timeout (specificed by
112  * drm_mach64_private_t::usec_timeout) occurs.
113  *
114  * \sa mach64_dump_ring_info()
115  */
mach64_wait_ring(drm_mach64_private_t * dev_priv,int n)116 int mach64_wait_ring(drm_mach64_private_t *dev_priv, int n)
117 {
118           drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
119           int i;
120 
121           for (i = 0; i < dev_priv->usec_timeout; i++) {
122                     mach64_update_ring_snapshot(dev_priv);
123                     if (ring->space >= n) {
124                               if (i > 0)
125                                         DRM_DEBUG("%d usecs\n", i);
126                               return 0;
127                     }
128                     DRM_UDELAY(1);
129           }
130 
131           /* FIXME: This is being ignored... */
132           DRM_ERROR("failed!\n");
133           mach64_dump_ring_info(dev_priv);
134           return -EBUSY;
135 }
136 
137 /**
138  * Wait until all DMA requests have been processed...
139  *
140  * \sa mach64_wait_ring()
141  */
mach64_ring_idle(drm_mach64_private_t * dev_priv)142 static int mach64_ring_idle(drm_mach64_private_t *dev_priv)
143 {
144           drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
145           u32 head;
146           int i;
147 
148           head = ring->head;
149           i = 0;
150           while (i < dev_priv->usec_timeout) {
151                     mach64_update_ring_snapshot(dev_priv);
152                     if (ring->head == ring->tail &&
153                         !(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE)) {
154                               if (i > 0)
155                                         DRM_DEBUG("%d usecs\n", i);
156                               return 0;
157                     }
158                     if (ring->head == head) {
159                               ++i;
160                     } else {
161                               head = ring->head;
162                               i = 0;
163                     }
164                     DRM_UDELAY(1);
165           }
166 
167           DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT));
168           mach64_dump_ring_info(dev_priv);
169           return -EBUSY;
170 }
171 
172 /**
173  * Reset the the ring buffer descriptors.
174  *
175  * \sa mach64_do_engine_reset()
176  */
mach64_ring_reset(drm_mach64_private_t * dev_priv)177 static void mach64_ring_reset(drm_mach64_private_t *dev_priv)
178 {
179           drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
180 
181           mach64_do_release_used_buffers(dev_priv);
182           ring->head_addr = ring->start_addr;
183           ring->head = ring->tail = 0;
184           ring->space = ring->size;
185 
186           MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
187                          ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
188 
189           dev_priv->ring_running = 0;
190 }
191 
192 /**
193  * Ensure the all the queued commands will be processed.
194  */
mach64_do_dma_flush(drm_mach64_private_t * dev_priv)195 int mach64_do_dma_flush(drm_mach64_private_t *dev_priv)
196 {
197           /* FIXME: It's not necessary to wait for idle when flushing
198            * we just need to ensure the ring will be completely processed
199            * in finite time without another ioctl
200            */
201           return mach64_ring_idle(dev_priv);
202 }
203 
204 /**
205  * Stop all DMA activity.
206  */
mach64_do_dma_idle(drm_mach64_private_t * dev_priv)207 int mach64_do_dma_idle(drm_mach64_private_t *dev_priv)
208 {
209           int ret;
210 
211           /* wait for completion */
212           if ((ret = mach64_ring_idle(dev_priv)) < 0) {
213                     DRM_ERROR("failed BM_GUI_TABLE=0x%08x tail: %u\n",
214                                 MACH64_READ(MACH64_BM_GUI_TABLE),
215                                 dev_priv->ring.tail);
216                     return ret;
217           }
218 
219           mach64_ring_stop(dev_priv);
220 
221           /* clean up after pass */
222           mach64_do_release_used_buffers(dev_priv);
223           return 0;
224 }
225 
226 /**
227  * Reset the engine.  This will stop the DMA if it is running.
228  */
mach64_do_engine_reset(drm_mach64_private_t * dev_priv)229 int mach64_do_engine_reset(drm_mach64_private_t *dev_priv)
230 {
231           u32 tmp;
232 
233           DRM_DEBUG("\n");
234 
235           /* Kill off any outstanding DMA transfers.
236            */
237           tmp = MACH64_READ(MACH64_BUS_CNTL);
238           MACH64_WRITE(MACH64_BUS_CNTL, tmp | MACH64_BUS_MASTER_DIS);
239 
240           /* Reset the GUI engine (high to low transition).
241            */
242           tmp = MACH64_READ(MACH64_GEN_TEST_CNTL);
243           MACH64_WRITE(MACH64_GEN_TEST_CNTL, tmp & ~MACH64_GUI_ENGINE_ENABLE);
244           /* Enable the GUI engine
245            */
246           tmp = MACH64_READ(MACH64_GEN_TEST_CNTL);
247           MACH64_WRITE(MACH64_GEN_TEST_CNTL, tmp | MACH64_GUI_ENGINE_ENABLE);
248 
249           /* ensure engine is not locked up by clearing any FIFO or HOST errors
250            */
251           tmp = MACH64_READ(MACH64_BUS_CNTL);
252           MACH64_WRITE(MACH64_BUS_CNTL, tmp | 0x00a00000);
253 
254           /* Once GUI engine is restored, disable bus mastering */
255           MACH64_WRITE(MACH64_SRC_CNTL, 0);
256 
257           /* Reset descriptor ring */
258           mach64_ring_reset(dev_priv);
259 
260           return 0;
261 }
262 
263 /*@}*/
264 
265 
266 /*******************************************************************/
267 /** \name Debugging output */
268 /*@{*/
269 
270 /**
271  * Dump engine registers values.
272  */
mach64_dump_engine_info(drm_mach64_private_t * dev_priv)273 void mach64_dump_engine_info(drm_mach64_private_t *dev_priv)
274 {
275           DRM_INFO("\n");
276           if (!dev_priv->is_pci) {
277                     DRM_INFO("           AGP_BASE = 0x%08x\n",
278                                MACH64_READ(MACH64_AGP_BASE));
279                     DRM_INFO("           AGP_CNTL = 0x%08x\n",
280                                MACH64_READ(MACH64_AGP_CNTL));
281           }
282           DRM_INFO("     ALPHA_TST_CNTL = 0x%08x\n",
283                      MACH64_READ(MACH64_ALPHA_TST_CNTL));
284           DRM_INFO("\n");
285           DRM_INFO("         BM_COMMAND = 0x%08x\n",
286                      MACH64_READ(MACH64_BM_COMMAND));
287           DRM_INFO("BM_FRAME_BUF_OFFSET = 0x%08x\n",
288                      MACH64_READ(MACH64_BM_FRAME_BUF_OFFSET));
289           DRM_INFO("       BM_GUI_TABLE = 0x%08x\n",
290                      MACH64_READ(MACH64_BM_GUI_TABLE));
291           DRM_INFO("          BM_STATUS = 0x%08x\n",
292                      MACH64_READ(MACH64_BM_STATUS));
293           DRM_INFO(" BM_SYSTEM_MEM_ADDR = 0x%08x\n",
294                      MACH64_READ(MACH64_BM_SYSTEM_MEM_ADDR));
295           DRM_INFO("    BM_SYSTEM_TABLE = 0x%08x\n",
296                      MACH64_READ(MACH64_BM_SYSTEM_TABLE));
297           DRM_INFO("           BUS_CNTL = 0x%08x\n",
298                      MACH64_READ(MACH64_BUS_CNTL));
299           DRM_INFO("\n");
300           /* DRM_INFO( "         CLOCK_CNTL = 0x%08x\n", MACH64_READ( MACH64_CLOCK_CNTL ) ); */
301           DRM_INFO("        CLR_CMP_CLR = 0x%08x\n",
302                      MACH64_READ(MACH64_CLR_CMP_CLR));
303           DRM_INFO("       CLR_CMP_CNTL = 0x%08x\n",
304                      MACH64_READ(MACH64_CLR_CMP_CNTL));
305           /* DRM_INFO( "        CLR_CMP_MSK = 0x%08x\n", MACH64_READ( MACH64_CLR_CMP_MSK ) ); */
306           DRM_INFO("     CONFIG_CHIP_ID = 0x%08x\n",
307                      MACH64_READ(MACH64_CONFIG_CHIP_ID));
308           DRM_INFO("        CONFIG_CNTL = 0x%08x\n",
309                      MACH64_READ(MACH64_CONFIG_CNTL));
310           DRM_INFO("       CONFIG_STAT0 = 0x%08x\n",
311                      MACH64_READ(MACH64_CONFIG_STAT0));
312           DRM_INFO("       CONFIG_STAT1 = 0x%08x\n",
313                      MACH64_READ(MACH64_CONFIG_STAT1));
314           DRM_INFO("       CONFIG_STAT2 = 0x%08x\n",
315                      MACH64_READ(MACH64_CONFIG_STAT2));
316           DRM_INFO("            CRC_SIG = 0x%08x\n", MACH64_READ(MACH64_CRC_SIG));
317           DRM_INFO("  CUSTOM_MACRO_CNTL = 0x%08x\n",
318                      MACH64_READ(MACH64_CUSTOM_MACRO_CNTL));
319           DRM_INFO("\n");
320           /* DRM_INFO( "           DAC_CNTL = 0x%08x\n", MACH64_READ( MACH64_DAC_CNTL ) ); */
321           /* DRM_INFO( "           DAC_REGS = 0x%08x\n", MACH64_READ( MACH64_DAC_REGS ) ); */
322           DRM_INFO("        DP_BKGD_CLR = 0x%08x\n",
323                      MACH64_READ(MACH64_DP_BKGD_CLR));
324           DRM_INFO("        DP_FRGD_CLR = 0x%08x\n",
325                      MACH64_READ(MACH64_DP_FRGD_CLR));
326           DRM_INFO("             DP_MIX = 0x%08x\n", MACH64_READ(MACH64_DP_MIX));
327           DRM_INFO("       DP_PIX_WIDTH = 0x%08x\n",
328                      MACH64_READ(MACH64_DP_PIX_WIDTH));
329           DRM_INFO("             DP_SRC = 0x%08x\n", MACH64_READ(MACH64_DP_SRC));
330           DRM_INFO("      DP_WRITE_MASK = 0x%08x\n",
331                      MACH64_READ(MACH64_DP_WRITE_MASK));
332           DRM_INFO("         DSP_CONFIG = 0x%08x\n",
333                      MACH64_READ(MACH64_DSP_CONFIG));
334           DRM_INFO("         DSP_ON_OFF = 0x%08x\n",
335                      MACH64_READ(MACH64_DSP_ON_OFF));
336           DRM_INFO("           DST_CNTL = 0x%08x\n",
337                      MACH64_READ(MACH64_DST_CNTL));
338           DRM_INFO("      DST_OFF_PITCH = 0x%08x\n",
339                      MACH64_READ(MACH64_DST_OFF_PITCH));
340           DRM_INFO("\n");
341           /* DRM_INFO( "       EXT_DAC_REGS = 0x%08x\n", MACH64_READ( MACH64_EXT_DAC_REGS ) ); */
342           DRM_INFO("       EXT_MEM_CNTL = 0x%08x\n",
343                      MACH64_READ(MACH64_EXT_MEM_CNTL));
344           DRM_INFO("\n");
345           DRM_INFO("          FIFO_STAT = 0x%08x\n",
346                      MACH64_READ(MACH64_FIFO_STAT));
347           DRM_INFO("\n");
348           DRM_INFO("      GEN_TEST_CNTL = 0x%08x\n",
349                      MACH64_READ(MACH64_GEN_TEST_CNTL));
350           /* DRM_INFO( "              GP_IO = 0x%08x\n", MACH64_READ( MACH64_GP_IO ) ); */
351           DRM_INFO("   GUI_CMDFIFO_DATA = 0x%08x\n",
352                      MACH64_READ(MACH64_GUI_CMDFIFO_DATA));
353           DRM_INFO("  GUI_CMDFIFO_DEBUG = 0x%08x\n",
354                      MACH64_READ(MACH64_GUI_CMDFIFO_DEBUG));
355           DRM_INFO("           GUI_CNTL = 0x%08x\n",
356                      MACH64_READ(MACH64_GUI_CNTL));
357           DRM_INFO("           GUI_STAT = 0x%08x\n",
358                      MACH64_READ(MACH64_GUI_STAT));
359           DRM_INFO("      GUI_TRAJ_CNTL = 0x%08x\n",
360                      MACH64_READ(MACH64_GUI_TRAJ_CNTL));
361           DRM_INFO("\n");
362           DRM_INFO("          HOST_CNTL = 0x%08x\n",
363                      MACH64_READ(MACH64_HOST_CNTL));
364           DRM_INFO("           HW_DEBUG = 0x%08x\n",
365                      MACH64_READ(MACH64_HW_DEBUG));
366           DRM_INFO("\n");
367           DRM_INFO("    MEM_ADDR_CONFIG = 0x%08x\n",
368                      MACH64_READ(MACH64_MEM_ADDR_CONFIG));
369           DRM_INFO("       MEM_BUF_CNTL = 0x%08x\n",
370                      MACH64_READ(MACH64_MEM_BUF_CNTL));
371           DRM_INFO("\n");
372           DRM_INFO("           PAT_REG0 = 0x%08x\n",
373                      MACH64_READ(MACH64_PAT_REG0));
374           DRM_INFO("           PAT_REG1 = 0x%08x\n",
375                      MACH64_READ(MACH64_PAT_REG1));
376           DRM_INFO("\n");
377           DRM_INFO("            SC_LEFT = 0x%08x\n", MACH64_READ(MACH64_SC_LEFT));
378           DRM_INFO("           SC_RIGHT = 0x%08x\n",
379                      MACH64_READ(MACH64_SC_RIGHT));
380           DRM_INFO("             SC_TOP = 0x%08x\n", MACH64_READ(MACH64_SC_TOP));
381           DRM_INFO("          SC_BOTTOM = 0x%08x\n",
382                      MACH64_READ(MACH64_SC_BOTTOM));
383           DRM_INFO("\n");
384           DRM_INFO("      SCALE_3D_CNTL = 0x%08x\n",
385                      MACH64_READ(MACH64_SCALE_3D_CNTL));
386           DRM_INFO("       SCRATCH_REG0 = 0x%08x\n",
387                      MACH64_READ(MACH64_SCRATCH_REG0));
388           DRM_INFO("       SCRATCH_REG1 = 0x%08x\n",
389                      MACH64_READ(MACH64_SCRATCH_REG1));
390           DRM_INFO("         SETUP_CNTL = 0x%08x\n",
391                      MACH64_READ(MACH64_SETUP_CNTL));
392           DRM_INFO("           SRC_CNTL = 0x%08x\n",
393                      MACH64_READ(MACH64_SRC_CNTL));
394           DRM_INFO("\n");
395           DRM_INFO("           TEX_CNTL = 0x%08x\n",
396                      MACH64_READ(MACH64_TEX_CNTL));
397           DRM_INFO("     TEX_SIZE_PITCH = 0x%08x\n",
398                      MACH64_READ(MACH64_TEX_SIZE_PITCH));
399           DRM_INFO("       TIMER_CONFIG = 0x%08x\n",
400                      MACH64_READ(MACH64_TIMER_CONFIG));
401           DRM_INFO("\n");
402           DRM_INFO("             Z_CNTL = 0x%08x\n", MACH64_READ(MACH64_Z_CNTL));
403           DRM_INFO("        Z_OFF_PITCH = 0x%08x\n",
404                      MACH64_READ(MACH64_Z_OFF_PITCH));
405           DRM_INFO("\n");
406 }
407 
408 #define MACH64_DUMP_CONTEXT   3
409 
410 /**
411  * Used by mach64_dump_ring_info() to dump the contents of the current buffer
412  * pointed by the ring head.
413  */
mach64_dump_buf_info(drm_mach64_private_t * dev_priv,struct drm_buf * buf)414 static void mach64_dump_buf_info(drm_mach64_private_t *dev_priv,
415                                          struct drm_buf *buf)
416 {
417           u32 addr = GETBUFADDR(buf);
418           u32 used = buf->used >> 2;
419           u32 sys_addr = MACH64_READ(MACH64_BM_SYSTEM_MEM_ADDR);
420           u32 *p = GETBUFPTR(buf);
421           int skipped = 0;
422 
423           DRM_INFO("buffer contents:\n");
424 
425           while (used) {
426                     u32 reg, count;
427 
428                     reg = le32_to_cpu(*p++);
429                     if (addr <= GETBUFADDR(buf) + MACH64_DUMP_CONTEXT * 4 ||
430                         (addr >= sys_addr - MACH64_DUMP_CONTEXT * 4 &&
431                          addr <= sys_addr + MACH64_DUMP_CONTEXT * 4) ||
432                         addr >=
433                         GETBUFADDR(buf) + buf->used - MACH64_DUMP_CONTEXT * 4) {
434                               DRM_INFO("%08x:  0x%08x\n", addr, reg);
435                     }
436                     addr += 4;
437                     used--;
438 
439                     count = (reg >> 16) + 1;
440                     reg = reg & 0xffff;
441                     reg = MMSELECT(reg);
442                     while (count && used) {
443                               if (addr <= GETBUFADDR(buf) + MACH64_DUMP_CONTEXT * 4 ||
444                                   (addr >= sys_addr - MACH64_DUMP_CONTEXT * 4 &&
445                                    addr <= sys_addr + MACH64_DUMP_CONTEXT * 4) ||
446                                   addr >=
447                                   GETBUFADDR(buf) + buf->used -
448                                   MACH64_DUMP_CONTEXT * 4) {
449                                         DRM_INFO("%08x:    0x%04x = 0x%08x\n", addr,
450                                                    reg, le32_to_cpu(*p));
451                                         skipped = 0;
452                               } else {
453                                         if (!skipped) {
454                                                   DRM_INFO("  ...\n");
455                                                   skipped = 1;
456                                         }
457                               }
458                               p++;
459                               addr += 4;
460                               used--;
461 
462                               reg += 4;
463                               count--;
464                     }
465           }
466 
467           DRM_INFO("\n");
468 }
469 
470 /**
471  * Dump the ring state and contents, including the contents of the buffer being
472  * processed by the graphics engine.
473  */
mach64_dump_ring_info(drm_mach64_private_t * dev_priv)474 void mach64_dump_ring_info(drm_mach64_private_t *dev_priv)
475 {
476           drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
477           int i, skipped;
478 
479           DRM_INFO("\n");
480 
481           DRM_INFO("ring contents:\n");
482           DRM_INFO("  head_addr: 0x%08x head: %u tail: %u\n\n",
483                      ring->head_addr, ring->head, ring->tail);
484 
485           skipped = 0;
486           for (i = 0; i < ring->size / sizeof(u32); i += 4) {
487                     if (i <= MACH64_DUMP_CONTEXT * 4 ||
488                         i >= ring->size / sizeof(u32) - MACH64_DUMP_CONTEXT * 4 ||
489                         (i >= ring->tail - MACH64_DUMP_CONTEXT * 4 &&
490                          i <= ring->tail + MACH64_DUMP_CONTEXT * 4) ||
491                         (i >= ring->head - MACH64_DUMP_CONTEXT * 4 &&
492                          i <= ring->head + MACH64_DUMP_CONTEXT * 4)) {
493                               DRM_INFO("  0x%08x:  0x%08x 0x%08x 0x%08x 0x%08x%s%s\n",
494                                          (u32)(ring->start_addr + i * sizeof(u32)),
495                                          le32_to_cpu(((u32 *) ring->start)[i + 0]),
496                                          le32_to_cpu(((u32 *) ring->start)[i + 1]),
497                                          le32_to_cpu(((u32 *) ring->start)[i + 2]),
498                                          le32_to_cpu(((u32 *) ring->start)[i + 3]),
499                                          i == ring->head ? " (head)" : "",
500                                          i == ring->tail ? " (tail)" : "");
501                               skipped = 0;
502                     } else {
503                               if (!skipped) {
504                                         DRM_INFO("  ...\n");
505                                         skipped = 1;
506                               }
507                     }
508           }
509 
510           DRM_INFO("\n");
511 
512           if (ring->head < ring->size / sizeof(u32)) {
513                     struct list_head *ptr;
514                     u32 addr = le32_to_cpu(((u32 *) ring->start)[ring->head + 1]);
515 
516                     list_for_each(ptr, &dev_priv->pending) {
517                               drm_mach64_freelist_t *entry =
518                                   list_entry(ptr, drm_mach64_freelist_t, list);
519                               struct drm_buf *buf = entry->buf;
520 
521                               u32 buf_addr = GETBUFADDR(buf);
522 
523                               if (buf_addr <= addr && addr < buf_addr + buf->used)
524                                         mach64_dump_buf_info(dev_priv, buf);
525                     }
526           }
527 
528           DRM_INFO("\n");
529           DRM_INFO("       BM_GUI_TABLE = 0x%08x\n",
530                      MACH64_READ(MACH64_BM_GUI_TABLE));
531           DRM_INFO("\n");
532           DRM_INFO("BM_FRAME_BUF_OFFSET = 0x%08x\n",
533                      MACH64_READ(MACH64_BM_FRAME_BUF_OFFSET));
534           DRM_INFO(" BM_SYSTEM_MEM_ADDR = 0x%08x\n",
535                      MACH64_READ(MACH64_BM_SYSTEM_MEM_ADDR));
536           DRM_INFO("         BM_COMMAND = 0x%08x\n",
537                      MACH64_READ(MACH64_BM_COMMAND));
538           DRM_INFO("\n");
539           DRM_INFO("          BM_STATUS = 0x%08x\n",
540                      MACH64_READ(MACH64_BM_STATUS));
541           DRM_INFO("           BUS_CNTL = 0x%08x\n",
542                      MACH64_READ(MACH64_BUS_CNTL));
543           DRM_INFO("          FIFO_STAT = 0x%08x\n",
544                      MACH64_READ(MACH64_FIFO_STAT));
545           DRM_INFO("           GUI_STAT = 0x%08x\n",
546                      MACH64_READ(MACH64_GUI_STAT));
547           DRM_INFO("           SRC_CNTL = 0x%08x\n",
548                      MACH64_READ(MACH64_SRC_CNTL));
549 }
550 
551 /*@}*/
552 
553 
554 /*******************************************************************/
555 /** \name DMA descriptor ring macros */
556 /*@{*/
557 
558 /**
559  * Add the end mark to the ring's new tail position.
560  *
561  * The bus master engine will keep processing the DMA buffers listed in the ring
562  * until it finds this mark, making it stop.
563  *
564  * \sa mach64_clear_dma_eol
565  */
mach64_set_dma_eol(volatile u32 * addr)566 static __inline__ __unused void mach64_set_dma_eol(volatile u32 *addr)
567 {
568 #if defined(__i386__)
569           int nr = 31;
570 
571           /* Taken from include/asm-i386/bitops.h linux header */
572           __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr)
573                                    :"Ir"(nr));
574 #elif defined(__powerpc__)
575           u32 old;
576           u32 mask = cpu_to_le32(MACH64_DMA_EOL);
577 
578           /* Taken from the include/asm-ppc/bitops.h linux header */
579           __asm__ __volatile__("\n\
580 1:        lwarx     %0,0,%3 \n\
581           or        %0,%0,%2 \n\
582           stwcx.    %0,0,%3 \n\
583           bne-      1b":"=&r"(old), "=m"(*addr)
584                                    :"r"(mask), "r"(addr), "m"(*addr)
585                                    :"cc");
586 #elif defined(__alpha__)
587           u32 temp;
588           u32 mask = MACH64_DMA_EOL;
589 
590           /* Taken from the include/asm-alpha/bitops.h linux header */
591           __asm__ __volatile__("1:      ldl_l %0,%3\n"
592                                    "    bis %0,%2,%0\n"
593                                    "    stl_c %0,%1\n"
594                                    "    beq %0,2f\n"
595                                    ".subsection 2\n"
596                                    "2:  br 1b\n"
597                                    ".previous":"=&r"(temp), "=m"(*addr)
598                                    :"Ir"(mask), "m"(*addr));
599 #else
600           u32 mask = cpu_to_le32(MACH64_DMA_EOL);
601 
602           *addr |= mask;
603 #endif
604 }
605 
606 /**
607  * Remove the end mark from the ring's old tail position.
608  *
609  * It should be called after calling mach64_set_dma_eol to mark the ring's new
610  * tail position.
611  *
612  * We update the end marks while the bus master engine is in operation. Since
613  * the bus master engine may potentially be reading from the same position
614  * that we write, we must change atomically to avoid having intermediary bad
615  * data.
616  */
mach64_clear_dma_eol(volatile u32 * addr)617 static __inline__ void mach64_clear_dma_eol(volatile u32 *addr)
618 {
619 #if defined(__i386__)
620           int nr = 31;
621 
622           /* Taken from include/asm-i386/bitops.h linux header */
623           __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr)
624                                    :"Ir"(nr));
625 #elif defined(__powerpc__)
626           u32 old;
627           u32 mask = cpu_to_le32(MACH64_DMA_EOL);
628 
629           /* Taken from the include/asm-ppc/bitops.h linux header */
630           __asm__ __volatile__("\n\
631 1:        lwarx     %0,0,%3 \n\
632           andc      %0,%0,%2 \n\
633           stwcx.    %0,0,%3 \n\
634           bne-      1b":"=&r"(old), "=m"(*addr)
635                                    :"r"(mask), "r"(addr), "m"(*addr)
636                                    :"cc");
637 #elif defined(__alpha__)
638           u32 temp;
639           u32 mask = ~MACH64_DMA_EOL;
640 
641           /* Taken from the include/asm-alpha/bitops.h linux header */
642           __asm__ __volatile__("1:      ldl_l %0,%3\n"
643                                    "    and %0,%2,%0\n"
644                                    "    stl_c %0,%1\n"
645                                    "    beq %0,2f\n"
646                                    ".subsection 2\n"
647                                    "2:  br 1b\n"
648                                    ".previous":"=&r"(temp), "=m"(*addr)
649                                    :"Ir"(mask), "m"(*addr));
650 #else
651           u32 mask = cpu_to_le32(~MACH64_DMA_EOL);
652 
653           *addr &= mask;
654 #endif
655 }
656 
657 #define RING_LOCALS                                                             \
658           int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring
659 
660 #define RING_WRITE_OFS  _ring_write
661 
662 #define BEGIN_RING(n)                                                                     \
663           do {                                                                            \
664                     if (MACH64_VERBOSE) {                                                 \
665                               DRM_INFO( "BEGIN_RING( %d ) \n",                  \
666                                           (n) );                                \
667                     }                                                                     \
668                     if (dev_priv->ring.space <= (n) * sizeof(u32)) {  \
669                               int ret;                                          \
670                               if ((ret = mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \
671                                         DRM_ERROR( "wait_ring failed, resetting engine\n"); \
672                                         mach64_dump_engine_info( dev_priv );    \
673                                         mach64_do_engine_reset( dev_priv );     \
674                                         return ret;                                       \
675                               }                                                           \
676                     }                                                                     \
677                     dev_priv->ring.space -= (n) * sizeof(u32);                  \
678                     _ring = (u32 *) dev_priv->ring.start;                       \
679                     _ring_tail = _ring_write = dev_priv->ring.tail;             \
680                     _ring_mask = dev_priv->ring.tail_mask;                      \
681           } while (0)
682 
683 #define OUT_RING( x )                                                           \
684 do {                                                                            \
685           if (MACH64_VERBOSE) {                                                 \
686                     DRM_INFO( "   OUT_RING( 0x%08x ) at 0x%x\n",      \
687                                  (unsigned int)(x), _ring_write );    \
688           }                                                                     \
689           _ring[_ring_write++] = cpu_to_le32( x );                    \
690           _ring_write &= _ring_mask;                                  \
691 } while (0)
692 
693 #define ADVANCE_RING()                                                                    \
694 do {                                                                                      \
695           if (MACH64_VERBOSE) {                                                           \
696                     DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",         \
697                                 _ring_write, _ring_tail );                      \
698           }                                                                               \
699           DRM_MEMORYBARRIER();                                                            \
700           mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] );        \
701           DRM_MEMORYBARRIER();                                                            \
702           dev_priv->ring.tail = _ring_write;                                    \
703           mach64_ring_tick( dev_priv, &(dev_priv)->ring );            \
704 } while (0)
705 
706 /**
707  * Queue a DMA buffer of registers writes into the ring buffer.
708  */
mach64_add_buf_to_ring(drm_mach64_private_t * dev_priv,drm_mach64_freelist_t * entry)709 int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv,
710                            drm_mach64_freelist_t *entry)
711 {
712           int bytes, pages, remainder;
713           u32 address, page;
714           int i;
715           struct drm_buf *buf = entry->buf;
716           RING_LOCALS;
717 
718           bytes = buf->used;
719           address = GETBUFADDR( buf );
720           pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;
721 
722           BEGIN_RING( pages * 4 );
723 
724           for ( i = 0 ; i < pages-1 ; i++ ) {
725                     page = address + i * MACH64_DMA_CHUNKSIZE;
726                     OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
727                     OUT_RING( page );
728                     OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );
729                     OUT_RING( 0 );
730           }
731 
732           /* generate the final descriptor for any remaining commands in this buffer */
733           page = address + i * MACH64_DMA_CHUNKSIZE;
734           remainder = bytes - i * MACH64_DMA_CHUNKSIZE;
735 
736           /* Save dword offset of last descriptor for this buffer.
737            * This is needed to check for completion of the buffer in freelist_get
738            */
739           entry->ring_ofs = RING_WRITE_OFS;
740 
741           OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
742           OUT_RING( page );
743           OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );
744           OUT_RING( 0 );
745 
746           ADVANCE_RING();
747 
748           return 0;
749 }
750 
751 /**
752  * Queue DMA buffer controlling host data tranfers (e.g., blit).
753  *
754  * Almost identical to mach64_add_buf_to_ring.
755  */
mach64_add_hostdata_buf_to_ring(drm_mach64_private_t * dev_priv,drm_mach64_freelist_t * entry)756 int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv,
757                                     drm_mach64_freelist_t *entry)
758 {
759           int bytes, pages, remainder;
760           u32 address, page;
761           int i;
762           struct drm_buf *buf = entry->buf;
763           RING_LOCALS;
764 
765           bytes = buf->used - MACH64_HOSTDATA_BLIT_OFFSET;
766           pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;
767           address = GETBUFADDR( buf );
768 
769           BEGIN_RING( 4 + pages * 4 );
770 
771           OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
772           OUT_RING( address );
773           OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET );
774           OUT_RING( 0 );
775           address += MACH64_HOSTDATA_BLIT_OFFSET;
776 
777           for ( i = 0 ; i < pages-1 ; i++ ) {
778                     page = address + i * MACH64_DMA_CHUNKSIZE;
779                     OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );
780                     OUT_RING( page );
781                     OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );
782                     OUT_RING( 0 );
783           }
784 
785           /* generate the final descriptor for any remaining commands in this buffer */
786           page = address + i * MACH64_DMA_CHUNKSIZE;
787           remainder = bytes - i * MACH64_DMA_CHUNKSIZE;
788 
789           /* Save dword offset of last descriptor for this buffer.
790            * This is needed to check for completion of the buffer in freelist_get
791            */
792           entry->ring_ofs = RING_WRITE_OFS;
793 
794           OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );
795           OUT_RING( page );
796           OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );
797           OUT_RING( 0 );
798 
799           ADVANCE_RING();
800 
801           return 0;
802 }
803 
804 /*@}*/
805 
806 
807 /*******************************************************************/
808 /** \name DMA test and initialization */
809 /*@{*/
810 
811 /**
812  * Perform a simple DMA operation using the pattern registers to test whether
813  * DMA works.
814  *
815  * \return zero if successful.
816  *
817  * \note This function was the testbed for many experiences regarding Mach64
818  * DMA operation. It is left here since it so tricky to get DMA operating
819  * properly in some architectures and hardware.
820  */
mach64_bm_dma_test(struct drm_device * dev)821 static int mach64_bm_dma_test(struct drm_device * dev)
822 {
823           drm_mach64_private_t *dev_priv = dev->dev_private;
824           drm_dma_handle_t *cpu_addr_dmah;
825           u32 data_addr;
826           u32 *table, *data;
827           u32 expected[2];
828           u32 src_cntl, pat_reg0, pat_reg1;
829           int i, count, failed;
830 
831           DRM_DEBUG("\n");
832 
833           table = (u32 *) dev_priv->ring.start;
834 
835           /* FIXME: get a dma buffer from the freelist here */
836           DRM_DEBUG("Allocating data memory ...\n");
837 #ifdef __FreeBSD__
838           DRM_UNLOCK();
839 #endif
840           cpu_addr_dmah =
841               drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful);
842 #ifdef __FreeBSD__
843           DRM_LOCK();
844 #endif
845           if (!cpu_addr_dmah) {
846                     DRM_INFO("data-memory allocation failed!\n");
847                     return -ENOMEM;
848           } else {
849                     data = (u32 *) cpu_addr_dmah->vaddr;
850                     data_addr = (u32) cpu_addr_dmah->busaddr;
851           }
852 
853           /* Save the X server's value for SRC_CNTL and restore it
854            * in case our test fails.  This prevents the X server
855            * from disabling it's cache for this register
856            */
857           src_cntl = MACH64_READ(MACH64_SRC_CNTL);
858           pat_reg0 = MACH64_READ(MACH64_PAT_REG0);
859           pat_reg1 = MACH64_READ(MACH64_PAT_REG1);
860 
861           mach64_do_wait_for_fifo(dev_priv, 3);
862 
863           MACH64_WRITE(MACH64_SRC_CNTL, 0);
864           MACH64_WRITE(MACH64_PAT_REG0, 0x11111111);
865           MACH64_WRITE(MACH64_PAT_REG1, 0x11111111);
866 
867           mach64_do_wait_for_idle(dev_priv);
868 
869           for (i = 0; i < 2; i++) {
870                     u32 reg;
871                     reg = MACH64_READ((MACH64_PAT_REG0 + i * 4));
872                     DRM_DEBUG("(Before DMA Transfer) reg %d = 0x%08x\n", i, reg);
873                     if (reg != 0x11111111) {
874                               DRM_INFO("Error initializing test registers\n");
875                               DRM_INFO("resetting engine ...\n");
876                               mach64_do_engine_reset(dev_priv);
877                               DRM_INFO("freeing data buffer memory.\n");
878                               drm_pci_free(dev, cpu_addr_dmah);
879                               return -EIO;
880                     }
881           }
882 
883           /* fill up a buffer with sets of 2 consecutive writes starting with PAT_REG0 */
884           count = 0;
885 
886           data[count++] = cpu_to_le32(DMAREG(MACH64_PAT_REG0) | (1 << 16));
887           data[count++] = expected[0] = 0x22222222;
888           data[count++] = expected[1] = 0xaaaaaaaa;
889 
890           while (count < 1020) {
891                     data[count++] =
892                         cpu_to_le32(DMAREG(MACH64_PAT_REG0) | (1 << 16));
893                     data[count++] = 0x22222222;
894                     data[count++] = 0xaaaaaaaa;
895           }
896           data[count++] = cpu_to_le32(DMAREG(MACH64_SRC_CNTL) | (0 << 16));
897           data[count++] = 0;
898 
899           DRM_DEBUG("Preparing table ...\n");
900           table[MACH64_DMA_FRAME_BUF_OFFSET] = cpu_to_le32(MACH64_BM_ADDR +
901                                                                        MACH64_APERTURE_OFFSET);
902           table[MACH64_DMA_SYS_MEM_ADDR] = cpu_to_le32(data_addr);
903           table[MACH64_DMA_COMMAND] = cpu_to_le32(count * sizeof(u32)
904                                                             | MACH64_DMA_HOLD_OFFSET
905                                                             | MACH64_DMA_EOL);
906           table[MACH64_DMA_RESERVED] = 0;
907 
908           DRM_DEBUG("table[0] = 0x%08x\n", table[0]);
909           DRM_DEBUG("table[1] = 0x%08x\n", table[1]);
910           DRM_DEBUG("table[2] = 0x%08x\n", table[2]);
911           DRM_DEBUG("table[3] = 0x%08x\n", table[3]);
912 
913           for (i = 0; i < 6; i++) {
914                     DRM_DEBUG(" data[%d] = 0x%08x\n", i, data[i]);
915           }
916           DRM_DEBUG(" ...\n");
917           for (i = count - 5; i < count; i++) {
918                     DRM_DEBUG(" data[%d] = 0x%08x\n", i, data[i]);
919           }
920 
921           DRM_MEMORYBARRIER();
922 
923           DRM_DEBUG("waiting for idle...\n");
924           if ((i = mach64_do_wait_for_idle(dev_priv))) {
925                     DRM_INFO("mach64_do_wait_for_idle failed (result=%d)\n", i);
926                     DRM_INFO("resetting engine ...\n");
927                     mach64_do_engine_reset(dev_priv);
928                     mach64_do_wait_for_fifo(dev_priv, 3);
929                     MACH64_WRITE(MACH64_SRC_CNTL, src_cntl);
930                     MACH64_WRITE(MACH64_PAT_REG0, pat_reg0);
931                     MACH64_WRITE(MACH64_PAT_REG1, pat_reg1);
932                     DRM_INFO("freeing data buffer memory.\n");
933                     drm_pci_free(dev, cpu_addr_dmah);
934                     return i;
935           }
936           DRM_DEBUG("waiting for idle...done\n");
937 
938           DRM_DEBUG("BUS_CNTL = 0x%08x\n", MACH64_READ(MACH64_BUS_CNTL));
939           DRM_DEBUG("SRC_CNTL = 0x%08x\n", MACH64_READ(MACH64_SRC_CNTL));
940           DRM_DEBUG("\n");
941           DRM_DEBUG("data bus addr = 0x%08x\n", data_addr);
942           DRM_DEBUG("table bus addr = 0x%08x\n", dev_priv->ring.start_addr);
943 
944           DRM_DEBUG("starting DMA transfer...\n");
945           MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
946                          dev_priv->ring.start_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
947 
948           MACH64_WRITE(MACH64_SRC_CNTL,
949                          MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC |
950                          MACH64_SRC_BM_OP_SYSTEM_TO_REG);
951 
952           /* Kick off the transfer */
953           DRM_DEBUG("starting DMA transfer... done.\n");
954           MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0);
955 
956           DRM_DEBUG("waiting for idle...\n");
957 
958           if ((i = mach64_do_wait_for_idle(dev_priv))) {
959                     /* engine locked up, dump register state and reset */
960                     DRM_INFO("mach64_do_wait_for_idle failed (result=%d)\n", i);
961                     mach64_dump_engine_info(dev_priv);
962                     DRM_INFO("resetting engine ...\n");
963                     mach64_do_engine_reset(dev_priv);
964                     mach64_do_wait_for_fifo(dev_priv, 3);
965                     MACH64_WRITE(MACH64_SRC_CNTL, src_cntl);
966                     MACH64_WRITE(MACH64_PAT_REG0, pat_reg0);
967                     MACH64_WRITE(MACH64_PAT_REG1, pat_reg1);
968                     DRM_INFO("freeing data buffer memory.\n");
969                     drm_pci_free(dev, cpu_addr_dmah);
970                     return i;
971           }
972 
973           DRM_DEBUG("waiting for idle...done\n");
974 
975           /* restore SRC_CNTL */
976           mach64_do_wait_for_fifo(dev_priv, 1);
977           MACH64_WRITE(MACH64_SRC_CNTL, src_cntl);
978 
979           failed = 0;
980 
981           /* Check register values to see if the GUI master operation succeeded */
982           for (i = 0; i < 2; i++) {
983                     u32 reg;
984                     reg = MACH64_READ((MACH64_PAT_REG0 + i * 4));
985                     DRM_DEBUG("(After DMA Transfer) reg %d = 0x%08x\n", i, reg);
986                     if (reg != expected[i]) {
987                               failed = -1;
988                     }
989           }
990 
991           /* restore pattern registers */
992           mach64_do_wait_for_fifo(dev_priv, 2);
993           MACH64_WRITE(MACH64_PAT_REG0, pat_reg0);
994           MACH64_WRITE(MACH64_PAT_REG1, pat_reg1);
995 
996           DRM_DEBUG("freeing data buffer memory.\n");
997           drm_pci_free(dev, cpu_addr_dmah);
998           DRM_DEBUG("returning ...\n");
999 
1000           return failed;
1001 }
1002 
1003 /**
1004  * Called during the DMA initialization ioctl to initialize all the necessary
1005  * software and hardware state for DMA operation.
1006  */
mach64_do_dma_init(struct drm_device * dev,drm_mach64_init_t * init)1007 static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
1008 {
1009           drm_mach64_private_t *dev_priv;
1010           u32 tmp;
1011           int i, ret;
1012 
1013           DRM_DEBUG("\n");
1014 
1015           dev_priv = drm_alloc(sizeof(drm_mach64_private_t), DRM_MEM_DRIVER);
1016           if (dev_priv == NULL)
1017                     return -ENOMEM;
1018 
1019           memset(dev_priv, 0, sizeof(drm_mach64_private_t));
1020 
1021           dev_priv->is_pci = init->is_pci;
1022 
1023           dev_priv->fb_bpp = init->fb_bpp;
1024           dev_priv->front_offset = init->front_offset;
1025           dev_priv->front_pitch = init->front_pitch;
1026           dev_priv->back_offset = init->back_offset;
1027           dev_priv->back_pitch = init->back_pitch;
1028 
1029           dev_priv->depth_bpp = init->depth_bpp;
1030           dev_priv->depth_offset = init->depth_offset;
1031           dev_priv->depth_pitch = init->depth_pitch;
1032 
1033           dev_priv->front_offset_pitch = (((dev_priv->front_pitch / 8) << 22) |
1034                                                   (dev_priv->front_offset >> 3));
1035           dev_priv->back_offset_pitch = (((dev_priv->back_pitch / 8) << 22) |
1036                                                (dev_priv->back_offset >> 3));
1037           dev_priv->depth_offset_pitch = (((dev_priv->depth_pitch / 8) << 22) |
1038                                                   (dev_priv->depth_offset >> 3));
1039 
1040           dev_priv->usec_timeout = 1000000;
1041 
1042           /* Set up the freelist, placeholder list and pending list */
1043           INIT_LIST_HEAD(&dev_priv->free_list);
1044           INIT_LIST_HEAD(&dev_priv->placeholders);
1045           INIT_LIST_HEAD(&dev_priv->pending);
1046 
1047           dev_priv->sarea = drm_getsarea(dev);
1048           if (!dev_priv->sarea) {
1049                     DRM_ERROR("can not find sarea!\n");
1050                     dev->dev_private = (void *)dev_priv;
1051                     mach64_do_cleanup_dma(dev);
1052                     return -EINVAL;
1053           }
1054           dev_priv->fb = drm_core_findmap(dev, init->fb_offset);
1055           if (!dev_priv->fb) {
1056                     DRM_ERROR("can not find frame buffer map!\n");
1057                     dev->dev_private = (void *)dev_priv;
1058                     mach64_do_cleanup_dma(dev);
1059                     return -EINVAL;
1060           }
1061           dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
1062           if (!dev_priv->mmio) {
1063                     DRM_ERROR("can not find mmio map!\n");
1064                     dev->dev_private = (void *)dev_priv;
1065                     mach64_do_cleanup_dma(dev);
1066                     return -EINVAL;
1067           }
1068 
1069           dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset);
1070           if (!dev_priv->ring_map) {
1071                     DRM_ERROR("can not find ring map!\n");
1072                     dev->dev_private = (void *)dev_priv;
1073                     mach64_do_cleanup_dma(dev);
1074                     return -EINVAL;
1075           }
1076 
1077           dev_priv->sarea_priv = (drm_mach64_sarea_t *)
1078               ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
1079 
1080           if (!dev_priv->is_pci) {
1081                     drm_core_ioremap(dev_priv->ring_map, dev);
1082                     if (!dev_priv->ring_map->handle) {
1083                               DRM_ERROR("can not ioremap virtual address for"
1084                                           " descriptor ring\n");
1085                               dev->dev_private = (void *)dev_priv;
1086                               mach64_do_cleanup_dma(dev);
1087                               return -ENOMEM;
1088                     }
1089                     dev->agp_buffer_token = init->buffers_offset;
1090                     dev->agp_buffer_map =
1091                         drm_core_findmap(dev, init->buffers_offset);
1092                     if (!dev->agp_buffer_map) {
1093                               DRM_ERROR("can not find dma buffer map!\n");
1094                               dev->dev_private = (void *)dev_priv;
1095                               mach64_do_cleanup_dma(dev);
1096                               return -EINVAL;
1097                     }
1098                     /* there might be a nicer way to do this -
1099                        dev isn't passed all the way though the mach64 - DA */
1100                     dev_priv->dev_buffers = dev->agp_buffer_map;
1101 
1102                     drm_core_ioremap(dev->agp_buffer_map, dev);
1103                     if (!dev->agp_buffer_map->handle) {
1104                               DRM_ERROR("can not ioremap virtual address for"
1105                                           " dma buffer\n");
1106                               dev->dev_private = (void *)dev_priv;
1107                               mach64_do_cleanup_dma(dev);
1108                               return -ENOMEM;
1109                     }
1110                     dev_priv->agp_textures =
1111                         drm_core_findmap(dev, init->agp_textures_offset);
1112                     if (!dev_priv->agp_textures) {
1113                               DRM_ERROR("can not find agp texture region!\n");
1114                               dev->dev_private = (void *)dev_priv;
1115                               mach64_do_cleanup_dma(dev);
1116                               return -EINVAL;
1117                     }
1118           }
1119 
1120           dev->dev_private = (void *)dev_priv;
1121 
1122           dev_priv->driver_mode = init->dma_mode;
1123 
1124           /* changing the FIFO size from the default causes problems with DMA */
1125           tmp = MACH64_READ(MACH64_GUI_CNTL);
1126           if ((tmp & MACH64_CMDFIFO_SIZE_MASK) != MACH64_CMDFIFO_SIZE_128) {
1127                     DRM_INFO("Setting FIFO size to 128 entries\n");
1128                     /* FIFO must be empty to change the FIFO depth */
1129                     if ((ret = mach64_do_wait_for_idle(dev_priv))) {
1130                               DRM_ERROR
1131                                   ("wait for idle failed before changing FIFO depth!\n");
1132                               mach64_do_cleanup_dma(dev);
1133                               return ret;
1134                     }
1135                     MACH64_WRITE(MACH64_GUI_CNTL, ((tmp & ~MACH64_CMDFIFO_SIZE_MASK)
1136                                                          | MACH64_CMDFIFO_SIZE_128));
1137                     /* need to read GUI_STAT for proper sync according to docs */
1138                     if ((ret = mach64_do_wait_for_idle(dev_priv))) {
1139                               DRM_ERROR
1140                                   ("wait for idle failed when changing FIFO depth!\n");
1141                               mach64_do_cleanup_dma(dev);
1142                               return ret;
1143                     }
1144           }
1145 
1146           dev_priv->ring.size = 0x4000; /* 16KB */
1147           dev_priv->ring.start = dev_priv->ring_map->handle;
1148           dev_priv->ring.start_addr = (u32) dev_priv->ring_map->offset;
1149 
1150           memset(dev_priv->ring.start, 0, dev_priv->ring.size);
1151           DRM_INFO("descriptor ring: cpu addr %p, bus addr: 0x%08x\n",
1152                      dev_priv->ring.start, dev_priv->ring.start_addr);
1153 
1154           ret = 0;
1155           if (dev_priv->driver_mode != MACH64_MODE_MMIO) {
1156 
1157                     /* enable block 1 registers and bus mastering */
1158                     MACH64_WRITE(MACH64_BUS_CNTL, ((MACH64_READ(MACH64_BUS_CNTL)
1159                                                             | MACH64_BUS_EXT_REG_EN)
1160                                                          & ~MACH64_BUS_MASTER_DIS));
1161 
1162                     /* try a DMA GUI-mastering pass and fall back to MMIO if it fails */
1163                     DRM_DEBUG("Starting DMA test...\n");
1164                     if ((ret = mach64_bm_dma_test(dev))) {
1165                               dev_priv->driver_mode = MACH64_MODE_MMIO;
1166                     }
1167           }
1168 
1169           switch (dev_priv->driver_mode) {
1170           case MACH64_MODE_MMIO:
1171                     MACH64_WRITE(MACH64_BUS_CNTL, (MACH64_READ(MACH64_BUS_CNTL)
1172                                                          | MACH64_BUS_EXT_REG_EN
1173                                                          | MACH64_BUS_MASTER_DIS));
1174                     if (init->dma_mode == MACH64_MODE_MMIO)
1175                               DRM_INFO("Forcing pseudo-DMA mode\n");
1176                     else
1177                               DRM_INFO
1178                                   ("DMA test failed (ret=%d), using pseudo-DMA mode\n",
1179                                    ret);
1180                     break;
1181           case MACH64_MODE_DMA_SYNC:
1182                     DRM_INFO("DMA test succeeded, using synchronous DMA mode\n");
1183                     break;
1184           case MACH64_MODE_DMA_ASYNC:
1185           default:
1186                     DRM_INFO("DMA test succeeded, using asynchronous DMA mode\n");
1187           }
1188 
1189           dev_priv->ring_running = 0;
1190 
1191           /* setup offsets for physical address of table start and end */
1192           dev_priv->ring.head_addr = dev_priv->ring.start_addr;
1193           dev_priv->ring.head = dev_priv->ring.tail = 0;
1194           dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
1195           dev_priv->ring.space = dev_priv->ring.size;
1196 
1197           /* setup physical address and size of descriptor table */
1198           mach64_do_wait_for_fifo(dev_priv, 1);
1199           MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
1200                          (dev_priv->ring.
1201                           head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB));
1202 
1203           /* init frame counter */
1204           dev_priv->sarea_priv->frames_queued = 0;
1205           for (i = 0; i < MACH64_MAX_QUEUED_FRAMES; i++) {
1206                     dev_priv->frame_ofs[i] = ~0;  /* All ones indicates placeholder */
1207           }
1208 
1209           /* Allocate the DMA buffer freelist */
1210           if ((ret = mach64_init_freelist(dev))) {
1211                     DRM_ERROR("Freelist allocation failed\n");
1212                     mach64_do_cleanup_dma(dev);
1213                     return ret;
1214           }
1215 
1216           return 0;
1217 }
1218 
1219 /*******************************************************************/
1220 /** MMIO Pseudo-DMA (intended primarily for debugging, not performance)
1221  */
1222 
mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)1223 int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t *dev_priv)
1224 {
1225           drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
1226           volatile u32 *ring_read;
1227           struct list_head *ptr;
1228           drm_mach64_freelist_t *entry;
1229           struct drm_buf *buf = NULL;
1230           u32 *buf_ptr;
1231           u32 used, reg, target;
1232           int fifo, count, found, ret, no_idle_wait;
1233 
1234           fifo = count = reg = no_idle_wait = 0;
1235           target = MACH64_BM_ADDR;
1236 
1237           if ((ret = mach64_do_wait_for_idle(dev_priv)) < 0) {
1238                     DRM_INFO("idle failed before pseudo-dma dispatch, resetting engine\n");
1239                     mach64_dump_engine_info(dev_priv);
1240                     mach64_do_engine_reset(dev_priv);
1241                     return ret;
1242           }
1243 
1244           ring_read = (u32 *) ring->start;
1245 
1246           while (ring->tail != ring->head) {
1247                     u32 buf_addr, new_target, offset;
1248                     u32 bytes, remaining, head, eol;
1249 
1250                     head = ring->head;
1251 
1252                     new_target =
1253                         le32_to_cpu(ring_read[head++]) - MACH64_APERTURE_OFFSET;
1254                     buf_addr = le32_to_cpu(ring_read[head++]);
1255                     eol = le32_to_cpu(ring_read[head]) & MACH64_DMA_EOL;
1256                     bytes = le32_to_cpu(ring_read[head++])
1257                         & ~(MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL);
1258                     head++;
1259                     head &= ring->tail_mask;
1260 
1261                     /* can't wait for idle between a blit setup descriptor
1262                      * and a HOSTDATA descriptor or the engine will lock
1263                      */
1264                     if (new_target == MACH64_BM_HOSTDATA
1265                         && target == MACH64_BM_ADDR)
1266                               no_idle_wait = 1;
1267 
1268                     target = new_target;
1269 
1270                     found = 0;
1271                     offset = 0;
1272                     list_for_each(ptr, &dev_priv->pending) {
1273                               entry = list_entry(ptr, drm_mach64_freelist_t, list);
1274                               buf = entry->buf;
1275                               offset = buf_addr - GETBUFADDR(buf);
1276                               if (offset < MACH64_BUFFER_SIZE) {
1277                                         found = 1;
1278                                         break;
1279                               }
1280                     }
1281 
1282                     if (!found || buf == NULL) {
1283                               DRM_ERROR
1284                                   ("Couldn't find pending buffer: head: %u tail: %u buf_addr: 0x%08x %s\n",
1285                                    head, ring->tail, buf_addr, (eol ? "eol" : ""));
1286                               mach64_dump_ring_info(dev_priv);
1287                               mach64_do_engine_reset(dev_priv);
1288                               return -EINVAL;
1289                     }
1290 
1291                     /* Hand feed the buffer to the card via MMIO, waiting for the fifo
1292                      * every 16 writes
1293                      */
1294                     DRM_DEBUG("target: (0x%08x) %s\n", target,
1295                                 (target ==
1296                                  MACH64_BM_HOSTDATA ? "BM_HOSTDATA" : "BM_ADDR"));
1297                     DRM_DEBUG("offset: %u bytes: %u used: %u\n", offset, bytes,
1298                                 buf->used);
1299 
1300                     remaining = (buf->used - offset) >> 2;  /* dwords remaining in buffer */
1301                     used = bytes >> 2;  /* dwords in buffer for this descriptor */
1302                     buf_ptr = (u32 *) ((char *)GETBUFPTR(buf) + offset);
1303 
1304                     while (used) {
1305 
1306                               if (count == 0) {
1307                                         if (target == MACH64_BM_HOSTDATA) {
1308                                                   reg = DMAREG(MACH64_HOST_DATA0);
1309                                                   count =
1310                                                       (remaining > 16) ? 16 : remaining;
1311                                                   fifo = 0;
1312                                         } else {
1313                                                   reg = le32_to_cpu(*buf_ptr++);
1314                                                   used--;
1315                                                   count = (reg >> 16) + 1;
1316                                         }
1317 
1318                                         reg = reg & 0xffff;
1319                                         reg = MMSELECT(reg);
1320                               }
1321                               while (count && used) {
1322                                         if (!fifo) {
1323                                                   if (no_idle_wait) {
1324                                                             if ((ret =
1325                                                                  mach64_do_wait_for_fifo
1326                                                                  (dev_priv, 16)) < 0) {
1327                                                                       no_idle_wait = 0;
1328                                                                       return ret;
1329                                                             }
1330                                                   } else {
1331                                                             if ((ret =
1332                                                                  mach64_do_wait_for_idle
1333                                                                  (dev_priv)) < 0) {
1334                                                                       return ret;
1335                                                             }
1336                                                   }
1337                                                   fifo = 16;
1338                                         }
1339                                         --fifo;
1340                                         MACH64_WRITE(reg, le32_to_cpu(*buf_ptr++));
1341                                         used--;
1342                                         remaining--;
1343 
1344                                         reg += 4;
1345                                         count--;
1346                               }
1347                     }
1348                     ring->head = head;
1349                     ring->head_addr = ring->start_addr + (ring->head * sizeof(u32));
1350                     ring->space += (4 * sizeof(u32));
1351           }
1352 
1353           if ((ret = mach64_do_wait_for_idle(dev_priv)) < 0) {
1354                     return ret;
1355           }
1356           MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
1357                          ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
1358 
1359           DRM_DEBUG("completed\n");
1360           return 0;
1361 }
1362 
1363 /*@}*/
1364 
1365 
1366 /*******************************************************************/
1367 /** \name DMA cleanup */
1368 /*@{*/
1369 
mach64_do_cleanup_dma(struct drm_device * dev)1370 int mach64_do_cleanup_dma(struct drm_device * dev)
1371 {
1372           DRM_DEBUG("\n");
1373 
1374           /* Make sure interrupts are disabled here because the uninstall ioctl
1375            * may not have been called from userspace and after dev_private
1376            * is freed, it's too late.
1377            */
1378           if (dev->irq)
1379                     drm_irq_uninstall(dev);
1380 
1381           if (dev->dev_private) {
1382                     drm_mach64_private_t *dev_priv = dev->dev_private;
1383 
1384                     if (!dev_priv->is_pci) {
1385                               if (dev_priv->ring_map)
1386                                         drm_core_ioremapfree(dev_priv->ring_map, dev);
1387 
1388                               if (dev->agp_buffer_map) {
1389                                         drm_core_ioremapfree(dev->agp_buffer_map, dev);
1390                                         dev->agp_buffer_map = NULL;
1391                               }
1392                     }
1393 
1394                     mach64_destroy_freelist(dev);
1395 
1396                     drm_free(dev_priv, sizeof(drm_mach64_private_t),
1397                                DRM_MEM_DRIVER);
1398                     dev->dev_private = NULL;
1399           }
1400 
1401           return 0;
1402 }
1403 
1404 /*@}*/
1405 
1406 
1407 /*******************************************************************/
1408 /** \name IOCTL handlers */
1409 /*@{*/
1410 
mach64_dma_init(struct drm_device * dev,void * data,struct drm_file * file_priv)1411 int mach64_dma_init(struct drm_device *dev, void *data,
1412                         struct drm_file *file_priv)
1413 {
1414           drm_mach64_init_t *init = data;
1415 
1416           DRM_DEBUG("\n");
1417 
1418           LOCK_TEST_WITH_RETURN(dev, file_priv);
1419 
1420           switch (init->func) {
1421           case DRM_MACH64_INIT_DMA:
1422                     return mach64_do_dma_init(dev, init);
1423           case DRM_MACH64_CLEANUP_DMA:
1424                     return mach64_do_cleanup_dma(dev);
1425           }
1426 
1427           return -EINVAL;
1428 }
1429 
mach64_dma_idle(struct drm_device * dev,void * data,struct drm_file * file_priv)1430 int mach64_dma_idle(struct drm_device *dev, void *data,
1431                         struct drm_file *file_priv)
1432 {
1433           drm_mach64_private_t *dev_priv = dev->dev_private;
1434 
1435           DRM_DEBUG("\n");
1436 
1437           LOCK_TEST_WITH_RETURN(dev, file_priv);
1438 
1439           return mach64_do_dma_idle(dev_priv);
1440 }
1441 
mach64_dma_flush(struct drm_device * dev,void * data,struct drm_file * file_priv)1442 int mach64_dma_flush(struct drm_device *dev, void *data,
1443                          struct drm_file *file_priv)
1444 {
1445           drm_mach64_private_t *dev_priv = dev->dev_private;
1446 
1447           DRM_DEBUG("\n");
1448 
1449           LOCK_TEST_WITH_RETURN(dev, file_priv);
1450 
1451           return mach64_do_dma_flush(dev_priv);
1452 }
1453 
mach64_engine_reset(struct drm_device * dev,void * data,struct drm_file * file_priv)1454 int mach64_engine_reset(struct drm_device *dev, void *data,
1455                               struct drm_file *file_priv)
1456 {
1457           drm_mach64_private_t *dev_priv = dev->dev_private;
1458 
1459           DRM_DEBUG("\n");
1460 
1461           LOCK_TEST_WITH_RETURN(dev, file_priv);
1462 
1463           return mach64_do_engine_reset(dev_priv);
1464 }
1465 
1466 /*@}*/
1467 
1468 
1469 /*******************************************************************/
1470 /** \name Freelist management */
1471 /*@{*/
1472 
mach64_init_freelist(struct drm_device * dev)1473 int mach64_init_freelist(struct drm_device * dev)
1474 {
1475           struct drm_device_dma *dma = dev->dma;
1476           drm_mach64_private_t *dev_priv = dev->dev_private;
1477           drm_mach64_freelist_t *entry;
1478           struct list_head *ptr;
1479           int i;
1480 
1481           DRM_DEBUG("adding %d buffers to freelist\n", dma->buf_count);
1482 
1483           for (i = 0; i < dma->buf_count; i++) {
1484                     if ((entry =
1485                          (drm_mach64_freelist_t *)
1486                          drm_alloc(sizeof(drm_mach64_freelist_t),
1487                                      DRM_MEM_BUFLISTS)) == NULL)
1488                               return -ENOMEM;
1489                     memset(entry, 0, sizeof(drm_mach64_freelist_t));
1490                     entry->buf = dma->buflist[i];
1491                     ptr = &entry->list;
1492                     list_add_tail(ptr, &dev_priv->free_list);
1493           }
1494 
1495           return 0;
1496 }
1497 
mach64_destroy_freelist(struct drm_device * dev)1498 void mach64_destroy_freelist(struct drm_device * dev)
1499 {
1500           drm_mach64_private_t *dev_priv = dev->dev_private;
1501           drm_mach64_freelist_t *entry;
1502           struct list_head *ptr;
1503           struct list_head *tmp;
1504 
1505           DRM_DEBUG("\n");
1506 
1507           list_for_each_safe(ptr, tmp, &dev_priv->pending) {
1508                     list_del(ptr);
1509                     entry = list_entry(ptr, drm_mach64_freelist_t, list);
1510                     drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS);
1511           }
1512           list_for_each_safe(ptr, tmp, &dev_priv->placeholders) {
1513                     list_del(ptr);
1514                     entry = list_entry(ptr, drm_mach64_freelist_t, list);
1515                     drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS);
1516           }
1517 
1518           list_for_each_safe(ptr, tmp, &dev_priv->free_list) {
1519                     list_del(ptr);
1520                     entry = list_entry(ptr, drm_mach64_freelist_t, list);
1521                     drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS);
1522           }
1523 }
1524 
1525 /* IMPORTANT: This function should only be called when the engine is idle or locked up,
1526  * as it assumes all buffers in the pending list have been completed by the hardware.
1527  */
mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv)1528 int mach64_do_release_used_buffers(drm_mach64_private_t *dev_priv)
1529 {
1530           struct list_head *ptr;
1531           struct list_head *tmp;
1532           drm_mach64_freelist_t *entry;
1533           int i;
1534 
1535           if (list_empty(&dev_priv->pending))
1536                     return 0;
1537 
1538           /* Iterate the pending list and move all buffers into the freelist... */
1539           i = 0;
1540           list_for_each_safe(ptr, tmp, &dev_priv->pending) {
1541                     entry = list_entry(ptr, drm_mach64_freelist_t, list);
1542                     if (entry->discard) {
1543                               entry->buf->pending = 0;
1544                               list_del(ptr);
1545                               list_add_tail(ptr, &dev_priv->free_list);
1546                               i++;
1547                     }
1548           }
1549 
1550           DRM_DEBUG("released %d buffers from pending list\n", i);
1551 
1552           return 0;
1553 }
1554 
mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)1555 static int mach64_do_reclaim_completed(drm_mach64_private_t *dev_priv)
1556 {
1557           drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
1558           struct list_head *ptr;
1559           struct list_head *tmp;
1560           drm_mach64_freelist_t *entry;
1561           u32 head, tail, ofs;
1562 
1563           mach64_ring_tick(dev_priv, ring);
1564           head = ring->head;
1565           tail = ring->tail;
1566 
1567           if (head == tail) {
1568 #if MACH64_EXTRA_CHECKING
1569                     if (MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE) {
1570                               DRM_ERROR("Empty ring with non-idle engine!\n");
1571                               mach64_dump_ring_info(dev_priv);
1572                               return -1;
1573                     }
1574 #endif
1575                     /* last pass is complete, so release everything */
1576                     mach64_do_release_used_buffers(dev_priv);
1577                     DRM_DEBUG("idle engine, freed all buffers.\n");
1578                     if (list_empty(&dev_priv->free_list)) {
1579                               DRM_ERROR("Freelist empty with idle engine\n");
1580                               return -1;
1581                     }
1582                     return 0;
1583           }
1584           /* Look for a completed buffer and bail out of the loop
1585            * as soon as we find one -- don't waste time trying
1586            * to free extra bufs here, leave that to do_release_used_buffers
1587            */
1588           list_for_each_safe(ptr, tmp, &dev_priv->pending) {
1589                     entry = list_entry(ptr, drm_mach64_freelist_t, list);
1590                     ofs = entry->ring_ofs;
1591                     if (entry->discard &&
1592                         ((head < tail && (ofs < head || ofs >= tail)) ||
1593                          (head > tail && (ofs < head && ofs >= tail)))) {
1594 #if MACH64_EXTRA_CHECKING
1595                               int i;
1596 
1597                               for (i = head; i != tail; i = (i + 4) & ring->tail_mask)
1598                               {
1599                                         u32 o1 = le32_to_cpu(((u32 *) ring->
1600                                                              start)[i + 1]);
1601                                         u32 o2 = GETBUFADDR(entry->buf);
1602 
1603                                         if (o1 == o2) {
1604                                                   DRM_ERROR
1605                                                       ("Attempting to free used buffer: "
1606                                                        "i=%d  buf=0x%08x\n",
1607                                                        i, o1);
1608                                                   mach64_dump_ring_info(dev_priv);
1609                                                   return -1;
1610                                         }
1611                               }
1612 #endif
1613                               /* found a processed buffer */
1614                               entry->buf->pending = 0;
1615                               list_del(ptr);
1616                               list_add_tail(ptr, &dev_priv->free_list);
1617                               DRM_DEBUG
1618                                   ("freed processed buffer (head=%d tail=%d "
1619                                    "buf ring ofs=%d).\n",
1620                                    head, tail, ofs);
1621                               return 0;
1622                     }
1623           }
1624 
1625           return 1;
1626 }
1627 
mach64_freelist_get(drm_mach64_private_t * dev_priv)1628 struct drm_buf *mach64_freelist_get(drm_mach64_private_t *dev_priv)
1629 {
1630           drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
1631           drm_mach64_freelist_t *entry;
1632           struct list_head *ptr;
1633           int t;
1634 
1635           if (list_empty(&dev_priv->free_list)) {
1636                     if (list_empty(&dev_priv->pending)) {
1637                               DRM_ERROR
1638                                   ("Couldn't get buffer - pending and free lists empty\n");
1639                               t = 0;
1640                               list_for_each(ptr, &dev_priv->placeholders) {
1641                                         t++;
1642                               }
1643                               DRM_INFO("Placeholders: %d\n", t);
1644                               return NULL;
1645                     }
1646 
1647                     for (t = 0; t < dev_priv->usec_timeout; t++) {
1648                               int ret;
1649 
1650                               ret = mach64_do_reclaim_completed(dev_priv);
1651                               if (ret == 0)
1652                                         goto _freelist_entry_found;
1653                               if (ret < 0)
1654                                         return NULL;
1655 
1656                               DRM_UDELAY(1);
1657                     }
1658                     mach64_dump_ring_info(dev_priv);
1659                     DRM_ERROR
1660                         ("timeout waiting for buffers: ring head_addr: 0x%08x head: %d tail: %d\n",
1661                          ring->head_addr, ring->head, ring->tail);
1662                     return NULL;
1663           }
1664 
1665       _freelist_entry_found:
1666           ptr = dev_priv->free_list.next;
1667           list_del(ptr);
1668           entry = list_entry(ptr, drm_mach64_freelist_t, list);
1669           entry->buf->used = 0;
1670           list_add_tail(ptr, &dev_priv->placeholders);
1671           return entry->buf;
1672 }
1673 
mach64_freelist_put(drm_mach64_private_t * dev_priv,struct drm_buf * copy_buf)1674 int mach64_freelist_put(drm_mach64_private_t *dev_priv, struct drm_buf *copy_buf)
1675 {
1676           struct list_head *ptr;
1677           drm_mach64_freelist_t *entry;
1678 
1679 #if MACH64_EXTRA_CHECKING
1680           list_for_each(ptr, &dev_priv->pending) {
1681                     entry = list_entry(ptr, drm_mach64_freelist_t, list);
1682                     if (copy_buf == entry->buf) {
1683                               DRM_ERROR("Trying to release a pending buf\n");
1684                               return -EFAULT;
1685                     }
1686           }
1687 #endif
1688           ptr = dev_priv->placeholders.next;
1689           entry = list_entry(ptr, drm_mach64_freelist_t, list);
1690           copy_buf->pending = 0;
1691           copy_buf->used = 0;
1692           entry->buf = copy_buf;
1693           entry->discard = 1;
1694           list_del(ptr);
1695           list_add_tail(ptr, &dev_priv->free_list);
1696 
1697           return 0;
1698 }
1699 
1700 /*@}*/
1701 
1702 
1703 /*******************************************************************/
1704 /** \name DMA buffer request and submission IOCTL handler */
1705 /*@{*/
1706 
mach64_dma_get_buffers(struct drm_device * dev,struct drm_file * file_priv,struct drm_dma * d)1707 static int mach64_dma_get_buffers(struct drm_device *dev,
1708                                           struct drm_file *file_priv,
1709                                           struct drm_dma * d)
1710 {
1711           int i;
1712           struct drm_buf *buf;
1713           drm_mach64_private_t *dev_priv = dev->dev_private;
1714 
1715           for (i = d->granted_count; i < d->request_count; i++) {
1716                     buf = mach64_freelist_get(dev_priv);
1717 #if MACH64_EXTRA_CHECKING
1718                     if (!buf)
1719                               return -EFAULT;
1720 #else
1721                     if (!buf)
1722                               return -EAGAIN;
1723 #endif
1724 
1725                     buf->file_priv = file_priv;
1726 
1727                     if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
1728                                              sizeof(buf->idx)))
1729                               return -EFAULT;
1730                     if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
1731                                              sizeof(buf->total)))
1732                               return -EFAULT;
1733 
1734                     d->granted_count++;
1735           }
1736           return 0;
1737 }
1738 
mach64_dma_buffers(struct drm_device * dev,void * data,struct drm_file * file_priv)1739 int mach64_dma_buffers(struct drm_device *dev, void *data,
1740                            struct drm_file *file_priv)
1741 {
1742           struct drm_device_dma *dma = dev->dma;
1743           struct drm_dma *d = data;
1744           int ret = 0;
1745 
1746           LOCK_TEST_WITH_RETURN(dev, file_priv);
1747 
1748           /* Please don't send us buffers.
1749            */
1750           if (d->send_count != 0) {
1751                     DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
1752                                 DRM_CURRENTPID, d->send_count);
1753                     return -EINVAL;
1754           }
1755 
1756           /* We'll send you buffers.
1757            */
1758           if (d->request_count < 0 || d->request_count > dma->buf_count) {
1759                     DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
1760                                 DRM_CURRENTPID, d->request_count, dma->buf_count);
1761                     ret = -EINVAL;
1762           }
1763 
1764           d->granted_count = 0;
1765 
1766           if (d->request_count) {
1767                     ret = mach64_dma_get_buffers(dev, file_priv, d);
1768           }
1769 
1770           return ret;
1771 }
1772 
mach64_driver_lastclose(struct drm_device * dev)1773 void mach64_driver_lastclose(struct drm_device * dev)
1774 {
1775           mach64_do_cleanup_dma(dev);
1776 }
1777 
1778 /*@}*/
1779