The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/mach64_drv.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* mach64_drv.h -- Private header for mach64 driver -*- linux-c -*-
    2  * Created: Fri Nov 24 22:07:58 2000 by gareth@valinux.com
    3  */
    4 /*-
    5  * Copyright 2000 Gareth Hughes
    6  * Copyright 2002 Frank C. Earl
    7  * Copyright 2002-2003 Leif Delgass
    8  * All Rights Reserved.
    9  *
   10  * Permission is hereby granted, free of charge, to any person obtaining a
   11  * copy of this software and associated documentation files (the "Software"),
   12  * to deal in the Software without restriction, including without limitation
   13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   14  * and/or sell copies of the Software, and to permit persons to whom the
   15  * Software is furnished to do so, subject to the following conditions:
   16  *
   17  * The above copyright notice and this permission notice (including the next
   18  * paragraph) shall be included in all copies or substantial portions of the
   19  * Software.
   20  *
   21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   24  * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
   25  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   27  *
   28  * Authors:
   29  *    Gareth Hughes <gareth@valinux.com>
   30  *    Frank C. Earl <fearl@airmail.net>
   31  *    Leif Delgass <ldelgass@retinalburn.net>
   32  *    Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD: releng/6.4/sys/dev/drm/mach64_drv.h 153401 2005-12-14 00:52:59Z anholt $");
   37 
   38 #ifndef __MACH64_DRV_H__
   39 #define __MACH64_DRV_H__
   40 
   41 /* General customization:
   42  */
   43 
   44 #define DRIVER_AUTHOR           "Gareth Hughes, Leif Delgass, José Fonseca"
   45 
   46 #define DRIVER_NAME             "mach64"
   47 #define DRIVER_DESC             "DRM module for the ATI Rage Pro"
   48 #define DRIVER_DATE             "20020904"
   49 
   50 #define DRIVER_MAJOR            1
   51 #define DRIVER_MINOR            0
   52 #define DRIVER_PATCHLEVEL       0
   53 
   54 /* FIXME: remove these when not needed */
   55 /* Development driver options */
   56 #define MACH64_EXTRA_CHECKING     0     /* Extra sanity checks for DMA/freelist management */
   57 #define MACH64_VERBOSE            0     /* Verbose debugging output */
   58 
   59 typedef struct drm_mach64_freelist {
   60         struct list_head list;  /* List pointers for free_list, placeholders, or pending list */
   61         drm_buf_t *buf;         /* Pointer to the buffer */
   62         int discard;            /* This flag is set when we're done (re)using a buffer */
   63         u32 ring_ofs;           /* dword offset in ring of last descriptor for this buffer */
   64 } drm_mach64_freelist_t;
   65 
   66 typedef struct drm_mach64_descriptor_ring {
   67         drm_dma_handle_t *dmah; /* Handle to pci dma memory */
   68         void *start;            /* write pointer (cpu address) to start of descriptor ring */
   69         u32 start_addr;         /* bus address of beginning of descriptor ring */
   70         int size;               /* size of ring in bytes */
   71 
   72         u32 head_addr;          /* bus address of descriptor ring head */
   73         u32 head;               /* dword offset of descriptor ring head */
   74         u32 tail;               /* dword offset of descriptor ring tail */
   75         u32 tail_mask;          /* mask used to wrap ring */
   76         int space;              /* number of free bytes in ring */
   77 } drm_mach64_descriptor_ring_t;
   78 
   79 typedef struct drm_mach64_private {
   80         drm_mach64_sarea_t *sarea_priv;
   81 
   82         int is_pci;
   83         drm_mach64_dma_mode_t driver_mode;      /* Async DMA, sync DMA, or MMIO */
   84 
   85         int usec_timeout;       /* Timeout for the wait functions */
   86 
   87         drm_mach64_descriptor_ring_t ring;      /* DMA descriptor table (ring buffer) */
   88         int ring_running;       /* Is bus mastering is enabled */
   89 
   90         struct list_head free_list;     /* Free-list head */
   91         struct list_head placeholders;  /* Placeholder list for buffers held by clients */
   92         struct list_head pending;       /* Buffers pending completion */
   93 
   94         u32 frame_ofs[MACH64_MAX_QUEUED_FRAMES];        /* dword ring offsets of most recent frame swaps */
   95 
   96         unsigned int fb_bpp;
   97         unsigned int front_offset, front_pitch;
   98         unsigned int back_offset, back_pitch;
   99 
  100         unsigned int depth_bpp;
  101         unsigned int depth_offset, depth_pitch;
  102 
  103         u32 front_offset_pitch;
  104         u32 back_offset_pitch;
  105         u32 depth_offset_pitch;
  106 
  107         drm_local_map_t *sarea;
  108         drm_local_map_t *fb;
  109         drm_local_map_t *mmio;
  110         drm_local_map_t *ring_map;
  111         drm_local_map_t *dev_buffers;   /* this is a pointer to a structure in dev */
  112         drm_local_map_t *agp_textures;
  113 } drm_mach64_private_t;
  114 
  115 extern drm_ioctl_desc_t mach64_ioctls[];
  116 extern int mach64_max_ioctl;
  117 
  118                                 /* mach64_dma.c */
  119 extern int mach64_dma_init(DRM_IOCTL_ARGS);
  120 extern int mach64_dma_idle(DRM_IOCTL_ARGS);
  121 extern int mach64_dma_flush(DRM_IOCTL_ARGS);
  122 extern int mach64_engine_reset(DRM_IOCTL_ARGS);
  123 extern int mach64_dma_buffers(DRM_IOCTL_ARGS);
  124 extern void mach64_driver_lastclose(drm_device_t * dev);
  125 
  126 extern int mach64_init_freelist(drm_device_t * dev);
  127 extern void mach64_destroy_freelist(drm_device_t * dev);
  128 extern drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv);
  129 
  130 extern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv,
  131                                    int entries);
  132 extern int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv);
  133 extern int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n);
  134 extern int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv);
  135 extern int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv);
  136 extern void mach64_dump_engine_info(drm_mach64_private_t * dev_priv);
  137 extern void mach64_dump_ring_info(drm_mach64_private_t * dev_priv);
  138 extern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv);
  139 
  140 extern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv);
  141 extern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv);
  142 extern int mach64_do_cleanup_dma(drm_device_t * dev);
  143 
  144                                 /* mach64_state.c */
  145 extern int mach64_dma_clear(DRM_IOCTL_ARGS);
  146 extern int mach64_dma_swap(DRM_IOCTL_ARGS);
  147 extern int mach64_dma_vertex(DRM_IOCTL_ARGS);
  148 extern int mach64_dma_blit(DRM_IOCTL_ARGS);
  149 extern int mach64_get_param(DRM_IOCTL_ARGS);
  150 extern int mach64_driver_vblank_wait(drm_device_t * dev,
  151                                      unsigned int *sequence);
  152 
  153 extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS);
  154 extern void mach64_driver_irq_preinstall(drm_device_t * dev);
  155 extern void mach64_driver_irq_postinstall(drm_device_t * dev);
  156 extern void mach64_driver_irq_uninstall(drm_device_t * dev);
  157 
  158 /* ================================================================
  159  * Registers
  160  */
  161 
  162 #define MACH64_AGP_BASE                         0x0148
  163 #define MACH64_AGP_CNTL                         0x014c
  164 #define MACH64_ALPHA_TST_CNTL                   0x0550
  165 
  166 #define MACH64_DSP_CONFIG                       0x0420
  167 #define MACH64_DSP_ON_OFF                       0x0424
  168 #define MACH64_EXT_MEM_CNTL                     0x04ac
  169 #define MACH64_GEN_TEST_CNTL                    0x04d0
  170 #define MACH64_HW_DEBUG                         0x047c
  171 #define MACH64_MEM_ADDR_CONFIG                  0x0434
  172 #define MACH64_MEM_BUF_CNTL                     0x042c
  173 #define MACH64_MEM_CNTL                         0x04b0
  174 
  175 #define MACH64_BM_ADDR                          0x0648
  176 #define MACH64_BM_COMMAND                       0x0188
  177 #define MACH64_BM_DATA                          0x0648
  178 #define MACH64_BM_FRAME_BUF_OFFSET              0x0180
  179 #define MACH64_BM_GUI_TABLE                     0x01b8
  180 #define MACH64_BM_GUI_TABLE_CMD                 0x064c
  181 #       define MACH64_CIRCULAR_BUF_SIZE_16KB            (0 << 0)
  182 #       define MACH64_CIRCULAR_BUF_SIZE_32KB            (1 << 0)
  183 #       define MACH64_CIRCULAR_BUF_SIZE_64KB            (2 << 0)
  184 #       define MACH64_CIRCULAR_BUF_SIZE_128KB           (3 << 0)
  185 #       define MACH64_LAST_DESCRIPTOR                   (1 << 31)
  186 #define MACH64_BM_HOSTDATA                      0x0644
  187 #define MACH64_BM_STATUS                        0x018c
  188 #define MACH64_BM_SYSTEM_MEM_ADDR               0x0184
  189 #define MACH64_BM_SYSTEM_TABLE                  0x01bc
  190 #define MACH64_BUS_CNTL                         0x04a0
  191 #       define MACH64_BUS_MSTR_RESET                    (1 << 1)
  192 #       define MACH64_BUS_APER_REG_DIS                  (1 << 4)
  193 #       define MACH64_BUS_FLUSH_BUF                     (1 << 2)
  194 #       define MACH64_BUS_MASTER_DIS                    (1 << 6)
  195 #       define MACH64_BUS_EXT_REG_EN                    (1 << 27)
  196 
  197 #define MACH64_CLR_CMP_CLR                      0x0700
  198 #define MACH64_CLR_CMP_CNTL                     0x0708
  199 #define MACH64_CLR_CMP_MASK                     0x0704
  200 #define MACH64_CONFIG_CHIP_ID                   0x04e0
  201 #define MACH64_CONFIG_CNTL                      0x04dc
  202 #define MACH64_CONFIG_STAT0                     0x04e4
  203 #define MACH64_CONFIG_STAT1                     0x0494
  204 #define MACH64_CONFIG_STAT2                     0x0498
  205 #define MACH64_CONTEXT_LOAD_CNTL                0x072c
  206 #define MACH64_CONTEXT_MASK                     0x0720
  207 #define MACH64_COMPOSITE_SHADOW_ID              0x0798
  208 #define MACH64_CRC_SIG                          0x04e8
  209 #define MACH64_CUSTOM_MACRO_CNTL                0x04d4
  210 
  211 #define MACH64_DP_BKGD_CLR                      0x06c0
  212 #define MACH64_DP_FOG_CLR                       0x06c4
  213 #define MACH64_DP_FGRD_BKGD_CLR                 0x06e0
  214 #define MACH64_DP_FRGD_CLR                      0x06c4
  215 #define MACH64_DP_FGRD_CLR_MIX                  0x06dc
  216 
  217 #define MACH64_DP_MIX                           0x06d4
  218 #       define BKGD_MIX_NOT_D                           (0 << 0)
  219 #       define BKGD_MIX_ZERO                            (1 << 0)
  220 #       define BKGD_MIX_ONE                             (2 << 0)
  221 #       define MACH64_BKGD_MIX_D                        (3 << 0)
  222 #       define BKGD_MIX_NOT_S                           (4 << 0)
  223 #       define BKGD_MIX_D_XOR_S                         (5 << 0)
  224 #       define BKGD_MIX_NOT_D_XOR_S                     (6 << 0)
  225 #       define MACH64_BKGD_MIX_S                        (7 << 0)
  226 #       define BKGD_MIX_NOT_D_OR_NOT_S                  (8 << 0)
  227 #       define BKGD_MIX_D_OR_NOT_S                      (9 << 0)
  228 #       define BKGD_MIX_NOT_D_OR_S                      (10 << 0)
  229 #       define BKGD_MIX_D_OR_S                          (11 << 0)
  230 #       define BKGD_MIX_D_AND_S                         (12 << 0)
  231 #       define BKGD_MIX_NOT_D_AND_S                     (13 << 0)
  232 #       define BKGD_MIX_D_AND_NOT_S                     (14 << 0)
  233 #       define BKGD_MIX_NOT_D_AND_NOT_S                 (15 << 0)
  234 #       define BKGD_MIX_D_PLUS_S_DIV2                   (23 << 0)
  235 #       define FRGD_MIX_NOT_D                           (0 << 16)
  236 #       define FRGD_MIX_ZERO                            (1 << 16)
  237 #       define FRGD_MIX_ONE                             (2 << 16)
  238 #       define FRGD_MIX_D                               (3 << 16)
  239 #       define FRGD_MIX_NOT_S                           (4 << 16)
  240 #       define FRGD_MIX_D_XOR_S                         (5 << 16)
  241 #       define FRGD_MIX_NOT_D_XOR_S                     (6 << 16)
  242 #       define MACH64_FRGD_MIX_S                        (7 << 16)
  243 #       define FRGD_MIX_NOT_D_OR_NOT_S                  (8 << 16)
  244 #       define FRGD_MIX_D_OR_NOT_S                      (9 << 16)
  245 #       define FRGD_MIX_NOT_D_OR_S                      (10 << 16)
  246 #       define FRGD_MIX_D_OR_S                          (11 << 16)
  247 #       define FRGD_MIX_D_AND_S                         (12 << 16)
  248 #       define FRGD_MIX_NOT_D_AND_S                     (13 << 16)
  249 #       define FRGD_MIX_D_AND_NOT_S                     (14 << 16)
  250 #       define FRGD_MIX_NOT_D_AND_NOT_S                 (15 << 16)
  251 #       define FRGD_MIX_D_PLUS_S_DIV2                   (23 << 16)
  252 
  253 #define MACH64_DP_PIX_WIDTH                     0x06d0
  254 #       define MACH64_HOST_TRIPLE_ENABLE                (1 << 13)
  255 #       define MACH64_BYTE_ORDER_MSB_TO_LSB             (0 << 24)
  256 #       define MACH64_BYTE_ORDER_LSB_TO_MSB             (1 << 24)
  257 
  258 #define MACH64_DP_SRC                           0x06d8
  259 #       define MACH64_BKGD_SRC_BKGD_CLR                 (0 << 0)
  260 #       define MACH64_BKGD_SRC_FRGD_CLR                 (1 << 0)
  261 #       define MACH64_BKGD_SRC_HOST                     (2 << 0)
  262 #       define MACH64_BKGD_SRC_BLIT                     (3 << 0)
  263 #       define MACH64_BKGD_SRC_PATTERN                  (4 << 0)
  264 #       define MACH64_BKGD_SRC_3D                       (5 << 0)
  265 #       define MACH64_FRGD_SRC_BKGD_CLR                 (0 << 8)
  266 #       define MACH64_FRGD_SRC_FRGD_CLR                 (1 << 8)
  267 #       define MACH64_FRGD_SRC_HOST                     (2 << 8)
  268 #       define MACH64_FRGD_SRC_BLIT                     (3 << 8)
  269 #       define MACH64_FRGD_SRC_PATTERN                  (4 << 8)
  270 #       define MACH64_FRGD_SRC_3D                       (5 << 8)
  271 #       define MACH64_MONO_SRC_ONE                      (0 << 16)
  272 #       define MACH64_MONO_SRC_PATTERN                  (1 << 16)
  273 #       define MACH64_MONO_SRC_HOST                     (2 << 16)
  274 #       define MACH64_MONO_SRC_BLIT                     (3 << 16)
  275 
  276 #define MACH64_DP_WRITE_MASK                    0x06c8
  277 
  278 #define MACH64_DST_CNTL                         0x0530
  279 #       define MACH64_DST_X_RIGHT_TO_LEFT               (0 << 0)
  280 #       define MACH64_DST_X_LEFT_TO_RIGHT               (1 << 0)
  281 #       define MACH64_DST_Y_BOTTOM_TO_TOP               (0 << 1)
  282 #       define MACH64_DST_Y_TOP_TO_BOTTOM               (1 << 1)
  283 #       define MACH64_DST_X_MAJOR                       (0 << 2)
  284 #       define MACH64_DST_Y_MAJOR                       (1 << 2)
  285 #       define MACH64_DST_X_TILE                        (1 << 3)
  286 #       define MACH64_DST_Y_TILE                        (1 << 4)
  287 #       define MACH64_DST_LAST_PEL                      (1 << 5)
  288 #       define MACH64_DST_POLYGON_ENABLE                (1 << 6)
  289 #       define MACH64_DST_24_ROTATION_ENABLE            (1 << 7)
  290 
  291 #define MACH64_DST_HEIGHT_WIDTH                 0x0518
  292 #define MACH64_DST_OFF_PITCH                    0x0500
  293 #define MACH64_DST_WIDTH_HEIGHT                 0x06ec
  294 #define MACH64_DST_X_Y                          0x06e8
  295 #define MACH64_DST_Y_X                          0x050c
  296 
  297 #define MACH64_FIFO_STAT                        0x0710
  298 #       define MACH64_FIFO_SLOT_MASK                    0x0000ffff
  299 #       define MACH64_FIFO_ERR                          (1 << 31)
  300 
  301 #define MACH64_GEN_TEST_CNTL                    0x04d0
  302 #       define MACH64_GUI_ENGINE_ENABLE                 (1 << 8)
  303 #define MACH64_GUI_CMDFIFO_DEBUG                0x0170
  304 #define MACH64_GUI_CMDFIFO_DATA                 0x0174
  305 #define MACH64_GUI_CNTL                         0x0178
  306 #       define MACH64_CMDFIFO_SIZE_MASK                 0x00000003ul
  307 #       define MACH64_CMDFIFO_SIZE_192                  0x00000000ul
  308 #       define MACH64_CMDFIFO_SIZE_128                  0x00000001ul
  309 #       define MACH64_CMDFIFO_SIZE_64                   0x00000002ul
  310 #define MACH64_GUI_STAT                         0x0738
  311 #       define MACH64_GUI_ACTIVE                        (1 << 0)
  312 #define MACH64_GUI_TRAJ_CNTL                    0x0730
  313 
  314 #define MACH64_HOST_CNTL                        0x0640
  315 #define MACH64_HOST_DATA0                       0x0600
  316 
  317 #define MACH64_ONE_OVER_AREA                    0x029c
  318 #define MACH64_ONE_OVER_AREA_UC                 0x0300
  319 
  320 #define MACH64_PAT_REG0                         0x0680
  321 #define MACH64_PAT_REG1                         0x0684
  322 
  323 #define MACH64_SC_LEFT                          0x06a0
  324 #define MACH64_SC_RIGHT                         0x06a4
  325 #define MACH64_SC_LEFT_RIGHT                    0x06a8
  326 #define MACH64_SC_TOP                           0x06ac
  327 #define MACH64_SC_BOTTOM                        0x06b0
  328 #define MACH64_SC_TOP_BOTTOM                    0x06b4
  329 
  330 #define MACH64_SCALE_3D_CNTL                    0x05fc
  331 #define MACH64_SCRATCH_REG0                     0x0480
  332 #define MACH64_SCRATCH_REG1                     0x0484
  333 #define MACH64_SECONDARY_TEX_OFF                0x0778
  334 #define MACH64_SETUP_CNTL                       0x0304
  335 #define MACH64_SRC_CNTL                         0x05b4
  336 #       define MACH64_SRC_BM_ENABLE                     (1 << 8)
  337 #       define MACH64_SRC_BM_SYNC                       (1 << 9)
  338 #       define MACH64_SRC_BM_OP_FRAME_TO_SYSTEM         (0 << 10)
  339 #       define MACH64_SRC_BM_OP_SYSTEM_TO_FRAME         (1 << 10)
  340 #       define MACH64_SRC_BM_OP_REG_TO_SYSTEM           (2 << 10)
  341 #       define MACH64_SRC_BM_OP_SYSTEM_TO_REG           (3 << 10)
  342 #define MACH64_SRC_HEIGHT1                      0x0594
  343 #define MACH64_SRC_HEIGHT2                      0x05ac
  344 #define MACH64_SRC_HEIGHT1_WIDTH1               0x0598
  345 #define MACH64_SRC_HEIGHT2_WIDTH2               0x05b0
  346 #define MACH64_SRC_OFF_PITCH                    0x0580
  347 #define MACH64_SRC_WIDTH1                       0x0590
  348 #define MACH64_SRC_Y_X                          0x058c
  349 
  350 #define MACH64_TEX_0_OFF                        0x05c0
  351 #define MACH64_TEX_CNTL                         0x0774
  352 #define MACH64_TEX_SIZE_PITCH                   0x0770
  353 #define MACH64_TIMER_CONFIG                     0x0428
  354 
  355 #define MACH64_VERTEX_1_ARGB                    0x0254
  356 #define MACH64_VERTEX_1_S                       0x0240
  357 #define MACH64_VERTEX_1_SECONDARY_S             0x0328
  358 #define MACH64_VERTEX_1_SECONDARY_T             0x032c
  359 #define MACH64_VERTEX_1_SECONDARY_W             0x0330
  360 #define MACH64_VERTEX_1_SPEC_ARGB               0x024c
  361 #define MACH64_VERTEX_1_T                       0x0244
  362 #define MACH64_VERTEX_1_W                       0x0248
  363 #define MACH64_VERTEX_1_X_Y                     0x0258
  364 #define MACH64_VERTEX_1_Z                       0x0250
  365 #define MACH64_VERTEX_2_ARGB                    0x0274
  366 #define MACH64_VERTEX_2_S                       0x0260
  367 #define MACH64_VERTEX_2_SECONDARY_S             0x0334
  368 #define MACH64_VERTEX_2_SECONDARY_T             0x0338
  369 #define MACH64_VERTEX_2_SECONDARY_W             0x033c
  370 #define MACH64_VERTEX_2_SPEC_ARGB               0x026c
  371 #define MACH64_VERTEX_2_T                       0x0264
  372 #define MACH64_VERTEX_2_W                       0x0268
  373 #define MACH64_VERTEX_2_X_Y                     0x0278
  374 #define MACH64_VERTEX_2_Z                       0x0270
  375 #define MACH64_VERTEX_3_ARGB                    0x0294
  376 #define MACH64_VERTEX_3_S                       0x0280
  377 #define MACH64_VERTEX_3_SECONDARY_S             0x02a0
  378 #define MACH64_VERTEX_3_SECONDARY_T             0x02a4
  379 #define MACH64_VERTEX_3_SECONDARY_W             0x02a8
  380 #define MACH64_VERTEX_3_SPEC_ARGB               0x028c
  381 #define MACH64_VERTEX_3_T                       0x0284
  382 #define MACH64_VERTEX_3_W                       0x0288
  383 #define MACH64_VERTEX_3_X_Y                     0x0298
  384 #define MACH64_VERTEX_3_Z                       0x0290
  385 
  386 #define MACH64_Z_CNTL                           0x054c
  387 #define MACH64_Z_OFF_PITCH                      0x0548
  388 
  389 #define MACH64_CRTC_VLINE_CRNT_VLINE            0x0410
  390 #       define MACH64_CRTC_VLINE_MASK                   0x000007ff
  391 #       define MACH64_CRTC_CRNT_VLINE_MASK              0x07ff0000
  392 #define MACH64_CRTC_OFF_PITCH                   0x0414
  393 #define MACH64_CRTC_INT_CNTL                    0x0418
  394 #       define MACH64_CRTC_VBLANK                       (1 << 0)
  395 #       define MACH64_CRTC_VBLANK_INT_EN                (1 << 1)
  396 #       define MACH64_CRTC_VBLANK_INT                   (1 << 2)
  397 #       define MACH64_CRTC_VLINE_INT_EN                 (1 << 3)
  398 #       define MACH64_CRTC_VLINE_INT                    (1 << 4)
  399 #       define MACH64_CRTC_VLINE_SYNC                   (1 << 5)        /* 0=even, 1=odd */
  400 #       define MACH64_CRTC_FRAME                        (1 << 6)        /* 0=even, 1=odd */
  401 #       define MACH64_CRTC_SNAPSHOT_INT_EN              (1 << 7)
  402 #       define MACH64_CRTC_SNAPSHOT_INT                 (1 << 8)
  403 #       define MACH64_CRTC_I2C_INT_EN                   (1 << 9)
  404 #       define MACH64_CRTC_I2C_INT                      (1 << 10)
  405 #       define MACH64_CRTC2_VBLANK                      (1 << 11)       /* LT Pro */
  406 #       define MACH64_CRTC2_VBLANK_INT_EN               (1 << 12)       /* LT Pro */
  407 #       define MACH64_CRTC2_VBLANK_INT                  (1 << 13)       /* LT Pro */
  408 #       define MACH64_CRTC2_VLINE_INT_EN                (1 << 14)       /* LT Pro */
  409 #       define MACH64_CRTC2_VLINE_INT                   (1 << 15)       /* LT Pro */
  410 #       define MACH64_CRTC_CAPBUF0_INT_EN               (1 << 16)
  411 #       define MACH64_CRTC_CAPBUF0_INT                  (1 << 17)
  412 #       define MACH64_CRTC_CAPBUF1_INT_EN               (1 << 18)
  413 #       define MACH64_CRTC_CAPBUF1_INT                  (1 << 19)
  414 #       define MACH64_CRTC_OVERLAY_EOF_INT_EN           (1 << 20)
  415 #       define MACH64_CRTC_OVERLAY_EOF_INT              (1 << 21)
  416 #       define MACH64_CRTC_ONESHOT_CAP_INT_EN           (1 << 22)
  417 #       define MACH64_CRTC_ONESHOT_CAP_INT              (1 << 23)
  418 #       define MACH64_CRTC_BUSMASTER_EOL_INT_EN         (1 << 24)
  419 #       define MACH64_CRTC_BUSMASTER_EOL_INT            (1 << 25)
  420 #       define MACH64_CRTC_GP_INT_EN                    (1 << 26)
  421 #       define MACH64_CRTC_GP_INT                       (1 << 27)
  422 #       define MACH64_CRTC2_VLINE_SYNC                  (1 << 28) /* LT Pro */  /* 0=even, 1=odd */
  423 #       define MACH64_CRTC_SNAPSHOT2_INT_EN             (1 << 29)       /* LT Pro */
  424 #       define MACH64_CRTC_SNAPSHOT2_INT                (1 << 30)       /* LT Pro */
  425 #       define MACH64_CRTC_VBLANK2_INT                  (1 << 31)
  426 #       define MACH64_CRTC_INT_ENS                              \
  427                 (                                               \
  428                         MACH64_CRTC_VBLANK_INT_EN |             \
  429                         MACH64_CRTC_VLINE_INT_EN |              \
  430                         MACH64_CRTC_SNAPSHOT_INT_EN |           \
  431                         MACH64_CRTC_I2C_INT_EN |                \
  432                         MACH64_CRTC2_VBLANK_INT_EN |            \
  433                         MACH64_CRTC2_VLINE_INT_EN |             \
  434                         MACH64_CRTC_CAPBUF0_INT_EN |            \
  435                         MACH64_CRTC_CAPBUF1_INT_EN |            \
  436                         MACH64_CRTC_OVERLAY_EOF_INT_EN |        \
  437                         MACH64_CRTC_ONESHOT_CAP_INT_EN |        \
  438                         MACH64_CRTC_BUSMASTER_EOL_INT_EN |      \
  439                         MACH64_CRTC_GP_INT_EN |                 \
  440                         MACH64_CRTC_SNAPSHOT2_INT_EN |          \
  441                         0                                       \
  442                 )
  443 #       define MACH64_CRTC_INT_ACKS                     \
  444                 (                                       \
  445                         MACH64_CRTC_VBLANK_INT |        \
  446                         MACH64_CRTC_VLINE_INT |         \
  447                         MACH64_CRTC_SNAPSHOT_INT |      \
  448                         MACH64_CRTC_I2C_INT |           \
  449                         MACH64_CRTC2_VBLANK_INT |       \
  450                         MACH64_CRTC2_VLINE_INT |        \
  451                         MACH64_CRTC_CAPBUF0_INT |       \
  452                         MACH64_CRTC_CAPBUF1_INT |       \
  453                         MACH64_CRTC_OVERLAY_EOF_INT |   \
  454                         MACH64_CRTC_ONESHOT_CAP_INT |   \
  455                         MACH64_CRTC_BUSMASTER_EOL_INT | \
  456                         MACH64_CRTC_GP_INT |            \
  457                         MACH64_CRTC_SNAPSHOT2_INT |     \
  458                         MACH64_CRTC_VBLANK2_INT |       \
  459                         0                               \
  460                 )
  461 
  462 #define MACH64_DATATYPE_CI8                             2
  463 #define MACH64_DATATYPE_ARGB1555                        3
  464 #define MACH64_DATATYPE_RGB565                          4
  465 #define MACH64_DATATYPE_ARGB8888                        6
  466 #define MACH64_DATATYPE_RGB332                          7
  467 #define MACH64_DATATYPE_Y8                              8
  468 #define MACH64_DATATYPE_RGB8                            9
  469 #define MACH64_DATATYPE_VYUY422                         11
  470 #define MACH64_DATATYPE_YVYU422                         12
  471 #define MACH64_DATATYPE_AYUV444                         14
  472 #define MACH64_DATATYPE_ARGB4444                        15
  473 
  474 #define MACH64_READ(reg)        DRM_READ32(dev_priv->mmio, (reg) )
  475 #define MACH64_WRITE(reg,val)   DRM_WRITE32(dev_priv->mmio, (reg), (val) )
  476 
  477 #define DWMREG0         0x0400
  478 #define DWMREG0_END     0x07ff
  479 #define DWMREG1         0x0000
  480 #define DWMREG1_END     0x03ff
  481 
  482 #define ISREG0(r)       (((r) >= DWMREG0) && ((r) <= DWMREG0_END))
  483 #define DMAREG0(r)      (((r) - DWMREG0) >> 2)
  484 #define DMAREG1(r)      ((((r) - DWMREG1) >> 2 ) | 0x0100)
  485 #define DMAREG(r)       (ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
  486 
  487 #define MMREG0          0x0000
  488 #define MMREG0_END      0x00ff
  489 
  490 #define ISMMREG0(r)     (((r) >= MMREG0) && ((r) <= MMREG0_END))
  491 #define MMSELECT0(r)    (((r) << 2) + DWMREG0)
  492 #define MMSELECT1(r)    (((((r) & 0xff) << 2) + DWMREG1))
  493 #define MMSELECT(r)     (ISMMREG0(r) ? MMSELECT0(r) : MMSELECT1(r))
  494 
  495 /* ================================================================
  496  * DMA constants
  497  */
  498 
  499 /* DMA descriptor field indices:
  500  * The descriptor fields are loaded into the read-only
  501  * BM_* system bus master registers during a bus-master operation
  502  */
  503 #define MACH64_DMA_FRAME_BUF_OFFSET     0       /* BM_FRAME_BUF_OFFSET */
  504 #define MACH64_DMA_SYS_MEM_ADDR         1       /* BM_SYSTEM_MEM_ADDR */
  505 #define MACH64_DMA_COMMAND              2       /* BM_COMMAND */
  506 #define MACH64_DMA_RESERVED             3       /* BM_STATUS */
  507 
  508 /* BM_COMMAND descriptor field flags */
  509 #define MACH64_DMA_HOLD_OFFSET          (1<<30) /* Don't increment DMA_FRAME_BUF_OFFSET */
  510 #define MACH64_DMA_EOL                  (1<<31) /* End of descriptor list flag */
  511 
  512 #define MACH64_DMA_CHUNKSIZE            0x1000  /* 4kB per DMA descriptor */
  513 #define MACH64_APERTURE_OFFSET          0x7ff800        /* frame-buffer offset for gui-masters */
  514 
  515 /* ================================================================
  516  * Misc helper macros
  517  */
  518 
  519 static __inline__ void mach64_set_dma_eol(volatile u32 * addr)
  520 {
  521 #if defined(__i386__)
  522         int nr = 31;
  523 
  524         /* Taken from include/asm-i386/bitops.h linux header */
  525         __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr)
  526                              :"Ir"(nr));
  527 #elif defined(__powerpc__)
  528         u32 old;
  529         u32 mask = cpu_to_le32(MACH64_DMA_EOL);
  530 
  531         /* Taken from the include/asm-ppc/bitops.h linux header */
  532         __asm__ __volatile__("\n\
  533 1:      lwarx   %0,0,%3 \n\
  534         or      %0,%0,%2 \n\
  535         stwcx.  %0,0,%3 \n\
  536         bne-    1b":"=&r"(old), "=m"(*addr)
  537                              :"r"(mask), "r"(addr), "m"(*addr)
  538                              :"cc");
  539 #elif defined(__alpha__)
  540         u32 temp;
  541         u32 mask = MACH64_DMA_EOL;
  542 
  543         /* Taken from the include/asm-alpha/bitops.h linux header */
  544         __asm__ __volatile__("1:        ldl_l %0,%3\n"
  545                              "  bis %0,%2,%0\n"
  546                              "  stl_c %0,%1\n"
  547                              "  beq %0,2f\n"
  548                              ".subsection 2\n"
  549                              "2:        br 1b\n"
  550                              ".previous":"=&r"(temp), "=m"(*addr)
  551                              :"Ir"(mask), "m"(*addr));
  552 #else
  553         u32 mask = cpu_to_le32(MACH64_DMA_EOL);
  554 
  555         *addr |= mask;
  556 #endif
  557 }
  558 
  559 static __inline__ void mach64_clear_dma_eol(volatile u32 * addr)
  560 {
  561 #if defined(__i386__)
  562         int nr = 31;
  563 
  564         /* Taken from include/asm-i386/bitops.h linux header */
  565         __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr)
  566                              :"Ir"(nr));
  567 #elif defined(__powerpc__)
  568         u32 old;
  569         u32 mask = cpu_to_le32(MACH64_DMA_EOL);
  570 
  571         /* Taken from the include/asm-ppc/bitops.h linux header */
  572         __asm__ __volatile__("\n\
  573 1:      lwarx   %0,0,%3 \n\
  574         andc    %0,%0,%2 \n\
  575         stwcx.  %0,0,%3 \n\
  576         bne-    1b":"=&r"(old), "=m"(*addr)
  577                              :"r"(mask), "r"(addr), "m"(*addr)
  578                              :"cc");
  579 #elif defined(__alpha__)
  580         u32 temp;
  581         u32 mask = ~MACH64_DMA_EOL;
  582 
  583         /* Taken from the include/asm-alpha/bitops.h linux header */
  584         __asm__ __volatile__("1:        ldl_l %0,%3\n"
  585                              "  and %0,%2,%0\n"
  586                              "  stl_c %0,%1\n"
  587                              "  beq %0,2f\n"
  588                              ".subsection 2\n"
  589                              "2:        br 1b\n"
  590                              ".previous":"=&r"(temp), "=m"(*addr)
  591                              :"Ir"(mask), "m"(*addr));
  592 #else
  593         u32 mask = cpu_to_le32(~MACH64_DMA_EOL);
  594 
  595         *addr &= mask;
  596 #endif
  597 }
  598 
  599 static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv)
  600 {
  601         drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
  602 
  603         DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
  604                   __FUNCTION__,
  605                   ring->head_addr, ring->head, ring->tail, ring->space);
  606 
  607         if (mach64_do_wait_for_idle(dev_priv) < 0) {
  608                 mach64_do_engine_reset(dev_priv);
  609         }
  610 
  611         if (dev_priv->driver_mode != MACH64_MODE_MMIO) {
  612                 /* enable bus mastering and block 1 registers */
  613                 MACH64_WRITE(MACH64_BUS_CNTL,
  614                              (MACH64_READ(MACH64_BUS_CNTL) &
  615                               ~MACH64_BUS_MASTER_DIS)
  616                              | MACH64_BUS_EXT_REG_EN);
  617                 mach64_do_wait_for_idle(dev_priv);
  618         }
  619 
  620         /* reset descriptor table ring head */
  621         MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
  622                      ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
  623 
  624         dev_priv->ring_running = 1;
  625 }
  626 
  627 static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
  628                                           drm_mach64_descriptor_ring_t * ring)
  629 {
  630         DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
  631                   __FUNCTION__,
  632                   ring->head_addr, ring->head, ring->tail, ring->space);
  633 
  634         /* reset descriptor table ring head */
  635         MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
  636                      ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
  637 
  638         if (dev_priv->driver_mode == MACH64_MODE_MMIO) {
  639                 mach64_do_dispatch_pseudo_dma(dev_priv);
  640         } else {
  641                 /* enable GUI bus mastering, and sync the bus master to the GUI */
  642                 MACH64_WRITE(MACH64_SRC_CNTL,
  643                              MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC |
  644                              MACH64_SRC_BM_OP_SYSTEM_TO_REG);
  645 
  646                 /* kick off the transfer */
  647                 MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0);
  648                 if (dev_priv->driver_mode == MACH64_MODE_DMA_SYNC) {
  649                         if ((mach64_do_wait_for_idle(dev_priv)) < 0) {
  650                                 DRM_ERROR("%s: idle failed, resetting engine\n",
  651                                           __FUNCTION__);
  652                                 mach64_dump_engine_info(dev_priv);
  653                                 mach64_do_engine_reset(dev_priv);
  654                                 return;
  655                         }
  656                         mach64_do_release_used_buffers(dev_priv);
  657                 }
  658         }
  659 }
  660 
  661 static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv,
  662                                         drm_mach64_descriptor_ring_t * ring)
  663 {
  664         DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
  665                   __FUNCTION__,
  666                   ring->head_addr, ring->head, ring->tail, ring->space);
  667 
  668         if (!dev_priv->ring_running) {
  669                 mach64_ring_start(dev_priv);
  670 
  671                 if (ring->head != ring->tail) {
  672                         mach64_ring_resume(dev_priv, ring);
  673                 }
  674         } else {
  675                 /* GUI_ACTIVE must be read before BM_GUI_TABLE to
  676                  * correctly determine the ring head
  677                  */
  678                 int gui_active =
  679                     MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE;
  680 
  681                 ring->head_addr = MACH64_READ(MACH64_BM_GUI_TABLE) & 0xfffffff0;
  682 
  683                 if (gui_active) {
  684                         /* If not idle, BM_GUI_TABLE points one descriptor
  685                          * past the current head
  686                          */
  687                         if (ring->head_addr == ring->start_addr) {
  688                                 ring->head_addr += ring->size;
  689                         }
  690                         ring->head_addr -= 4 * sizeof(u32);
  691                 }
  692 
  693                 if (ring->head_addr < ring->start_addr ||
  694                     ring->head_addr >= ring->start_addr + ring->size) {
  695                         DRM_ERROR("bad ring head address: 0x%08x\n",
  696                                   ring->head_addr);
  697                         mach64_dump_ring_info(dev_priv);
  698                         mach64_do_engine_reset(dev_priv);
  699                         return;
  700                 }
  701 
  702                 ring->head = (ring->head_addr - ring->start_addr) / sizeof(u32);
  703 
  704                 if (!gui_active && ring->head != ring->tail) {
  705                         mach64_ring_resume(dev_priv, ring);
  706                 }
  707         }
  708 }
  709 
  710 static __inline__ void mach64_ring_stop(drm_mach64_private_t * dev_priv)
  711 {
  712         DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
  713                   __FUNCTION__,
  714                   dev_priv->ring.head_addr, dev_priv->ring.head,
  715                   dev_priv->ring.tail, dev_priv->ring.space);
  716 
  717         /* restore previous SRC_CNTL to disable busmastering */
  718         mach64_do_wait_for_fifo(dev_priv, 1);
  719         MACH64_WRITE(MACH64_SRC_CNTL, 0);
  720 
  721         /* disable busmastering but keep the block 1 registers enabled */
  722         mach64_do_wait_for_idle(dev_priv);
  723         MACH64_WRITE(MACH64_BUS_CNTL, MACH64_READ(MACH64_BUS_CNTL)
  724                      | MACH64_BUS_MASTER_DIS | MACH64_BUS_EXT_REG_EN);
  725 
  726         dev_priv->ring_running = 0;
  727 }
  728 
  729 static __inline__ void
  730 mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv)
  731 {
  732         drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
  733 
  734         DRM_DEBUG("%s\n", __FUNCTION__);
  735 
  736         mach64_ring_tick(dev_priv, ring);
  737 
  738         ring->space = (ring->head - ring->tail) * sizeof(u32);
  739         if (ring->space <= 0) {
  740                 ring->space += ring->size;
  741         }
  742 }
  743 
  744 /* ================================================================
  745  * DMA descriptor ring macros
  746  */
  747 
  748 #define RING_LOCALS                                                                     \
  749         int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring
  750 
  751 #define RING_WRITE_OFS  _ring_write
  752 
  753 #define BEGIN_RING( n )                                                                 \
  754 do {                                                                                    \
  755         if ( MACH64_VERBOSE ) {                                                         \
  756                 DRM_INFO( "BEGIN_RING( %d ) in %s\n",                                   \
  757                            (n), __FUNCTION__ );                                         \
  758         }                                                                               \
  759         if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {                              \
  760                 int ret;                                                                \
  761                 if ((ret=mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) {        \
  762                         DRM_ERROR( "wait_ring failed, resetting engine\n");             \
  763                         mach64_dump_engine_info( dev_priv );                            \
  764                         mach64_do_engine_reset( dev_priv );                             \
  765                         return ret;                                                     \
  766                 }                                                                       \
  767         }                                                                               \
  768         dev_priv->ring.space -= (n) * sizeof(u32);                                      \
  769         _ring = (u32 *) dev_priv->ring.start;                                           \
  770         _ring_tail = _ring_write = dev_priv->ring.tail;                                 \
  771         _ring_mask = dev_priv->ring.tail_mask;                                          \
  772 } while (0)
  773 
  774 #define OUT_RING( x )                                           \
  775 do {                                                            \
  776         if ( MACH64_VERBOSE ) {                                 \
  777                 DRM_INFO( "   OUT_RING( 0x%08x ) at 0x%x\n",    \
  778                            (unsigned int)(x), _ring_write );    \
  779         }                                                       \
  780         _ring[_ring_write++] = cpu_to_le32( x );                \
  781         _ring_write &= _ring_mask;                              \
  782 } while (0)
  783 
  784 #define ADVANCE_RING()                                                  \
  785 do {                                                                    \
  786         if ( MACH64_VERBOSE ) {                                         \
  787                 DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",     \
  788                           _ring_write, _ring_tail );                    \
  789         }                                                               \
  790         DRM_MEMORYBARRIER();                                            \
  791         mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] );  \
  792         DRM_MEMORYBARRIER();                                            \
  793         dev_priv->ring.tail = _ring_write;                              \
  794         mach64_ring_tick( dev_priv, &(dev_priv)->ring );                \
  795 } while (0)
  796 
  797 /* ================================================================
  798  * DMA macros
  799  */
  800 
  801 #define DMALOCALS                               \
  802         drm_mach64_freelist_t *_entry = NULL;   \
  803         drm_buf_t *_buf = NULL;                 \
  804         u32 *_buf_wptr; int _outcount
  805 
  806 #define GETBUFPTR( __buf )                                              \
  807 ((dev_priv->is_pci) ?                                                   \
  808         ((u32 *)(__buf)->address) :                                     \
  809         ((u32 *)((char *)dev_priv->dev_buffers->handle + (__buf)->offset)))
  810 
  811 #define GETBUFADDR( __buf ) ((u32)(__buf)->bus_address)
  812 
  813 #define GETRINGOFFSET() (_entry->ring_ofs)
  814 
  815 static __inline__ int mach64_find_pending_buf_entry(drm_mach64_private_t *
  816                                                     dev_priv,
  817                                                     drm_mach64_freelist_t **
  818                                                     entry, drm_buf_t * buf)
  819 {
  820         struct list_head *ptr;
  821 #if MACH64_EXTRA_CHECKING
  822         if (list_empty(&dev_priv->pending)) {
  823                 DRM_ERROR("Empty pending list in %s\n", __FUNCTION__);
  824                 return DRM_ERR(EINVAL);
  825         }
  826 #endif
  827         ptr = dev_priv->pending.prev;
  828         *entry = list_entry(ptr, drm_mach64_freelist_t, list);
  829         while ((*entry)->buf != buf) {
  830                 if (ptr == &dev_priv->pending) {
  831                         return DRM_ERR(EFAULT);
  832                 }
  833                 ptr = ptr->prev;
  834                 *entry = list_entry(ptr, drm_mach64_freelist_t, list);
  835         }
  836         return 0;
  837 }
  838 
  839 #define DMASETPTR( _p )                         \
  840 do {                                            \
  841         _buf = (_p);                            \
  842         _outcount = 0;                          \
  843         _buf_wptr = GETBUFPTR( _buf );          \
  844 } while(0)
  845 
  846 /* FIXME: use a private set of smaller buffers for state emits, clears, and swaps? */
  847 #define DMAGETPTR( filp, dev_priv, n )                                  \
  848 do {                                                                    \
  849         if ( MACH64_VERBOSE ) {                                         \
  850                 DRM_INFO( "DMAGETPTR( %d ) in %s\n",                    \
  851                           n, __FUNCTION__ );                            \
  852         }                                                               \
  853         _buf = mach64_freelist_get( dev_priv );                         \
  854         if (_buf == NULL) {                                             \
  855                 DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n",     \
  856                            __FUNCTION__ );                              \
  857                 return DRM_ERR(EAGAIN);                                 \
  858         }                                                               \
  859         if (_buf->pending) {                                            \
  860                 DRM_ERROR("%s: pending buf in DMAGETPTR\n",             \
  861                            __FUNCTION__ );                              \
  862                 return DRM_ERR(EFAULT);                                 \
  863         }                                                               \
  864         _buf->filp = filp;                                              \
  865         _outcount = 0;                                                  \
  866                                                                         \
  867         _buf_wptr = GETBUFPTR( _buf );                                  \
  868 } while (0)
  869 
  870 #define DMAOUTREG( reg, val )                                   \
  871 do {                                                            \
  872         if ( MACH64_VERBOSE ) {                                 \
  873                 DRM_INFO( "   DMAOUTREG( 0x%x = 0x%08x )\n",    \
  874                           reg, val );                           \
  875         }                                                       \
  876         _buf_wptr[_outcount++] = cpu_to_le32(DMAREG(reg));      \
  877         _buf_wptr[_outcount++] = cpu_to_le32((val));            \
  878         _buf->used += 8;                                        \
  879 } while (0)
  880 
  881 #define DMAADVANCE( dev_priv, _discard )                                                     \
  882 do {                                                                                         \
  883         struct list_head *ptr;                                                               \
  884         RING_LOCALS;                                                                         \
  885                                                                                              \
  886         if ( MACH64_VERBOSE ) {                                                              \
  887                 DRM_INFO( "DMAADVANCE() in %s\n", __FUNCTION__ );                            \
  888         }                                                                                    \
  889                                                                                              \
  890         if (_buf->used <= 0) {                                                               \
  891                 DRM_ERROR( "DMAADVANCE() in %s: sending empty buf %d\n",                     \
  892                                    __FUNCTION__, _buf->idx );                                \
  893                 return DRM_ERR(EFAULT);                                                      \
  894         }                                                                                    \
  895         if (_buf->pending) {                                                                 \
  896                 /* This is a resued buffer, so we need to find it in the pending list */     \
  897                 int ret;                                                                     \
  898                 if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) {        \
  899                         DRM_ERROR( "DMAADVANCE() in %s: couldn't find pending buf %d\n",     \
  900                                    __FUNCTION__, _buf->idx );                                \
  901                         return ret;                                                          \
  902                 }                                                                            \
  903                 if (_entry->discard) {                                                       \
  904                         DRM_ERROR( "DMAADVANCE() in %s: sending discarded pending buf %d\n", \
  905                                    __FUNCTION__, _buf->idx );                                \
  906                         return DRM_ERR(EFAULT);                                              \
  907                 }                                                                            \
  908         } else {                                                                             \
  909                 if (list_empty(&dev_priv->placeholders)) {                                   \
  910                         DRM_ERROR( "DMAADVANCE() in %s: empty placeholder list\n",           \
  911                                 __FUNCTION__ );                                              \
  912                         return DRM_ERR(EFAULT);                                              \
  913                 }                                                                            \
  914                 ptr = dev_priv->placeholders.next;                                           \
  915                 list_del(ptr);                                                               \
  916                 _entry = list_entry(ptr, drm_mach64_freelist_t, list);                       \
  917                 _buf->pending = 1;                                                           \
  918                 _entry->buf = _buf;                                                          \
  919                 list_add_tail(ptr, &dev_priv->pending);                                      \
  920         }                                                                                    \
  921         _entry->discard = (_discard);                                                        \
  922         ADD_BUF_TO_RING( dev_priv );                                                         \
  923 } while (0)
  924 
  925 #define DMADISCARDBUF()                                                                 \
  926 do {                                                                                    \
  927         if (_entry == NULL) {                                                           \
  928                 int ret;                                                                \
  929                 if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) {   \
  930                         DRM_ERROR( "%s: couldn't find pending buf %d\n",                \
  931                                    __FUNCTION__, _buf->idx );                           \
  932                         return ret;                                                     \
  933                 }                                                                       \
  934         }                                                                               \
  935         _entry->discard = 1;                                                            \
  936 } while(0)
  937 
  938 #define ADD_BUF_TO_RING( dev_priv )                                                     \
  939 do {                                                                                    \
  940         int bytes, pages, remainder;                                                    \
  941         u32 address, page;                                                              \
  942         int i;                                                                          \
  943                                                                                         \
  944         bytes = _buf->used;                                                             \
  945         address = GETBUFADDR( _buf );                                                   \
  946                                                                                         \
  947         pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;              \
  948                                                                                         \
  949         BEGIN_RING( pages * 4 );                                                        \
  950                                                                                         \
  951         for ( i = 0 ; i < pages-1 ; i++ ) {                                             \
  952                 page = address + i * MACH64_DMA_CHUNKSIZE;                              \
  953                 OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );                    \
  954                 OUT_RING( page );                                                       \
  955                 OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );              \
  956                 OUT_RING( 0 );                                                          \
  957         }                                                                               \
  958                                                                                         \
  959         /* generate the final descriptor for any remaining commands in this buffer */   \
  960         page = address + i * MACH64_DMA_CHUNKSIZE;                                      \
  961         remainder = bytes - i * MACH64_DMA_CHUNKSIZE;                                   \
  962                                                                                         \
  963         /* Save dword offset of last descriptor for this buffer.                        \
  964          * This is needed to check for completion of the buffer in freelist_get         \
  965          */                                                                             \
  966         _entry->ring_ofs = RING_WRITE_OFS;                                              \
  967                                                                                         \
  968         OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );                            \
  969         OUT_RING( page );                                                               \
  970         OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );                \
  971         OUT_RING( 0 );                                                                  \
  972                                                                                         \
  973         ADVANCE_RING();                                                                 \
  974 } while(0)
  975 
  976 #define DMAADVANCEHOSTDATA( dev_priv )                                                  \
  977 do {                                                                                    \
  978         struct list_head *ptr;                                                          \
  979         RING_LOCALS;                                                                    \
  980                                                                                         \
  981         if ( MACH64_VERBOSE ) {                                                         \
  982                 DRM_INFO( "DMAADVANCEHOSTDATA() in %s\n", __FUNCTION__ );               \
  983         }                                                                               \
  984                                                                                         \
  985         if (_buf->used <= 0) {                                                          \
  986                 DRM_ERROR( "DMAADVANCEHOSTDATA() in %s: sending empty buf %d\n",        \
  987                                    __FUNCTION__, _buf->idx );                           \
  988                 return DRM_ERR(EFAULT);                                                 \
  989         }                                                                               \
  990         if (list_empty(&dev_priv->placeholders)) {                                      \
  991                 DRM_ERROR( "%s: empty placeholder list in DMAADVANCEHOSTDATA()\n",      \
  992                            __FUNCTION__ );                                              \
  993                 return DRM_ERR(EFAULT);                                                 \
  994         }                                                                               \
  995                                                                                         \
  996         ptr = dev_priv->placeholders.next;                                              \
  997         list_del(ptr);                                                                  \
  998         _entry = list_entry(ptr, drm_mach64_freelist_t, list);                          \
  999         _entry->buf = _buf;                                                             \
 1000         _entry->buf->pending = 1;                                                       \
 1001         list_add_tail(ptr, &dev_priv->pending);                                         \
 1002         _entry->discard = 1;                                                            \
 1003         ADD_HOSTDATA_BUF_TO_RING( dev_priv );                                           \
 1004 } while (0)
 1005 
 1006 #define ADD_HOSTDATA_BUF_TO_RING( dev_priv )                                             \
 1007 do {                                                                                     \
 1008         int bytes, pages, remainder;                                                     \
 1009         u32 address, page;                                                               \
 1010         int i;                                                                           \
 1011                                                                                          \
 1012         bytes = _buf->used - MACH64_HOSTDATA_BLIT_OFFSET;                                \
 1013         pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;               \
 1014         address = GETBUFADDR( _buf );                                                    \
 1015                                                                                          \
 1016         BEGIN_RING( 4 + pages * 4 );                                                     \
 1017                                                                                          \
 1018         OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );                             \
 1019         OUT_RING( address );                                                             \
 1020         OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET );                \
 1021         OUT_RING( 0 );                                                                   \
 1022                                                                                          \
 1023         address += MACH64_HOSTDATA_BLIT_OFFSET;                                          \
 1024                                                                                          \
 1025         for ( i = 0 ; i < pages-1 ; i++ ) {                                              \
 1026                 page = address + i * MACH64_DMA_CHUNKSIZE;                               \
 1027                 OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );                 \
 1028                 OUT_RING( page );                                                        \
 1029                 OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );               \
 1030                 OUT_RING( 0 );                                                           \
 1031         }                                                                                \
 1032                                                                                          \
 1033         /* generate the final descriptor for any remaining commands in this buffer */    \
 1034         page = address + i * MACH64_DMA_CHUNKSIZE;                                       \
 1035         remainder = bytes - i * MACH64_DMA_CHUNKSIZE;                                    \
 1036                                                                                          \
 1037         /* Save dword offset of last descriptor for this buffer.                         \
 1038          * This is needed to check for completion of the buffer in freelist_get          \
 1039          */                                                                              \
 1040         _entry->ring_ofs = RING_WRITE_OFS;                                               \
 1041                                                                                          \
 1042         OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );                         \
 1043         OUT_RING( page );                                                                \
 1044         OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );                 \
 1045         OUT_RING( 0 );                                                                   \
 1046                                                                                          \
 1047         ADVANCE_RING();                                                                  \
 1048 } while(0)
 1049 
 1050 #endif                          /* __MACH64_DRV_H__ */

Cache object: cd9be7c991cff8d4c855e0e76894deab


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.