Commit 399516ab0fee ("MAINTAINERS: Add a bunch of legacy (UMS) DRM drivers") marked mga driver obsolete 7 years ago. And the mesa UMD of this drm driver already in deprecated list in the link: https://docs.mesa3d.org/systems.html Matrox-->driver/gpu/drm/mga It's time to remove this driver.
Unified · Split
| @@ -414,15 +414,6 @@ config DRM_R128 · 413 unmodified lines | ||
| 414 | 414 | is selected, the module will be called r128. AGP support for |
| 415 | 415 | this card is strongly suggested (unless you have a PCI version). |
| 416 | 416 | |
| 417 | −config DRM_MGA | |
| 418 | − tristate "Matrox g200/g400" | |
| 419 | − depends on DRM && PCI | |
| 420 | − select FW_LOADER | |
| 421 | − help | |
| 422 | − Choose this option if you have a Matrox G200, G400 or G450 graphics | |
| 423 | − card. If M is selected, the module will be called mga. AGP | |
| 424 | − support is required for this driver to work. | |
| 425 | − | |
| 426 | 417 | config DRM_SIS |
| 427 | 418 | tristate "SiS video cards" |
| 428 | 419 | depends on DRM && AGP |
| @@ -137,7 +137,6 @@ obj-$(CONFIG_DRM_TDFX) += tdfx/ · 136 unmodified lines | ||
| 137 | 137 | obj-$(CONFIG_DRM_R128) += r128/ |
| 138 | 138 | obj-$(CONFIG_DRM_RADEON)+= radeon/ |
| 139 | 139 | obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/ |
| 140 | −obj-$(CONFIG_DRM_MGA) += mga/ | |
| 141 | 140 | obj-$(CONFIG_DRM_I915) += i915/ |
| 142 | 141 | obj-$(CONFIG_DRM_KMB_DISPLAY) += kmb/ |
| 143 | 142 | obj-$(CONFIG_DRM_MGAG200) += mgag200/ |
| @@ -1,11 +0,0 @@ | ||
| 1 | −# SPDX-License-Identifier: GPL-2.0-only | |
| 2 | −# | |
| 3 | −# Makefile for the drm device driver. This driver provides support for the | |
| 4 | −# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | |
| 5 | − | |
| 6 | −mga-y := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o | |
| 7 | − | |
| 8 | −mga-$(CONFIG_COMPAT) += mga_ioc32.o | |
| 9 | − | |
| 10 | −obj-$(CONFIG_DRM_MGA) += mga.o | |
| 11 | − | |
| @@ -1,1168 +0,0 @@ | ||
| 1 | −/* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*- | |
| 2 | − * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com | |
| 3 | − * | |
| 4 | − * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | |
| 5 | − * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | |
| 6 | − * All Rights Reserved. | |
| 7 | − * | |
| 8 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | − * copy of this software and associated documentation files (the "Software"), | |
| 10 | − * to deal in the Software without restriction, including without limitation | |
| 11 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | − * Software is furnished to do so, subject to the following conditions: | |
| 14 | − * | |
| 15 | − * The above copyright notice and this permission notice (including the next | |
| 16 | − * paragraph) shall be included in all copies or substantial portions of the | |
| 17 | − * Software. | |
| 18 | − * | |
| 19 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | − * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 23 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 24 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 25 | − * DEALINGS IN THE SOFTWARE. | |
| 26 | − */ | |
| 27 | − | |
| 28 | −/* | |
| 29 | − * \file mga_dma.c | |
| 30 | − * DMA support for MGA G200 / G400. | |
| 31 | − * | |
| 32 | − * \author Rickard E. (Rik) Faith <faith@valinux.com> | |
| 33 | − * \author Jeff Hartmann <jhartmann@valinux.com> | |
| 34 | − * \author Keith Whitwell <keith@tungstengraphics.com> | |
| 35 | − * \author Gareth Hughes <gareth@valinux.com> | |
| 36 | − */ | |
| 37 | − | |
| 38 | −#include <linux/delay.h> | |
| 39 | − | |
| 40 | −#include "mga_drv.h" | |
| 41 | − | |
| 42 | −#define MGA_DEFAULT_USEC_TIMEOUT 10000 | |
| 43 | −#define MGA_FREELIST_DEBUG 0 | |
| 44 | − | |
| 45 | −#define MINIMAL_CLEANUP 0 | |
| 46 | −#define FULL_CLEANUP 1 | |
| 47 | −static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup); | |
| 48 | − | |
| 49 | −/* ================================================================ | |
| 50 | − * Engine control | |
| 51 | − */ | |
| 52 | − | |
| 53 | −int mga_do_wait_for_idle(drm_mga_private_t *dev_priv) | |
| 54 | −{ | |
| 55 | − u32 status = 0; | |
| 56 | − int i; | |
| 57 | − DRM_DEBUG("\n"); | |
| 58 | − | |
| 59 | − for (i = 0; i < dev_priv->usec_timeout; i++) { | |
| 60 | − status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; | |
| 61 | − if (status == MGA_ENDPRDMASTS) { | |
| 62 | − MGA_WRITE8(MGA_CRTC_INDEX, 0); | |
| 63 | − return 0; | |
| 64 | − } | |
| 65 | − udelay(1); | |
| 66 | − } | |
| 67 | − | |
| 68 | −#if MGA_DMA_DEBUG | |
| 69 | − DRM_ERROR("failed!\n"); | |
| 70 | − DRM_INFO(" status=0x%08x\n", status); | |
| 71 | −#endif | |
| 72 | − return -EBUSY; | |
| 73 | −} | |
| 74 | − | |
| 75 | −static int mga_do_dma_reset(drm_mga_private_t *dev_priv) | |
| 76 | −{ | |
| 77 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 78 | − drm_mga_primary_buffer_t *primary = &dev_priv->prim; | |
| 79 | − | |
| 80 | − DRM_DEBUG("\n"); | |
| 81 | − | |
| 82 | − /* The primary DMA stream should look like new right about now. | |
| 83 | − */ | |
| 84 | − primary->tail = 0; | |
| 85 | − primary->space = primary->size; | |
| 86 | − primary->last_flush = 0; | |
| 87 | − | |
| 88 | − sarea_priv->last_wrap = 0; | |
| 89 | − | |
| 90 | − /* FIXME: Reset counters, buffer ages etc... | |
| 91 | − */ | |
| 92 | − | |
| 93 | − /* FIXME: What else do we need to reinitialize? WARP stuff? | |
| 94 | − */ | |
| 95 | − | |
| 96 | − return 0; | |
| 97 | −} | |
| 98 | − | |
| 99 | −/* ================================================================ | |
| 100 | − * Primary DMA stream | |
| 101 | − */ | |
| 102 | − | |
| 103 | −void mga_do_dma_flush(drm_mga_private_t *dev_priv) | |
| 104 | −{ | |
| 105 | − drm_mga_primary_buffer_t *primary = &dev_priv->prim; | |
| 106 | − u32 head, tail; | |
| 107 | − u32 status = 0; | |
| 108 | − int i; | |
| 109 | − DMA_LOCALS; | |
| 110 | − DRM_DEBUG("\n"); | |
| 111 | − | |
| 112 | − /* We need to wait so that we can do an safe flush */ | |
| 113 | − for (i = 0; i < dev_priv->usec_timeout; i++) { | |
| 114 | − status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; | |
| 115 | − if (status == MGA_ENDPRDMASTS) | |
| 116 | − break; | |
| 117 | − udelay(1); | |
| 118 | − } | |
| 119 | − | |
| 120 | − if (primary->tail == primary->last_flush) { | |
| 121 | − DRM_DEBUG(" bailing out...\n"); | |
| 122 | − return; | |
| 123 | − } | |
| 124 | − | |
| 125 | − tail = primary->tail + dev_priv->primary->offset; | |
| 126 | − | |
| 127 | − /* We need to pad the stream between flushes, as the card | |
| 128 | − * actually (partially?) reads the first of these commands. | |
| 129 | − * See page 4-16 in the G400 manual, middle of the page or so. | |
| 130 | − */ | |
| 131 | − BEGIN_DMA(1); | |
| 132 | − | |
| 133 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 134 | − MGA_DMAPAD, 0x00000000, | |
| 135 | − MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); | |
| 136 | − | |
| 137 | − ADVANCE_DMA(); | |
| 138 | − | |
| 139 | − primary->last_flush = primary->tail; | |
| 140 | − | |
| 141 | − head = MGA_READ(MGA_PRIMADDRESS); | |
| 142 | − | |
| 143 | − if (head <= tail) | |
| 144 | − primary->space = primary->size - primary->tail; | |
| 145 | − else | |
| 146 | − primary->space = head - tail; | |
| 147 | − | |
| 148 | − DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); | |
| 149 | − DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset)); | |
| 150 | − DRM_DEBUG(" space = 0x%06x\n", primary->space); | |
| 151 | − | |
| 152 | − mga_flush_write_combine(); | |
| 153 | − MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); | |
| 154 | − | |
| 155 | − DRM_DEBUG("done.\n"); | |
| 156 | −} | |
| 157 | − | |
| 158 | −void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv) | |
| 159 | −{ | |
| 160 | − drm_mga_primary_buffer_t *primary = &dev_priv->prim; | |
| 161 | − u32 head, tail; | |
| 162 | − DMA_LOCALS; | |
| 163 | − DRM_DEBUG("\n"); | |
| 164 | − | |
| 165 | − BEGIN_DMA_WRAP(); | |
| 166 | − | |
| 167 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 168 | − MGA_DMAPAD, 0x00000000, | |
| 169 | − MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); | |
| 170 | − | |
| 171 | − ADVANCE_DMA(); | |
| 172 | − | |
| 173 | − tail = primary->tail + dev_priv->primary->offset; | |
| 174 | − | |
| 175 | − primary->tail = 0; | |
| 176 | − primary->last_flush = 0; | |
| 177 | − primary->last_wrap++; | |
| 178 | − | |
| 179 | − head = MGA_READ(MGA_PRIMADDRESS); | |
| 180 | − | |
| 181 | − if (head == dev_priv->primary->offset) | |
| 182 | − primary->space = primary->size; | |
| 183 | − else | |
| 184 | − primary->space = head - dev_priv->primary->offset; | |
| 185 | − | |
| 186 | − DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); | |
| 187 | − DRM_DEBUG(" tail = 0x%06x\n", primary->tail); | |
| 188 | − DRM_DEBUG(" wrap = %d\n", primary->last_wrap); | |
| 189 | − DRM_DEBUG(" space = 0x%06x\n", primary->space); | |
| 190 | − | |
| 191 | − mga_flush_write_combine(); | |
| 192 | − MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); | |
| 193 | − | |
| 194 | − set_bit(0, &primary->wrapped); | |
| 195 | − DRM_DEBUG("done.\n"); | |
| 196 | −} | |
| 197 | − | |
| 198 | −void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv) | |
| 199 | −{ | |
| 200 | − drm_mga_primary_buffer_t *primary = &dev_priv->prim; | |
| 201 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 202 | − u32 head = dev_priv->primary->offset; | |
| 203 | − DRM_DEBUG("\n"); | |
| 204 | − | |
| 205 | − sarea_priv->last_wrap++; | |
| 206 | − DRM_DEBUG(" wrap = %d\n", sarea_priv->last_wrap); | |
| 207 | − | |
| 208 | − mga_flush_write_combine(); | |
| 209 | − MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL); | |
| 210 | − | |
| 211 | − clear_bit(0, &primary->wrapped); | |
| 212 | − DRM_DEBUG("done.\n"); | |
| 213 | −} | |
| 214 | − | |
| 215 | −/* ================================================================ | |
| 216 | − * Freelist management | |
| 217 | − */ | |
| 218 | − | |
| 219 | −#define MGA_BUFFER_USED (~0) | |
| 220 | −#define MGA_BUFFER_FREE 0 | |
| 221 | − | |
| 222 | −#if MGA_FREELIST_DEBUG | |
| 223 | −static void mga_freelist_print(struct drm_device *dev) | |
| 224 | −{ | |
| 225 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 226 | − drm_mga_freelist_t *entry; | |
| 227 | − | |
| 228 | − DRM_INFO("\n"); | |
| 229 | − DRM_INFO("current dispatch: last=0x%x done=0x%x\n", | |
| 230 | − dev_priv->sarea_priv->last_dispatch, | |
| 231 | − (unsigned int)(MGA_READ(MGA_PRIMADDRESS) - | |
| 232 | − dev_priv->primary->offset)); | |
| 233 | − DRM_INFO("current freelist:\n"); | |
| 234 | − | |
| 235 | − for (entry = dev_priv->head->next; entry; entry = entry->next) { | |
| 236 | − DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n", | |
| 237 | − entry, entry->buf->idx, entry->age.head, | |
| 238 | − (unsigned long)(entry->age.head - dev_priv->primary->offset)); | |
| 239 | − } | |
| 240 | − DRM_INFO("\n"); | |
| 241 | −} | |
| 242 | −#endif | |
| 243 | − | |
| 244 | −static int mga_freelist_init(struct drm_device *dev, drm_mga_private_t *dev_priv) | |
| 245 | −{ | |
| 246 | − struct drm_device_dma *dma = dev->dma; | |
| 247 | − struct drm_buf *buf; | |
| 248 | − drm_mga_buf_priv_t *buf_priv; | |
| 249 | − drm_mga_freelist_t *entry; | |
| 250 | − int i; | |
| 251 | − DRM_DEBUG("count=%d\n", dma->buf_count); | |
| 252 | − | |
| 253 | − dev_priv->head = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL); | |
| 254 | − if (dev_priv->head == NULL) | |
| 255 | − return -ENOMEM; | |
| 256 | − | |
| 257 | − SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0); | |
| 258 | − | |
| 259 | − for (i = 0; i < dma->buf_count; i++) { | |
| 260 | − buf = dma->buflist[i]; | |
| 261 | − buf_priv = buf->dev_private; | |
| 262 | − | |
| 263 | − entry = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL); | |
| 264 | − if (entry == NULL) | |
| 265 | − return -ENOMEM; | |
| 266 | − | |
| 267 | − entry->next = dev_priv->head->next; | |
| 268 | − entry->prev = dev_priv->head; | |
| 269 | − SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); | |
| 270 | − entry->buf = buf; | |
| 271 | − | |
| 272 | − if (dev_priv->head->next != NULL) | |
| 273 | − dev_priv->head->next->prev = entry; | |
| 274 | − if (entry->next == NULL) | |
| 275 | − dev_priv->tail = entry; | |
| 276 | − | |
| 277 | − buf_priv->list_entry = entry; | |
| 278 | − buf_priv->discard = 0; | |
| 279 | − buf_priv->dispatched = 0; | |
| 280 | − | |
| 281 | − dev_priv->head->next = entry; | |
| 282 | − } | |
| 283 | − | |
| 284 | − return 0; | |
| 285 | −} | |
| 286 | − | |
| 287 | −static void mga_freelist_cleanup(struct drm_device *dev) | |
| 288 | −{ | |
| 289 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 290 | − drm_mga_freelist_t *entry; | |
| 291 | − drm_mga_freelist_t *next; | |
| 292 | − DRM_DEBUG("\n"); | |
| 293 | − | |
| 294 | − entry = dev_priv->head; | |
| 295 | − while (entry) { | |
| 296 | − next = entry->next; | |
| 297 | − kfree(entry); | |
| 298 | − entry = next; | |
| 299 | − } | |
| 300 | − | |
| 301 | − dev_priv->head = dev_priv->tail = NULL; | |
| 302 | −} | |
| 303 | − | |
| 304 | −#if 0 | |
| 305 | −/* FIXME: Still needed? | |
| 306 | − */ | |
| 307 | −static void mga_freelist_reset(struct drm_device *dev) | |
| 308 | −{ | |
| 309 | − struct drm_device_dma *dma = dev->dma; | |
| 310 | − struct drm_buf *buf; | |
| 311 | − drm_mga_buf_priv_t *buf_priv; | |
| 312 | − int i; | |
| 313 | − | |
| 314 | − for (i = 0; i < dma->buf_count; i++) { | |
| 315 | − buf = dma->buflist[i]; | |
| 316 | − buf_priv = buf->dev_private; | |
| 317 | − SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0); | |
| 318 | − } | |
| 319 | −} | |
| 320 | −#endif | |
| 321 | − | |
| 322 | −static struct drm_buf *mga_freelist_get(struct drm_device * dev) | |
| 323 | −{ | |
| 324 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 325 | − drm_mga_freelist_t *next; | |
| 326 | − drm_mga_freelist_t *prev; | |
| 327 | − drm_mga_freelist_t *tail = dev_priv->tail; | |
| 328 | − u32 head, wrap; | |
| 329 | − DRM_DEBUG("\n"); | |
| 330 | − | |
| 331 | − head = MGA_READ(MGA_PRIMADDRESS); | |
| 332 | − wrap = dev_priv->sarea_priv->last_wrap; | |
| 333 | − | |
| 334 | − DRM_DEBUG(" tail=0x%06lx %d\n", | |
| 335 | − tail->age.head ? | |
| 336 | − (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0, | |
| 337 | − tail->age.wrap); | |
| 338 | − DRM_DEBUG(" head=0x%06lx %d\n", | |
| 339 | − (unsigned long)(head - dev_priv->primary->offset), wrap); | |
| 340 | − | |
| 341 | − if (TEST_AGE(&tail->age, head, wrap)) { | |
| 342 | − prev = dev_priv->tail->prev; | |
| 343 | − next = dev_priv->tail; | |
| 344 | − prev->next = NULL; | |
| 345 | − next->prev = next->next = NULL; | |
| 346 | − dev_priv->tail = prev; | |
| 347 | − SET_AGE(&next->age, MGA_BUFFER_USED, 0); | |
| 348 | − return next->buf; | |
| 349 | − } | |
| 350 | − | |
| 351 | − DRM_DEBUG("returning NULL!\n"); | |
| 352 | − return NULL; | |
| 353 | −} | |
| 354 | − | |
| 355 | −int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf) | |
| 356 | −{ | |
| 357 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 358 | − drm_mga_buf_priv_t *buf_priv = buf->dev_private; | |
| 359 | − drm_mga_freelist_t *head, *entry, *prev; | |
| 360 | − | |
| 361 | − DRM_DEBUG("age=0x%06lx wrap=%d\n", | |
| 362 | − (unsigned long)(buf_priv->list_entry->age.head - | |
| 363 | − dev_priv->primary->offset), | |
| 364 | − buf_priv->list_entry->age.wrap); | |
| 365 | − | |
| 366 | − entry = buf_priv->list_entry; | |
| 367 | − head = dev_priv->head; | |
| 368 | − | |
| 369 | − if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) { | |
| 370 | − SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); | |
| 371 | − prev = dev_priv->tail; | |
| 372 | − prev->next = entry; | |
| 373 | − entry->prev = prev; | |
| 374 | − entry->next = NULL; | |
| 375 | − } else { | |
| 376 | − prev = head->next; | |
| 377 | − head->next = entry; | |
| 378 | − prev->prev = entry; | |
| 379 | − entry->prev = head; | |
| 380 | − entry->next = prev; | |
| 381 | − } | |
| 382 | − | |
| 383 | − return 0; | |
| 384 | −} | |
| 385 | − | |
| 386 | −/* ================================================================ | |
| 387 | − * DMA initialization, cleanup | |
| 388 | − */ | |
| 389 | − | |
| 390 | −int mga_driver_load(struct drm_device *dev, unsigned long flags) | |
| 391 | −{ | |
| 392 | − struct pci_dev *pdev = to_pci_dev(dev->dev); | |
| 393 | − drm_mga_private_t *dev_priv; | |
| 394 | − int ret; | |
| 395 | − | |
| 396 | − /* There are PCI versions of the G450. These cards have the | |
| 397 | − * same PCI ID as the AGP G450, but have an additional PCI-to-PCI | |
| 398 | − * bridge chip. We detect these cards, which are not currently | |
| 399 | − * supported by this driver, by looking at the device ID of the | |
| 400 | − * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the | |
| 401 | − * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the | |
| 402 | − * device. | |
| 403 | − */ | |
| 404 | − if ((pdev->device == 0x0525) && pdev->bus->self | |
| 405 | − && (pdev->bus->self->vendor == 0x3388) | |
| 406 | − && (pdev->bus->self->device == 0x0021) | |
| 407 | − && dev->agp) { | |
| 408 | − /* FIXME: This should be quirked in the pci core, but oh well | |
| 409 | − * the hw probably stopped existing. */ | |
| 410 | − arch_phys_wc_del(dev->agp->agp_mtrr); | |
| 411 | − kfree(dev->agp); | |
| 412 | − dev->agp = NULL; | |
| 413 | − } | |
| 414 | − dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL); | |
| 415 | − if (!dev_priv) | |
| 416 | − return -ENOMEM; | |
| 417 | − | |
| 418 | − dev->dev_private = (void *)dev_priv; | |
| 419 | − | |
| 420 | − dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; | |
| 421 | − dev_priv->chipset = flags; | |
| 422 | − | |
| 423 | − pci_set_master(pdev); | |
| 424 | − | |
| 425 | − dev_priv->mmio_base = pci_resource_start(pdev, 1); | |
| 426 | − dev_priv->mmio_size = pci_resource_len(pdev, 1); | |
| 427 | − | |
| 428 | − ret = drm_vblank_init(dev, 1); | |
| 429 | − | |
| 430 | − if (ret) { | |
| 431 | − (void) mga_driver_unload(dev); | |
| 432 | − return ret; | |
| 433 | − } | |
| 434 | − | |
| 435 | − return 0; | |
| 436 | −} | |
| 437 | − | |
| 438 | −#if IS_ENABLED(CONFIG_AGP) | |
| 439 | −/* | |
| 440 | − * Bootstrap the driver for AGP DMA. | |
| 441 | − * | |
| 442 | − * \todo | |
| 443 | − * Investigate whether there is any benefit to storing the WARP microcode in | |
| 444 | − * AGP memory. If not, the microcode may as well always be put in PCI | |
| 445 | − * memory. | |
| 446 | − * | |
| 447 | − * \todo | |
| 448 | − * This routine needs to set dma_bs->agp_mode to the mode actually configured | |
| 449 | − * in the hardware. Looking just at the Linux AGP driver code, I don't see | |
| 450 | − * an easy way to determine this. | |
| 451 | − * | |
| 452 | − * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap | |
| 453 | − */ | |
| 454 | −static int mga_do_agp_dma_bootstrap(struct drm_device *dev, | |
| 455 | − drm_mga_dma_bootstrap_t *dma_bs) | |
| 456 | −{ | |
| 457 | − drm_mga_private_t *const dev_priv = | |
| 458 | − (drm_mga_private_t *) dev->dev_private; | |
| 459 | − unsigned int warp_size = MGA_WARP_UCODE_SIZE; | |
| 460 | − int err; | |
| 461 | − unsigned offset; | |
| 462 | − const unsigned secondary_size = dma_bs->secondary_bin_count | |
| 463 | − * dma_bs->secondary_bin_size; | |
| 464 | − const unsigned agp_size = (dma_bs->agp_size << 20); | |
| 465 | − struct drm_buf_desc req; | |
| 466 | − struct drm_agp_mode mode; | |
| 467 | − struct drm_agp_info info; | |
| 468 | − struct drm_agp_buffer agp_req; | |
| 469 | − struct drm_agp_binding bind_req; | |
| 470 | − | |
| 471 | − /* Acquire AGP. */ | |
| 472 | − err = drm_legacy_agp_acquire(dev); | |
| 473 | − if (err) { | |
| 474 | − DRM_ERROR("Unable to acquire AGP: %d\n", err); | |
| 475 | − return err; | |
| 476 | − } | |
| 477 | − | |
| 478 | − err = drm_legacy_agp_info(dev, &info); | |
| 479 | − if (err) { | |
| 480 | − DRM_ERROR("Unable to get AGP info: %d\n", err); | |
| 481 | − return err; | |
| 482 | − } | |
| 483 | − | |
| 484 | − mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode; | |
| 485 | − err = drm_legacy_agp_enable(dev, mode); | |
| 486 | − if (err) { | |
| 487 | − DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); | |
| 488 | − return err; | |
| 489 | − } | |
| 490 | − | |
| 491 | − /* In addition to the usual AGP mode configuration, the G200 AGP cards | |
| 492 | − * need to have the AGP mode "manually" set. | |
| 493 | − */ | |
| 494 | − | |
| 495 | − if (dev_priv->chipset == MGA_CARD_TYPE_G200) { | |
| 496 | − if (mode.mode & 0x02) | |
| 497 | − MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); | |
| 498 | − else | |
| 499 | − MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); | |
| 500 | − } | |
| 501 | − | |
| 502 | − /* Allocate and bind AGP memory. */ | |
| 503 | − agp_req.size = agp_size; | |
| 504 | − agp_req.type = 0; | |
| 505 | − err = drm_legacy_agp_alloc(dev, &agp_req); | |
| 506 | − if (err) { | |
| 507 | − dev_priv->agp_size = 0; | |
| 508 | − DRM_ERROR("Unable to allocate %uMB AGP memory\n", | |
| 509 | − dma_bs->agp_size); | |
| 510 | − return err; | |
| 511 | − } | |
| 512 | − | |
| 513 | − dev_priv->agp_size = agp_size; | |
| 514 | − dev_priv->agp_handle = agp_req.handle; | |
| 515 | − | |
| 516 | − bind_req.handle = agp_req.handle; | |
| 517 | − bind_req.offset = 0; | |
| 518 | − err = drm_legacy_agp_bind(dev, &bind_req); | |
| 519 | − if (err) { | |
| 520 | − DRM_ERROR("Unable to bind AGP memory: %d\n", err); | |
| 521 | − return err; | |
| 522 | − } | |
| 523 | − | |
| 524 | − /* Make drm_legacy_addbufs happy by not trying to create a mapping for | |
| 525 | − * less than a page. | |
| 526 | − */ | |
| 527 | − if (warp_size < PAGE_SIZE) | |
| 528 | − warp_size = PAGE_SIZE; | |
| 529 | − | |
| 530 | − offset = 0; | |
| 531 | − err = drm_legacy_addmap(dev, offset, warp_size, | |
| 532 | − _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); | |
| 533 | − if (err) { | |
| 534 | − DRM_ERROR("Unable to map WARP microcode: %d\n", err); | |
| 535 | − return err; | |
| 536 | − } | |
| 537 | − | |
| 538 | − offset += warp_size; | |
| 539 | − err = drm_legacy_addmap(dev, offset, dma_bs->primary_size, | |
| 540 | − _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); | |
| 541 | − if (err) { | |
| 542 | − DRM_ERROR("Unable to map primary DMA region: %d\n", err); | |
| 543 | − return err; | |
| 544 | − } | |
| 545 | − | |
| 546 | − offset += dma_bs->primary_size; | |
| 547 | − err = drm_legacy_addmap(dev, offset, secondary_size, | |
| 548 | − _DRM_AGP, 0, &dev->agp_buffer_map); | |
| 549 | − if (err) { | |
| 550 | − DRM_ERROR("Unable to map secondary DMA region: %d\n", err); | |
| 551 | − return err; | |
| 552 | − } | |
| 553 | − | |
| 554 | − (void)memset(&req, 0, sizeof(req)); | |
| 555 | − req.count = dma_bs->secondary_bin_count; | |
| 556 | − req.size = dma_bs->secondary_bin_size; | |
| 557 | − req.flags = _DRM_AGP_BUFFER; | |
| 558 | − req.agp_start = offset; | |
| 559 | − | |
| 560 | − err = drm_legacy_addbufs_agp(dev, &req); | |
| 561 | − if (err) { | |
| 562 | − DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); | |
| 563 | − return err; | |
| 564 | − } | |
| 565 | − | |
| 566 | − { | |
| 567 | − struct drm_map_list *_entry; | |
| 568 | − unsigned long agp_token = 0; | |
| 569 | − | |
| 570 | − list_for_each_entry(_entry, &dev->maplist, head) { | |
| 571 | − if (_entry->map == dev->agp_buffer_map) | |
| 572 | − agp_token = _entry->user_token; | |
| 573 | − } | |
| 574 | − if (!agp_token) | |
| 575 | − return -EFAULT; | |
| 576 | − | |
| 577 | − dev->agp_buffer_token = agp_token; | |
| 578 | − } | |
| 579 | − | |
| 580 | − offset += secondary_size; | |
| 581 | − err = drm_legacy_addmap(dev, offset, agp_size - offset, | |
| 582 | − _DRM_AGP, 0, &dev_priv->agp_textures); | |
| 583 | − if (err) { | |
| 584 | − DRM_ERROR("Unable to map AGP texture region %d\n", err); | |
| 585 | − return err; | |
| 586 | − } | |
| 587 | − | |
| 588 | − drm_legacy_ioremap(dev_priv->warp, dev); | |
| 589 | − drm_legacy_ioremap(dev_priv->primary, dev); | |
| 590 | − drm_legacy_ioremap(dev->agp_buffer_map, dev); | |
| 591 | − | |
| 592 | − if (!dev_priv->warp->handle || | |
| 593 | − !dev_priv->primary->handle || !dev->agp_buffer_map->handle) { | |
| 594 | − DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n", | |
| 595 | − dev_priv->warp->handle, dev_priv->primary->handle, | |
| 596 | − dev->agp_buffer_map->handle); | |
| 597 | − return -ENOMEM; | |
| 598 | − } | |
| 599 | − | |
| 600 | − dev_priv->dma_access = MGA_PAGPXFER; | |
| 601 | − dev_priv->wagp_enable = MGA_WAGP_ENABLE; | |
| 602 | − | |
| 603 | − DRM_INFO("Initialized card for AGP DMA.\n"); | |
| 604 | − return 0; | |
| 605 | −} | |
| 606 | −#else | |
| 607 | −static int mga_do_agp_dma_bootstrap(struct drm_device *dev, | |
| 608 | − drm_mga_dma_bootstrap_t *dma_bs) | |
| 609 | −{ | |
| 610 | − return -EINVAL; | |
| 611 | −} | |
| 612 | −#endif | |
| 613 | − | |
| 614 | −/* | |
| 615 | − * Bootstrap the driver for PCI DMA. | |
| 616 | − * | |
| 617 | − * \todo | |
| 618 | − * The algorithm for decreasing the size of the primary DMA buffer could be | |
| 619 | − * better. The size should be rounded up to the nearest page size, then | |
| 620 | − * decrease the request size by a single page each pass through the loop. | |
| 621 | − * | |
| 622 | − * \todo | |
| 623 | − * Determine whether the maximum address passed to drm_pci_alloc is correct. | |
| 624 | − * The same goes for drm_legacy_addbufs_pci. | |
| 625 | − * | |
| 626 | − * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap | |
| 627 | − */ | |
| 628 | −static int mga_do_pci_dma_bootstrap(struct drm_device *dev, | |
| 629 | − drm_mga_dma_bootstrap_t *dma_bs) | |
| 630 | −{ | |
| 631 | − drm_mga_private_t *const dev_priv = | |
| 632 | − (drm_mga_private_t *) dev->dev_private; | |
| 633 | − unsigned int warp_size = MGA_WARP_UCODE_SIZE; | |
| 634 | − unsigned int primary_size; | |
| 635 | − unsigned int bin_count; | |
| 636 | − int err; | |
| 637 | − struct drm_buf_desc req; | |
| 638 | − | |
| 639 | − if (dev->dma == NULL) { | |
| 640 | − DRM_ERROR("dev->dma is NULL\n"); | |
| 641 | − return -EFAULT; | |
| 642 | − } | |
| 643 | − | |
| 644 | − /* Make drm_legacy_addbufs happy by not trying to create a mapping for | |
| 645 | − * less than a page. | |
| 646 | − */ | |
| 647 | − if (warp_size < PAGE_SIZE) | |
| 648 | − warp_size = PAGE_SIZE; | |
| 649 | − | |
| 650 | − /* The proper alignment is 0x100 for this mapping */ | |
| 651 | − err = drm_legacy_addmap(dev, 0, warp_size, _DRM_CONSISTENT, | |
| 652 | − _DRM_READ_ONLY, &dev_priv->warp); | |
| 653 | − if (err != 0) { | |
| 654 | − DRM_ERROR("Unable to create mapping for WARP microcode: %d\n", | |
| 655 | − err); | |
| 656 | − return err; | |
| 657 | − } | |
| 658 | − | |
| 659 | − /* Other than the bottom two bits being used to encode other | |
| 660 | − * information, there don't appear to be any restrictions on the | |
| 661 | − * alignment of the primary or secondary DMA buffers. | |
| 662 | − */ | |
| 663 | − | |
| 664 | − for (primary_size = dma_bs->primary_size; primary_size != 0; | |
| 665 | − primary_size >>= 1) { | |
| 666 | − /* The proper alignment for this mapping is 0x04 */ | |
| 667 | − err = drm_legacy_addmap(dev, 0, primary_size, _DRM_CONSISTENT, | |
| 668 | − _DRM_READ_ONLY, &dev_priv->primary); | |
| 669 | − if (!err) | |
| 670 | − break; | |
| 671 | − } | |
| 672 | − | |
| 673 | − if (err != 0) { | |
| 674 | − DRM_ERROR("Unable to allocate primary DMA region: %d\n", err); | |
| 675 | − return -ENOMEM; | |
| 676 | − } | |
| 677 | − | |
| 678 | − if (dev_priv->primary->size != dma_bs->primary_size) { | |
| 679 | − DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n", | |
| 680 | − dma_bs->primary_size, | |
| 681 | − (unsigned)dev_priv->primary->size); | |
| 682 | − dma_bs->primary_size = dev_priv->primary->size; | |
| 683 | − } | |
| 684 | − | |
| 685 | − for (bin_count = dma_bs->secondary_bin_count; bin_count > 0; | |
| 686 | − bin_count--) { | |
| 687 | − (void)memset(&req, 0, sizeof(req)); | |
| 688 | − req.count = bin_count; | |
| 689 | − req.size = dma_bs->secondary_bin_size; | |
| 690 | − | |
| 691 | − err = drm_legacy_addbufs_pci(dev, &req); | |
| 692 | − if (!err) | |
| 693 | − break; | |
| 694 | − } | |
| 695 | − | |
| 696 | − if (bin_count == 0) { | |
| 697 | − DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); | |
| 698 | − return err; | |
| 699 | − } | |
| 700 | − | |
| 701 | − if (bin_count != dma_bs->secondary_bin_count) { | |
| 702 | − DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u " | |
| 703 | − "to %u.\n", dma_bs->secondary_bin_count, bin_count); | |
| 704 | − | |
| 705 | − dma_bs->secondary_bin_count = bin_count; | |
| 706 | − } | |
| 707 | − | |
| 708 | − dev_priv->dma_access = 0; | |
| 709 | − dev_priv->wagp_enable = 0; | |
| 710 | − | |
| 711 | − dma_bs->agp_mode = 0; | |
| 712 | − | |
| 713 | − DRM_INFO("Initialized card for PCI DMA.\n"); | |
| 714 | − return 0; | |
| 715 | −} | |
| 716 | − | |
| 717 | −static int mga_do_dma_bootstrap(struct drm_device *dev, | |
| 718 | − drm_mga_dma_bootstrap_t *dma_bs) | |
| 719 | −{ | |
| 720 | − const int is_agp = (dma_bs->agp_mode != 0) && dev->agp; | |
| 721 | − int err; | |
| 722 | − drm_mga_private_t *const dev_priv = | |
| 723 | − (drm_mga_private_t *) dev->dev_private; | |
| 724 | − | |
| 725 | − dev_priv->used_new_dma_init = 1; | |
| 726 | − | |
| 727 | − /* The first steps are the same for both PCI and AGP based DMA. Map | |
| 728 | − * the cards MMIO registers and map a status page. | |
| 729 | − */ | |
| 730 | − err = drm_legacy_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, | |
| 731 | − _DRM_REGISTERS, _DRM_READ_ONLY, | |
| 732 | − &dev_priv->mmio); | |
| 733 | − if (err) { | |
| 734 | − DRM_ERROR("Unable to map MMIO region: %d\n", err); | |
| 735 | − return err; | |
| 736 | − } | |
| 737 | − | |
| 738 | − err = drm_legacy_addmap(dev, 0, SAREA_MAX, _DRM_SHM, | |
| 739 | − _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, | |
| 740 | − &dev_priv->status); | |
| 741 | − if (err) { | |
| 742 | − DRM_ERROR("Unable to map status region: %d\n", err); | |
| 743 | − return err; | |
| 744 | − } | |
| 745 | − | |
| 746 | − /* The DMA initialization procedure is slightly different for PCI and | |
| 747 | − * AGP cards. AGP cards just allocate a large block of AGP memory and | |
| 748 | − * carve off portions of it for internal uses. The remaining memory | |
| 749 | − * is returned to user-mode to be used for AGP textures. | |
| 750 | − */ | |
| 751 | − if (is_agp) | |
| 752 | − err = mga_do_agp_dma_bootstrap(dev, dma_bs); | |
| 753 | − | |
| 754 | − /* If we attempted to initialize the card for AGP DMA but failed, | |
| 755 | − * clean-up any mess that may have been created. | |
| 756 | − */ | |
| 757 | − | |
| 758 | − if (err) | |
| 759 | − mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); | |
| 760 | − | |
| 761 | − /* Not only do we want to try and initialized PCI cards for PCI DMA, | |
| 762 | − * but we also try to initialized AGP cards that could not be | |
| 763 | − * initialized for AGP DMA. This covers the case where we have an AGP | |
| 764 | − * card in a system with an unsupported AGP chipset. In that case the | |
| 765 | − * card will be detected as AGP, but we won't be able to allocate any | |
| 766 | − * AGP memory, etc. | |
| 767 | − */ | |
| 768 | − | |
| 769 | − if (!is_agp || err) | |
| 770 | − err = mga_do_pci_dma_bootstrap(dev, dma_bs); | |
| 771 | − | |
| 772 | − return err; | |
| 773 | −} | |
| 774 | − | |
| 775 | −int mga_dma_bootstrap(struct drm_device *dev, void *data, | |
| 776 | − struct drm_file *file_priv) | |
| 777 | −{ | |
| 778 | − drm_mga_dma_bootstrap_t *bootstrap = data; | |
| 779 | − int err; | |
| 780 | − static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; | |
| 781 | − const drm_mga_private_t *const dev_priv = | |
| 782 | − (drm_mga_private_t *) dev->dev_private; | |
| 783 | − | |
| 784 | − err = mga_do_dma_bootstrap(dev, bootstrap); | |
| 785 | − if (err) { | |
| 786 | − mga_do_cleanup_dma(dev, FULL_CLEANUP); | |
| 787 | − return err; | |
| 788 | − } | |
| 789 | − | |
| 790 | − if (dev_priv->agp_textures != NULL) { | |
| 791 | − bootstrap->texture_handle = dev_priv->agp_textures->offset; | |
| 792 | − bootstrap->texture_size = dev_priv->agp_textures->size; | |
| 793 | − } else { | |
| 794 | − bootstrap->texture_handle = 0; | |
| 795 | − bootstrap->texture_size = 0; | |
| 796 | − } | |
| 797 | − | |
| 798 | − bootstrap->agp_mode = modes[bootstrap->agp_mode & 0x07]; | |
| 799 | − | |
| 800 | − return err; | |
| 801 | −} | |
| 802 | − | |
| 803 | −static int mga_do_init_dma(struct drm_device *dev, drm_mga_init_t *init) | |
| 804 | −{ | |
| 805 | − drm_mga_private_t *dev_priv; | |
| 806 | − int ret; | |
| 807 | − DRM_DEBUG("\n"); | |
| 808 | − | |
| 809 | − dev_priv = dev->dev_private; | |
| 810 | − | |
| 811 | − if (init->sgram) | |
| 812 | − dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; | |
| 813 | − else | |
| 814 | − dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; | |
| 815 | − dev_priv->maccess = init->maccess; | |
| 816 | − | |
| 817 | − dev_priv->fb_cpp = init->fb_cpp; | |
| 818 | − dev_priv->front_offset = init->front_offset; | |
| 819 | − dev_priv->front_pitch = init->front_pitch; | |
| 820 | − dev_priv->back_offset = init->back_offset; | |
| 821 | − dev_priv->back_pitch = init->back_pitch; | |
| 822 | − | |
| 823 | − dev_priv->depth_cpp = init->depth_cpp; | |
| 824 | − dev_priv->depth_offset = init->depth_offset; | |
| 825 | − dev_priv->depth_pitch = init->depth_pitch; | |
| 826 | − | |
| 827 | − /* FIXME: Need to support AGP textures... | |
| 828 | − */ | |
| 829 | − dev_priv->texture_offset = init->texture_offset[0]; | |
| 830 | − dev_priv->texture_size = init->texture_size[0]; | |
| 831 | − | |
| 832 | − dev_priv->sarea = drm_legacy_getsarea(dev); | |
| 833 | − if (!dev_priv->sarea) { | |
| 834 | − DRM_ERROR("failed to find sarea!\n"); | |
| 835 | − return -EINVAL; | |
| 836 | − } | |
| 837 | − | |
| 838 | − if (!dev_priv->used_new_dma_init) { | |
| 839 | − | |
| 840 | − dev_priv->dma_access = MGA_PAGPXFER; | |
| 841 | − dev_priv->wagp_enable = MGA_WAGP_ENABLE; | |
| 842 | − | |
| 843 | − dev_priv->status = drm_legacy_findmap(dev, init->status_offset); | |
| 844 | − if (!dev_priv->status) { | |
| 845 | − DRM_ERROR("failed to find status page!\n"); | |
| 846 | − return -EINVAL; | |
| 847 | − } | |
| 848 | − dev_priv->mmio = drm_legacy_findmap(dev, init->mmio_offset); | |
| 849 | − if (!dev_priv->mmio) { | |
| 850 | − DRM_ERROR("failed to find mmio region!\n"); | |
| 851 | − return -EINVAL; | |
| 852 | − } | |
| 853 | − dev_priv->warp = drm_legacy_findmap(dev, init->warp_offset); | |
| 854 | − if (!dev_priv->warp) { | |
| 855 | − DRM_ERROR("failed to find warp microcode region!\n"); | |
| 856 | − return -EINVAL; | |
| 857 | − } | |
| 858 | − dev_priv->primary = drm_legacy_findmap(dev, init->primary_offset); | |
| 859 | − if (!dev_priv->primary) { | |
| 860 | − DRM_ERROR("failed to find primary dma region!\n"); | |
| 861 | − return -EINVAL; | |
| 862 | − } | |
| 863 | − dev->agp_buffer_token = init->buffers_offset; | |
| 864 | − dev->agp_buffer_map = | |
| 865 | − drm_legacy_findmap(dev, init->buffers_offset); | |
| 866 | − if (!dev->agp_buffer_map) { | |
| 867 | − DRM_ERROR("failed to find dma buffer region!\n"); | |
| 868 | − return -EINVAL; | |
| 869 | − } | |
| 870 | − | |
| 871 | − drm_legacy_ioremap(dev_priv->warp, dev); | |
| 872 | − drm_legacy_ioremap(dev_priv->primary, dev); | |
| 873 | − drm_legacy_ioremap(dev->agp_buffer_map, dev); | |
| 874 | − } | |
| 875 | − | |
| 876 | − dev_priv->sarea_priv = | |
| 877 | − (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle + | |
| 878 | − init->sarea_priv_offset); | |
| 879 | − | |
| 880 | − if (!dev_priv->warp->handle || | |
| 881 | − !dev_priv->primary->handle || | |
| 882 | − ((dev_priv->dma_access != 0) && | |
| 883 | − ((dev->agp_buffer_map == NULL) || | |
| 884 | − (dev->agp_buffer_map->handle == NULL)))) { | |
| 885 | − DRM_ERROR("failed to ioremap agp regions!\n"); | |
| 886 | − return -ENOMEM; | |
| 887 | − } | |
| 888 | − | |
| 889 | − ret = mga_warp_install_microcode(dev_priv); | |
| 890 | − if (ret < 0) { | |
| 891 | − DRM_ERROR("failed to install WARP ucode!: %d\n", ret); | |
| 892 | − return ret; | |
| 893 | − } | |
| 894 | − | |
| 895 | − ret = mga_warp_init(dev_priv); | |
| 896 | − if (ret < 0) { | |
| 897 | − DRM_ERROR("failed to init WARP engine!: %d\n", ret); | |
| 898 | − return ret; | |
| 899 | − } | |
| 900 | − | |
| 901 | − dev_priv->prim.status = (u32 *) dev_priv->status->handle; | |
| 902 | − | |
| 903 | − mga_do_wait_for_idle(dev_priv); | |
| 904 | − | |
| 905 | − /* Init the primary DMA registers. | |
| 906 | − */ | |
| 907 | − MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL); | |
| 908 | −#if 0 | |
| 909 | − MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */ | |
| 910 | − MGA_PRIMPTREN1); /* DWGSYNC */ | |
| 911 | −#endif | |
| 912 | − | |
| 913 | − dev_priv->prim.start = (u8 *) dev_priv->primary->handle; | |
| 914 | − dev_priv->prim.end = ((u8 *) dev_priv->primary->handle | |
| 915 | − + dev_priv->primary->size); | |
| 916 | − dev_priv->prim.size = dev_priv->primary->size; | |
| 917 | − | |
| 918 | − dev_priv->prim.tail = 0; | |
| 919 | − dev_priv->prim.space = dev_priv->prim.size; | |
| 920 | − dev_priv->prim.wrapped = 0; | |
| 921 | − | |
| 922 | − dev_priv->prim.last_flush = 0; | |
| 923 | − dev_priv->prim.last_wrap = 0; | |
| 924 | − | |
| 925 | − dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; | |
| 926 | − | |
| 927 | − dev_priv->prim.status[0] = dev_priv->primary->offset; | |
| 928 | − dev_priv->prim.status[1] = 0; | |
| 929 | − | |
| 930 | − dev_priv->sarea_priv->last_wrap = 0; | |
| 931 | − dev_priv->sarea_priv->last_frame.head = 0; | |
| 932 | − dev_priv->sarea_priv->last_frame.wrap = 0; | |
| 933 | − | |
| 934 | − if (mga_freelist_init(dev, dev_priv) < 0) { | |
| 935 | − DRM_ERROR("could not initialize freelist\n"); | |
| 936 | − return -ENOMEM; | |
| 937 | − } | |
| 938 | − | |
| 939 | − return 0; | |
| 940 | −} | |
| 941 | − | |
| 942 | −static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) | |
| 943 | −{ | |
| 944 | − int err = 0; | |
| 945 | − DRM_DEBUG("\n"); | |
| 946 | − | |
| 947 | − /* Make sure interrupts are disabled here because the uninstall ioctl | |
| 948 | − * may not have been called from userspace and after dev_private | |
| 949 | − * is freed, it's too late. | |
| 950 | − */ | |
| 951 | − if (dev->irq_enabled) | |
| 952 | − drm_legacy_irq_uninstall(dev); | |
| 953 | − | |
| 954 | − if (dev->dev_private) { | |
| 955 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 956 | − | |
| 957 | − if ((dev_priv->warp != NULL) | |
| 958 | − && (dev_priv->warp->type != _DRM_CONSISTENT)) | |
| 959 | − drm_legacy_ioremapfree(dev_priv->warp, dev); | |
| 960 | − | |
| 961 | − if ((dev_priv->primary != NULL) | |
| 962 | − && (dev_priv->primary->type != _DRM_CONSISTENT)) | |
| 963 | − drm_legacy_ioremapfree(dev_priv->primary, dev); | |
| 964 | − | |
| 965 | − if (dev->agp_buffer_map != NULL) | |
| 966 | − drm_legacy_ioremapfree(dev->agp_buffer_map, dev); | |
| 967 | − | |
| 968 | − if (dev_priv->used_new_dma_init) { | |
| 969 | −#if IS_ENABLED(CONFIG_AGP) | |
| 970 | − if (dev_priv->agp_handle != 0) { | |
| 971 | − struct drm_agp_binding unbind_req; | |
| 972 | − struct drm_agp_buffer free_req; | |
| 973 | − | |
| 974 | − unbind_req.handle = dev_priv->agp_handle; | |
| 975 | − drm_legacy_agp_unbind(dev, &unbind_req); | |
| 976 | − | |
| 977 | − free_req.handle = dev_priv->agp_handle; | |
| 978 | − drm_legacy_agp_free(dev, &free_req); | |
| 979 | − | |
| 980 | − dev_priv->agp_textures = NULL; | |
| 981 | − dev_priv->agp_size = 0; | |
| 982 | − dev_priv->agp_handle = 0; | |
| 983 | − } | |
| 984 | − | |
| 985 | − if ((dev->agp != NULL) && dev->agp->acquired) | |
| 986 | − err = drm_legacy_agp_release(dev); | |
| 987 | −#endif | |
| 988 | − } | |
| 989 | − | |
| 990 | − dev_priv->warp = NULL; | |
| 991 | − dev_priv->primary = NULL; | |
| 992 | − dev_priv->sarea = NULL; | |
| 993 | − dev_priv->sarea_priv = NULL; | |
| 994 | − dev->agp_buffer_map = NULL; | |
| 995 | − | |
| 996 | − if (full_cleanup) { | |
| 997 | − dev_priv->mmio = NULL; | |
| 998 | − dev_priv->status = NULL; | |
| 999 | − dev_priv->used_new_dma_init = 0; | |
| 1000 | − } | |
| 1001 | − | |
| 1002 | − memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); | |
| 1003 | − dev_priv->warp_pipe = 0; | |
| 1004 | − memset(dev_priv->warp_pipe_phys, 0, | |
| 1005 | − sizeof(dev_priv->warp_pipe_phys)); | |
| 1006 | − | |
| 1007 | − if (dev_priv->head != NULL) | |
| 1008 | − mga_freelist_cleanup(dev); | |
| 1009 | − } | |
| 1010 | − | |
| 1011 | − return err; | |
| 1012 | −} | |
| 1013 | − | |
| 1014 | −int mga_dma_init(struct drm_device *dev, void *data, | |
| 1015 | − struct drm_file *file_priv) | |
| 1016 | −{ | |
| 1017 | − drm_mga_init_t *init = data; | |
| 1018 | − int err; | |
| 1019 | − | |
| 1020 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 1021 | − | |
| 1022 | − switch (init->func) { | |
| 1023 | − case MGA_INIT_DMA: | |
| 1024 | − err = mga_do_init_dma(dev, init); | |
| 1025 | − if (err) | |
| 1026 | − (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); | |
| 1027 | − return err; | |
| 1028 | − case MGA_CLEANUP_DMA: | |
| 1029 | − return mga_do_cleanup_dma(dev, FULL_CLEANUP); | |
| 1030 | − } | |
| 1031 | − | |
| 1032 | − return -EINVAL; | |
| 1033 | −} | |
| 1034 | − | |
| 1035 | −/* ================================================================ | |
| 1036 | − * Primary DMA stream management | |
| 1037 | − */ | |
| 1038 | − | |
| 1039 | −int mga_dma_flush(struct drm_device *dev, void *data, | |
| 1040 | − struct drm_file *file_priv) | |
| 1041 | −{ | |
| 1042 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 1043 | − struct drm_lock *lock = data; | |
| 1044 | − | |
| 1045 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 1046 | − | |
| 1047 | − DRM_DEBUG("%s%s%s\n", | |
| 1048 | − (lock->flags & _DRM_LOCK_FLUSH) ? "flush, " : "", | |
| 1049 | − (lock->flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", | |
| 1050 | − (lock->flags & _DRM_LOCK_QUIESCENT) ? "idle, " : ""); | |
| 1051 | − | |
| 1052 | − WRAP_WAIT_WITH_RETURN(dev_priv); | |
| 1053 | − | |
| 1054 | − if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) | |
| 1055 | − mga_do_dma_flush(dev_priv); | |
| 1056 | − | |
| 1057 | − if (lock->flags & _DRM_LOCK_QUIESCENT) { | |
| 1058 | −#if MGA_DMA_DEBUG | |
| 1059 | − int ret = mga_do_wait_for_idle(dev_priv); | |
| 1060 | − if (ret < 0) | |
| 1061 | − DRM_INFO("-EBUSY\n"); | |
| 1062 | − return ret; | |
| 1063 | −#else | |
| 1064 | − return mga_do_wait_for_idle(dev_priv); | |
| 1065 | −#endif | |
| 1066 | − } else { | |
| 1067 | − return 0; | |
| 1068 | − } | |
| 1069 | −} | |
| 1070 | − | |
| 1071 | −int mga_dma_reset(struct drm_device *dev, void *data, | |
| 1072 | − struct drm_file *file_priv) | |
| 1073 | −{ | |
| 1074 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 1075 | − | |
| 1076 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 1077 | − | |
| 1078 | − return mga_do_dma_reset(dev_priv); | |
| 1079 | −} | |
| 1080 | − | |
| 1081 | −/* ================================================================ | |
| 1082 | − * DMA buffer management | |
| 1083 | − */ | |
| 1084 | − | |
| 1085 | −static int mga_dma_get_buffers(struct drm_device *dev, | |
| 1086 | − struct drm_file *file_priv, struct drm_dma *d) | |
| 1087 | −{ | |
| 1088 | − struct drm_buf *buf; | |
| 1089 | − int i; | |
| 1090 | − | |
| 1091 | − for (i = d->granted_count; i < d->request_count; i++) { | |
| 1092 | − buf = mga_freelist_get(dev); | |
| 1093 | − if (!buf) | |
| 1094 | − return -EAGAIN; | |
| 1095 | − | |
| 1096 | − buf->file_priv = file_priv; | |
| 1097 | − | |
| 1098 | − if (copy_to_user(&d->request_indices[i], | |
| 1099 | − &buf->idx, sizeof(buf->idx))) | |
| 1100 | − return -EFAULT; | |
| 1101 | − if (copy_to_user(&d->request_sizes[i], | |
| 1102 | − &buf->total, sizeof(buf->total))) | |
| 1103 | − return -EFAULT; | |
| 1104 | − | |
| 1105 | − d->granted_count++; | |
| 1106 | − } | |
| 1107 | − return 0; | |
| 1108 | −} | |
| 1109 | − | |
| 1110 | −int mga_dma_buffers(struct drm_device *dev, void *data, | |
| 1111 | − struct drm_file *file_priv) | |
| 1112 | −{ | |
| 1113 | − struct drm_device_dma *dma = dev->dma; | |
| 1114 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 1115 | − struct drm_dma *d = data; | |
| 1116 | − int ret = 0; | |
| 1117 | − | |
| 1118 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 1119 | − | |
| 1120 | − /* Please don't send us buffers. | |
| 1121 | − */ | |
| 1122 | − if (d->send_count != 0) { | |
| 1123 | − DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", | |
| 1124 | − task_pid_nr(current), d->send_count); | |
| 1125 | − return -EINVAL; | |
| 1126 | − } | |
| 1127 | − | |
| 1128 | − /* We'll send you buffers. | |
| 1129 | − */ | |
| 1130 | − if (d->request_count < 0 || d->request_count > dma->buf_count) { | |
| 1131 | − DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", | |
| 1132 | − task_pid_nr(current), d->request_count, | |
| 1133 | − dma->buf_count); | |
| 1134 | − return -EINVAL; | |
| 1135 | − } | |
| 1136 | − | |
| 1137 | − WRAP_TEST_WITH_RETURN(dev_priv); | |
| 1138 | − | |
| 1139 | − d->granted_count = 0; | |
| 1140 | − | |
| 1141 | − if (d->request_count) | |
| 1142 | − ret = mga_dma_get_buffers(dev, file_priv, d); | |
| 1143 | − | |
| 1144 | − return ret; | |
| 1145 | −} | |
| 1146 | − | |
| 1147 | −/* | |
| 1148 | − * Called just before the module is unloaded. | |
| 1149 | − */ | |
| 1150 | −void mga_driver_unload(struct drm_device *dev) | |
| 1151 | −{ | |
| 1152 | − kfree(dev->dev_private); | |
| 1153 | − dev->dev_private = NULL; | |
| 1154 | −} | |
| 1155 | − | |
| 1156 | −/* | |
| 1157 | − * Called when the last opener of the device is closed. | |
| 1158 | − */ | |
| 1159 | −void mga_driver_lastclose(struct drm_device *dev) | |
| 1160 | −{ | |
| 1161 | − mga_do_cleanup_dma(dev, FULL_CLEANUP); | |
| 1162 | −} | |
| 1163 | − | |
| 1164 | −int mga_driver_dma_quiescent(struct drm_device *dev) | |
| 1165 | −{ | |
| 1166 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 1167 | − return mga_do_wait_for_idle(dev_priv); | |
| 1168 | −} | |
| @@ -1,104 +0,0 @@ | ||
| 1 | −/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*- | |
| 2 | − * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com | |
| 3 | − * | |
| 4 | − * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | |
| 5 | − * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | |
| 6 | − * All Rights Reserved. | |
| 7 | − * | |
| 8 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | − * copy of this software and associated documentation files (the "Software"), | |
| 10 | − * to deal in the Software without restriction, including without limitation | |
| 11 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | − * Software is furnished to do so, subject to the following conditions: | |
| 14 | − * | |
| 15 | − * The above copyright notice and this permission notice (including the next | |
| 16 | − * paragraph) shall be included in all copies or substantial portions of the | |
| 17 | − * Software. | |
| 18 | − * | |
| 19 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | − * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 23 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 24 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 25 | − * OTHER DEALINGS IN THE SOFTWARE. | |
| 26 | − * | |
| 27 | − * Authors: | |
| 28 | − * Rickard E. (Rik) Faith <faith@valinux.com> | |
| 29 | − * Gareth Hughes <gareth@valinux.com> | |
| 30 | − */ | |
| 31 | − | |
| 32 | −#include <linux/module.h> | |
| 33 | − | |
| 34 | −#include <drm/drm_drv.h> | |
| 35 | −#include <drm/drm_pciids.h> | |
| 36 | − | |
| 37 | −#include "mga_drv.h" | |
| 38 | − | |
| 39 | −static struct pci_device_id pciidlist[] = { | |
| 40 | − mga_PCI_IDS | |
| 41 | −}; | |
| 42 | − | |
| 43 | −static const struct file_operations mga_driver_fops = { | |
| 44 | − .owner = THIS_MODULE, | |
| 45 | − .open = drm_open, | |
| 46 | − .release = drm_release, | |
| 47 | − .unlocked_ioctl = drm_ioctl, | |
| 48 | − .mmap = drm_legacy_mmap, | |
| 49 | − .poll = drm_poll, | |
| 50 | −#ifdef CONFIG_COMPAT | |
| 51 | − .compat_ioctl = mga_compat_ioctl, | |
| 52 | −#endif | |
| 53 | − .llseek = noop_llseek, | |
| 54 | −}; | |
| 55 | − | |
| 56 | −static struct drm_driver driver = { | |
| 57 | − .driver_features = | |
| 58 | − DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_LEGACY | | |
| 59 | − DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ, | |
| 60 | − .dev_priv_size = sizeof(drm_mga_buf_priv_t), | |
| 61 | − .load = mga_driver_load, | |
| 62 | − .unload = mga_driver_unload, | |
| 63 | − .lastclose = mga_driver_lastclose, | |
| 64 | − .dma_quiescent = mga_driver_dma_quiescent, | |
| 65 | − .get_vblank_counter = mga_get_vblank_counter, | |
| 66 | − .enable_vblank = mga_enable_vblank, | |
| 67 | − .disable_vblank = mga_disable_vblank, | |
| 68 | − .irq_preinstall = mga_driver_irq_preinstall, | |
| 69 | − .irq_postinstall = mga_driver_irq_postinstall, | |
| 70 | − .irq_uninstall = mga_driver_irq_uninstall, | |
| 71 | − .irq_handler = mga_driver_irq_handler, | |
| 72 | − .ioctls = mga_ioctls, | |
| 73 | − .dma_ioctl = mga_dma_buffers, | |
| 74 | − .fops = &mga_driver_fops, | |
| 75 | − .name = DRIVER_NAME, | |
| 76 | − .desc = DRIVER_DESC, | |
| 77 | − .date = DRIVER_DATE, | |
| 78 | − .major = DRIVER_MAJOR, | |
| 79 | − .minor = DRIVER_MINOR, | |
| 80 | − .patchlevel = DRIVER_PATCHLEVEL, | |
| 81 | −}; | |
| 82 | − | |
| 83 | −static struct pci_driver mga_pci_driver = { | |
| 84 | − .name = DRIVER_NAME, | |
| 85 | − .id_table = pciidlist, | |
| 86 | −}; | |
| 87 | − | |
| 88 | −static int __init mga_init(void) | |
| 89 | −{ | |
| 90 | − driver.num_ioctls = mga_max_ioctl; | |
| 91 | − return drm_legacy_pci_init(&driver, &mga_pci_driver); | |
| 92 | −} | |
| 93 | − | |
| 94 | −static void __exit mga_exit(void) | |
| 95 | −{ | |
| 96 | − drm_legacy_pci_exit(&driver, &mga_pci_driver); | |
| 97 | −} | |
| 98 | − | |
| 99 | −module_init(mga_init); | |
| 100 | −module_exit(mga_exit); | |
| 101 | − | |
| 102 | −MODULE_AUTHOR(DRIVER_AUTHOR); | |
| 103 | −MODULE_DESCRIPTION(DRIVER_DESC); | |
| 104 | −MODULE_LICENSE("GPL and additional rights"); | |
| @@ -1,685 +0,0 @@ | ||
| 1 | −/* mga_drv.h -- Private header for the Matrox G200/G400 driver -*- linux-c -*- | |
| 2 | − * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com | |
| 3 | − * | |
| 4 | − * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | |
| 5 | − * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | |
| 6 | − * All rights reserved. | |
| 7 | − * | |
| 8 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | − * copy of this software and associated documentation files (the "Software"), | |
| 10 | − * to deal in the Software without restriction, including without limitation | |
| 11 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | − * Software is furnished to do so, subject to the following conditions: | |
| 14 | − * | |
| 15 | − * The above copyright notice and this permission notice (including the next | |
| 16 | − * paragraph) shall be included in all copies or substantial portions of the | |
| 17 | − * Software. | |
| 18 | − * | |
| 19 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | − * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 23 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 24 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 25 | − * OTHER DEALINGS IN THE SOFTWARE. | |
| 26 | − * | |
| 27 | − * Authors: | |
| 28 | − * Gareth Hughes <gareth@valinux.com> | |
| 29 | − */ | |
| 30 | − | |
| 31 | −#ifndef __MGA_DRV_H__ | |
| 32 | −#define __MGA_DRV_H__ | |
| 33 | − | |
| 34 | −#include <linux/irqreturn.h> | |
| 35 | −#include <linux/pci.h> | |
| 36 | −#include <linux/slab.h> | |
| 37 | − | |
| 38 | −#include <drm/drm_device.h> | |
| 39 | −#include <drm/drm_file.h> | |
| 40 | −#include <drm/drm_ioctl.h> | |
| 41 | −#include <drm/drm_legacy.h> | |
| 42 | −#include <drm/drm_print.h> | |
| 43 | −#include <drm/drm_sarea.h> | |
| 44 | −#include <drm/drm_vblank.h> | |
| 45 | −#include <drm/mga_drm.h> | |
| 46 | − | |
| 47 | −/* General customization: | |
| 48 | − */ | |
| 49 | − | |
| 50 | −#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." | |
| 51 | − | |
| 52 | −#define DRIVER_NAME "mga" | |
| 53 | −#define DRIVER_DESC "Matrox G200/G400" | |
| 54 | −#define DRIVER_DATE "20051102" | |
| 55 | − | |
| 56 | −#define DRIVER_MAJOR 3 | |
| 57 | −#define DRIVER_MINOR 2 | |
| 58 | −#define DRIVER_PATCHLEVEL 1 | |
| 59 | − | |
| 60 | −typedef struct drm_mga_primary_buffer { | |
| 61 | − u8 *start; | |
| 62 | − u8 *end; | |
| 63 | − int size; | |
| 64 | − | |
| 65 | − u32 tail; | |
| 66 | − int space; | |
| 67 | − volatile long wrapped; | |
| 68 | − | |
| 69 | − volatile u32 *status; | |
| 70 | − | |
| 71 | − u32 last_flush; | |
| 72 | − u32 last_wrap; | |
| 73 | − | |
| 74 | − u32 high_mark; | |
| 75 | −} drm_mga_primary_buffer_t; | |
| 76 | − | |
| 77 | −typedef struct drm_mga_freelist { | |
| 78 | − struct drm_mga_freelist *next; | |
| 79 | − struct drm_mga_freelist *prev; | |
| 80 | − drm_mga_age_t age; | |
| 81 | − struct drm_buf *buf; | |
| 82 | −} drm_mga_freelist_t; | |
| 83 | − | |
| 84 | −typedef struct { | |
| 85 | − drm_mga_freelist_t *list_entry; | |
| 86 | − int discard; | |
| 87 | − int dispatched; | |
| 88 | −} drm_mga_buf_priv_t; | |
| 89 | − | |
| 90 | −typedef struct drm_mga_private { | |
| 91 | − drm_mga_primary_buffer_t prim; | |
| 92 | − drm_mga_sarea_t *sarea_priv; | |
| 93 | − | |
| 94 | − drm_mga_freelist_t *head; | |
| 95 | − drm_mga_freelist_t *tail; | |
| 96 | − | |
| 97 | − unsigned int warp_pipe; | |
| 98 | − unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES]; | |
| 99 | − | |
| 100 | − int chipset; | |
| 101 | − int usec_timeout; | |
| 102 | − | |
| 103 | − /** | |
| 104 | − * If set, the new DMA initialization sequence was used. This is | |
| 105 | − * primarilly used to select how the driver should uninitialized its | |
| 106 | − * internal DMA structures. | |
| 107 | − */ | |
| 108 | − int used_new_dma_init; | |
| 109 | − | |
| 110 | − /** | |
| 111 | − * If AGP memory is used for DMA buffers, this will be the value | |
| 112 | − * \c MGA_PAGPXFER. Otherwise, it will be zero (for a PCI transfer). | |
| 113 | − */ | |
| 114 | − u32 dma_access; | |
| 115 | − | |
| 116 | − /** | |
| 117 | − * If AGP memory is used for DMA buffers, this will be the value | |
| 118 | − * \c MGA_WAGP_ENABLE. Otherwise, it will be zero (for a PCI | |
| 119 | − * transfer). | |
| 120 | − */ | |
| 121 | − u32 wagp_enable; | |
| 122 | − | |
| 123 | − /** | |
| 124 | − * \name MMIO region parameters. | |
| 125 | − * | |
| 126 | − * \sa drm_mga_private_t::mmio | |
| 127 | − */ | |
| 128 | − /*@{ */ | |
| 129 | − resource_size_t mmio_base; /**< Bus address of base of MMIO. */ | |
| 130 | − resource_size_t mmio_size; /**< Size of the MMIO region. */ | |
| 131 | − /*@} */ | |
| 132 | − | |
| 133 | − u32 clear_cmd; | |
| 134 | − u32 maccess; | |
| 135 | − | |
| 136 | − atomic_t vbl_received; /**< Number of vblanks received. */ | |
| 137 | − wait_queue_head_t fence_queue; | |
| 138 | − atomic_t last_fence_retired; | |
| 139 | − u32 next_fence_to_post; | |
| 140 | − | |
| 141 | − unsigned int fb_cpp; | |
| 142 | − unsigned int front_offset; | |
| 143 | − unsigned int front_pitch; | |
| 144 | − unsigned int back_offset; | |
| 145 | − unsigned int back_pitch; | |
| 146 | − | |
| 147 | − unsigned int depth_cpp; | |
| 148 | − unsigned int depth_offset; | |
| 149 | − unsigned int depth_pitch; | |
| 150 | − | |
| 151 | − unsigned int texture_offset; | |
| 152 | − unsigned int texture_size; | |
| 153 | − | |
| 154 | − drm_local_map_t *sarea; | |
| 155 | − drm_local_map_t *mmio; | |
| 156 | − drm_local_map_t *status; | |
| 157 | − drm_local_map_t *warp; | |
| 158 | − drm_local_map_t *primary; | |
| 159 | − drm_local_map_t *agp_textures; | |
| 160 | − | |
| 161 | − unsigned long agp_handle; | |
| 162 | − unsigned int agp_size; | |
| 163 | −} drm_mga_private_t; | |
| 164 | − | |
| 165 | −extern const struct drm_ioctl_desc mga_ioctls[]; | |
| 166 | −extern int mga_max_ioctl; | |
| 167 | − | |
| 168 | − /* mga_dma.c */ | |
| 169 | −extern int mga_dma_bootstrap(struct drm_device *dev, void *data, | |
| 170 | − struct drm_file *file_priv); | |
| 171 | −extern int mga_dma_init(struct drm_device *dev, void *data, | |
| 172 | − struct drm_file *file_priv); | |
| 173 | −extern int mga_getparam(struct drm_device *dev, void *data, | |
| 174 | − struct drm_file *file_priv); | |
| 175 | −extern int mga_dma_flush(struct drm_device *dev, void *data, | |
| 176 | − struct drm_file *file_priv); | |
| 177 | −extern int mga_dma_reset(struct drm_device *dev, void *data, | |
| 178 | − struct drm_file *file_priv); | |
| 179 | −extern int mga_dma_buffers(struct drm_device *dev, void *data, | |
| 180 | − struct drm_file *file_priv); | |
| 181 | −extern int mga_driver_load(struct drm_device *dev, unsigned long flags); | |
| 182 | −extern void mga_driver_unload(struct drm_device *dev); | |
| 183 | −extern void mga_driver_lastclose(struct drm_device *dev); | |
| 184 | −extern int mga_driver_dma_quiescent(struct drm_device *dev); | |
| 185 | − | |
| 186 | −extern int mga_do_wait_for_idle(drm_mga_private_t *dev_priv); | |
| 187 | − | |
| 188 | −extern void mga_do_dma_flush(drm_mga_private_t *dev_priv); | |
| 189 | −extern void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv); | |
| 190 | −extern void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv); | |
| 191 | − | |
| 192 | −extern int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf); | |
| 193 | − | |
| 194 | − /* mga_warp.c */ | |
| 195 | −extern int mga_warp_install_microcode(drm_mga_private_t *dev_priv); | |
| 196 | −extern int mga_warp_init(drm_mga_private_t *dev_priv); | |
| 197 | − | |
| 198 | − /* mga_irq.c */ | |
| 199 | −extern int mga_enable_vblank(struct drm_device *dev, unsigned int pipe); | |
| 200 | −extern void mga_disable_vblank(struct drm_device *dev, unsigned int pipe); | |
| 201 | −extern u32 mga_get_vblank_counter(struct drm_device *dev, unsigned int pipe); | |
| 202 | −extern void mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence); | |
| 203 | −extern int mga_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); | |
| 204 | −extern irqreturn_t mga_driver_irq_handler(int irq, void *arg); | |
| 205 | −extern void mga_driver_irq_preinstall(struct drm_device *dev); | |
| 206 | −extern int mga_driver_irq_postinstall(struct drm_device *dev); | |
| 207 | −extern void mga_driver_irq_uninstall(struct drm_device *dev); | |
| 208 | −extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, | |
| 209 | − unsigned long arg); | |
| 210 | − | |
| 211 | −#define mga_flush_write_combine() wmb() | |
| 212 | − | |
| 213 | −#define MGA_READ8(reg) \ | |
| 214 | − readb(((void __iomem *)dev_priv->mmio->handle) + (reg)) | |
| 215 | −#define MGA_READ(reg) \ | |
| 216 | − readl(((void __iomem *)dev_priv->mmio->handle) + (reg)) | |
| 217 | −#define MGA_WRITE8(reg, val) \ | |
| 218 | − writeb(val, ((void __iomem *)dev_priv->mmio->handle) + (reg)) | |
| 219 | −#define MGA_WRITE(reg, val) \ | |
| 220 | − writel(val, ((void __iomem *)dev_priv->mmio->handle) + (reg)) | |
| 221 | − | |
| 222 | −#define DWGREG0 0x1c00 | |
| 223 | −#define DWGREG0_END 0x1dff | |
| 224 | −#define DWGREG1 0x2c00 | |
| 225 | −#define DWGREG1_END 0x2dff | |
| 226 | − | |
| 227 | −#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) | |
| 228 | −#define DMAREG0(r) (u8)((r - DWGREG0) >> 2) | |
| 229 | −#define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) | |
| 230 | −#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r)) | |
| 231 | − | |
| 232 | −/* ================================================================ | |
| 233 | − * Helper macross... | |
| 234 | − */ | |
| 235 | − | |
| 236 | −#define MGA_EMIT_STATE(dev_priv, dirty) \ | |
| 237 | −do { \ | |
| 238 | − if ((dirty) & ~MGA_UPLOAD_CLIPRECTS) { \ | |
| 239 | − if (dev_priv->chipset >= MGA_CARD_TYPE_G400) \ | |
| 240 | − mga_g400_emit_state(dev_priv); \ | |
| 241 | − else \ | |
| 242 | − mga_g200_emit_state(dev_priv); \ | |
| 243 | − } \ | |
| 244 | −} while (0) | |
| 245 | − | |
| 246 | −#define WRAP_TEST_WITH_RETURN(dev_priv) \ | |
| 247 | −do { \ | |
| 248 | − if (test_bit(0, &dev_priv->prim.wrapped)) { \ | |
| 249 | − if (mga_is_idle(dev_priv)) { \ | |
| 250 | − mga_do_dma_wrap_end(dev_priv); \ | |
| 251 | − } else if (dev_priv->prim.space < \ | |
| 252 | − dev_priv->prim.high_mark) { \ | |
| 253 | − if (MGA_DMA_DEBUG) \ | |
| 254 | − DRM_INFO("wrap...\n"); \ | |
| 255 | − return -EBUSY; \ | |
| 256 | − } \ | |
| 257 | − } \ | |
| 258 | −} while (0) | |
| 259 | − | |
| 260 | −#define WRAP_WAIT_WITH_RETURN(dev_priv) \ | |
| 261 | −do { \ | |
| 262 | − if (test_bit(0, &dev_priv->prim.wrapped)) { \ | |
| 263 | − if (mga_do_wait_for_idle(dev_priv) < 0) { \ | |
| 264 | − if (MGA_DMA_DEBUG) \ | |
| 265 | − DRM_INFO("wrap...\n"); \ | |
| 266 | − return -EBUSY; \ | |
| 267 | − } \ | |
| 268 | − mga_do_dma_wrap_end(dev_priv); \ | |
| 269 | − } \ | |
| 270 | −} while (0) | |
| 271 | − | |
| 272 | −/* ================================================================ | |
| 273 | − * Primary DMA command stream | |
| 274 | − */ | |
| 275 | − | |
| 276 | −#define MGA_VERBOSE 0 | |
| 277 | − | |
| 278 | −#define DMA_LOCALS unsigned int write; volatile u8 *prim; | |
| 279 | − | |
| 280 | −#define DMA_BLOCK_SIZE (5 * sizeof(u32)) | |
| 281 | − | |
| 282 | −#define BEGIN_DMA(n) \ | |
| 283 | −do { \ | |
| 284 | − if (MGA_VERBOSE) { \ | |
| 285 | − DRM_INFO("BEGIN_DMA(%d)\n", (n)); \ | |
| 286 | − DRM_INFO(" space=0x%x req=0x%zx\n", \ | |
| 287 | − dev_priv->prim.space, (n) * DMA_BLOCK_SIZE); \ | |
| 288 | − } \ | |
| 289 | − prim = dev_priv->prim.start; \ | |
| 290 | − write = dev_priv->prim.tail; \ | |
| 291 | −} while (0) | |
| 292 | − | |
| 293 | −#define BEGIN_DMA_WRAP() \ | |
| 294 | −do { \ | |
| 295 | − if (MGA_VERBOSE) { \ | |
| 296 | − DRM_INFO("BEGIN_DMA()\n"); \ | |
| 297 | − DRM_INFO(" space=0x%x\n", dev_priv->prim.space); \ | |
| 298 | − } \ | |
| 299 | − prim = dev_priv->prim.start; \ | |
| 300 | − write = dev_priv->prim.tail; \ | |
| 301 | −} while (0) | |
| 302 | − | |
| 303 | −#define ADVANCE_DMA() \ | |
| 304 | −do { \ | |
| 305 | − dev_priv->prim.tail = write; \ | |
| 306 | − if (MGA_VERBOSE) \ | |
| 307 | − DRM_INFO("ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ | |
| 308 | − write, dev_priv->prim.space); \ | |
| 309 | −} while (0) | |
| 310 | − | |
| 311 | −#define FLUSH_DMA() \ | |
| 312 | −do { \ | |
| 313 | − if (0) { \ | |
| 314 | − DRM_INFO("\n"); \ | |
| 315 | − DRM_INFO(" tail=0x%06x head=0x%06lx\n", \ | |
| 316 | − dev_priv->prim.tail, \ | |
| 317 | − (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ | |
| 318 | − dev_priv->primary->offset)); \ | |
| 319 | − } \ | |
| 320 | − if (!test_bit(0, &dev_priv->prim.wrapped)) { \ | |
| 321 | − if (dev_priv->prim.space < dev_priv->prim.high_mark) \ | |
| 322 | − mga_do_dma_wrap_start(dev_priv); \ | |
| 323 | − else \ | |
| 324 | − mga_do_dma_flush(dev_priv); \ | |
| 325 | − } \ | |
| 326 | −} while (0) | |
| 327 | − | |
| 328 | −/* Never use this, always use DMA_BLOCK(...) for primary DMA output. | |
| 329 | − */ | |
| 330 | −#define DMA_WRITE(offset, val) \ | |
| 331 | −do { \ | |
| 332 | − if (MGA_VERBOSE) \ | |
| 333 | − DRM_INFO(" DMA_WRITE( 0x%08x ) at 0x%04zx\n", \ | |
| 334 | − (u32)(val), write + (offset) * sizeof(u32)); \ | |
| 335 | − *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ | |
| 336 | −} while (0) | |
| 337 | − | |
| 338 | −#define DMA_BLOCK(reg0, val0, reg1, val1, reg2, val2, reg3, val3) \ | |
| 339 | −do { \ | |
| 340 | − DMA_WRITE(0, ((DMAREG(reg0) << 0) | \ | |
| 341 | − (DMAREG(reg1) << 8) | \ | |
| 342 | − (DMAREG(reg2) << 16) | \ | |
| 343 | − (DMAREG(reg3) << 24))); \ | |
| 344 | − DMA_WRITE(1, val0); \ | |
| 345 | − DMA_WRITE(2, val1); \ | |
| 346 | − DMA_WRITE(3, val2); \ | |
| 347 | − DMA_WRITE(4, val3); \ | |
| 348 | − write += DMA_BLOCK_SIZE; \ | |
| 349 | −} while (0) | |
| 350 | − | |
| 351 | −/* Buffer aging via primary DMA stream head pointer. | |
| 352 | − */ | |
| 353 | − | |
| 354 | −#define SET_AGE(age, h, w) \ | |
| 355 | −do { \ | |
| 356 | − (age)->head = h; \ | |
| 357 | − (age)->wrap = w; \ | |
| 358 | −} while (0) | |
| 359 | − | |
| 360 | −#define TEST_AGE(age, h, w) ((age)->wrap < w || \ | |
| 361 | − ((age)->wrap == w && \ | |
| 362 | − (age)->head < h)) | |
| 363 | − | |
| 364 | −#define AGE_BUFFER(buf_priv) \ | |
| 365 | −do { \ | |
| 366 | − drm_mga_freelist_t *entry = (buf_priv)->list_entry; \ | |
| 367 | − if ((buf_priv)->dispatched) { \ | |
| 368 | − entry->age.head = (dev_priv->prim.tail + \ | |
| 369 | − dev_priv->primary->offset); \ | |
| 370 | − entry->age.wrap = dev_priv->sarea_priv->last_wrap; \ | |
| 371 | − } else { \ | |
| 372 | − entry->age.head = 0; \ | |
| 373 | − entry->age.wrap = 0; \ | |
| 374 | − } \ | |
| 375 | −} while (0) | |
| 376 | − | |
| 377 | −#define MGA_ENGINE_IDLE_MASK (MGA_SOFTRAPEN | \ | |
| 378 | − MGA_DWGENGSTS | \ | |
| 379 | − MGA_ENDPRDMASTS) | |
| 380 | −#define MGA_DMA_IDLE_MASK (MGA_SOFTRAPEN | \ | |
| 381 | − MGA_ENDPRDMASTS) | |
| 382 | − | |
| 383 | −#define MGA_DMA_DEBUG 0 | |
| 384 | − | |
| 385 | −/* A reduced set of the mga registers. | |
| 386 | − */ | |
| 387 | −#define MGA_CRTC_INDEX 0x1fd4 | |
| 388 | −#define MGA_CRTC_DATA 0x1fd5 | |
| 389 | − | |
| 390 | −/* CRTC11 */ | |
| 391 | −#define MGA_VINTCLR (1 << 4) | |
| 392 | −#define MGA_VINTEN (1 << 5) | |
| 393 | − | |
| 394 | −#define MGA_ALPHACTRL 0x2c7c | |
| 395 | −#define MGA_AR0 0x1c60 | |
| 396 | −#define MGA_AR1 0x1c64 | |
| 397 | −#define MGA_AR2 0x1c68 | |
| 398 | −#define MGA_AR3 0x1c6c | |
| 399 | −#define MGA_AR4 0x1c70 | |
| 400 | −#define MGA_AR5 0x1c74 | |
| 401 | −#define MGA_AR6 0x1c78 | |
| 402 | − | |
| 403 | −#define MGA_CXBNDRY 0x1c80 | |
| 404 | −#define MGA_CXLEFT 0x1ca0 | |
| 405 | −#define MGA_CXRIGHT 0x1ca4 | |
| 406 | − | |
| 407 | −#define MGA_DMAPAD 0x1c54 | |
| 408 | −#define MGA_DSTORG 0x2cb8 | |
| 409 | −#define MGA_DWGCTL 0x1c00 | |
| 410 | −# define MGA_OPCOD_MASK (15 << 0) | |
| 411 | −# define MGA_OPCOD_TRAP (4 << 0) | |
| 412 | −# define MGA_OPCOD_TEXTURE_TRAP (6 << 0) | |
| 413 | −# define MGA_OPCOD_BITBLT (8 << 0) | |
| 414 | −# define MGA_OPCOD_ILOAD (9 << 0) | |
| 415 | −# define MGA_ATYPE_MASK (7 << 4) | |
| 416 | −# define MGA_ATYPE_RPL (0 << 4) | |
| 417 | −# define MGA_ATYPE_RSTR (1 << 4) | |
| 418 | −# define MGA_ATYPE_ZI (3 << 4) | |
| 419 | −# define MGA_ATYPE_BLK (4 << 4) | |
| 420 | −# define MGA_ATYPE_I (7 << 4) | |
| 421 | −# define MGA_LINEAR (1 << 7) | |
| 422 | −# define MGA_ZMODE_MASK (7 << 8) | |
| 423 | −# define MGA_ZMODE_NOZCMP (0 << 8) | |
| 424 | −# define MGA_ZMODE_ZE (2 << 8) | |
| 425 | −# define MGA_ZMODE_ZNE (3 << 8) | |
| 426 | −# define MGA_ZMODE_ZLT (4 << 8) | |
| 427 | −# define MGA_ZMODE_ZLTE (5 << 8) | |
| 428 | −# define MGA_ZMODE_ZGT (6 << 8) | |
| 429 | −# define MGA_ZMODE_ZGTE (7 << 8) | |
| 430 | −# define MGA_SOLID (1 << 11) | |
| 431 | −# define MGA_ARZERO (1 << 12) | |
| 432 | −# define MGA_SGNZERO (1 << 13) | |
| 433 | −# define MGA_SHIFTZERO (1 << 14) | |
| 434 | −# define MGA_BOP_MASK (15 << 16) | |
| 435 | −# define MGA_BOP_ZERO (0 << 16) | |
| 436 | −# define MGA_BOP_DST (10 << 16) | |
| 437 | −# define MGA_BOP_SRC (12 << 16) | |
| 438 | −# define MGA_BOP_ONE (15 << 16) | |
| 439 | −# define MGA_TRANS_SHIFT 20 | |
| 440 | −# define MGA_TRANS_MASK (15 << 20) | |
| 441 | −# define MGA_BLTMOD_MASK (15 << 25) | |
| 442 | −# define MGA_BLTMOD_BMONOLEF (0 << 25) | |
| 443 | −# define MGA_BLTMOD_BMONOWF (4 << 25) | |
| 444 | −# define MGA_BLTMOD_PLAN (1 << 25) | |
| 445 | −# define MGA_BLTMOD_BFCOL (2 << 25) | |
| 446 | −# define MGA_BLTMOD_BU32BGR (3 << 25) | |
| 447 | −# define MGA_BLTMOD_BU32RGB (7 << 25) | |
| 448 | −# define MGA_BLTMOD_BU24BGR (11 << 25) | |
| 449 | −# define MGA_BLTMOD_BU24RGB (15 << 25) | |
| 450 | −# define MGA_PATTERN (1 << 29) | |
| 451 | −# define MGA_TRANSC (1 << 30) | |
| 452 | −# define MGA_CLIPDIS (1 << 31) | |
| 453 | −#define MGA_DWGSYNC 0x2c4c | |
| 454 | − | |
| 455 | −#define MGA_FCOL 0x1c24 | |
| 456 | −#define MGA_FIFOSTATUS 0x1e10 | |
| 457 | −#define MGA_FOGCOL 0x1cf4 | |
| 458 | −#define MGA_FXBNDRY 0x1c84 | |
| 459 | −#define MGA_FXLEFT 0x1ca8 | |
| 460 | −#define MGA_FXRIGHT 0x1cac | |
| 461 | − | |
| 462 | −#define MGA_ICLEAR 0x1e18 | |
| 463 | −# define MGA_SOFTRAPICLR (1 << 0) | |
| 464 | −# define MGA_VLINEICLR (1 << 5) | |
| 465 | −#define MGA_IEN 0x1e1c | |
| 466 | −# define MGA_SOFTRAPIEN (1 << 0) | |
| 467 | −# define MGA_VLINEIEN (1 << 5) | |
| 468 | − | |
| 469 | −#define MGA_LEN 0x1c5c | |
| 470 | − | |
| 471 | −#define MGA_MACCESS 0x1c04 | |
| 472 | − | |
| 473 | −#define MGA_PITCH 0x1c8c | |
| 474 | −#define MGA_PLNWT 0x1c1c | |
| 475 | −#define MGA_PRIMADDRESS 0x1e58 | |
| 476 | −# define MGA_DMA_GENERAL (0 << 0) | |
| 477 | −# define MGA_DMA_BLIT (1 << 0) | |
| 478 | −# define MGA_DMA_VECTOR (2 << 0) | |
| 479 | −# define MGA_DMA_VERTEX (3 << 0) | |
| 480 | −#define MGA_PRIMEND 0x1e5c | |
| 481 | −# define MGA_PRIMNOSTART (1 << 0) | |
| 482 | −# define MGA_PAGPXFER (1 << 1) | |
| 483 | −#define MGA_PRIMPTR 0x1e50 | |
| 484 | −# define MGA_PRIMPTREN0 (1 << 0) | |
| 485 | −# define MGA_PRIMPTREN1 (1 << 1) | |
| 486 | − | |
| 487 | −#define MGA_RST 0x1e40 | |
| 488 | −# define MGA_SOFTRESET (1 << 0) | |
| 489 | −# define MGA_SOFTEXTRST (1 << 1) | |
| 490 | − | |
| 491 | −#define MGA_SECADDRESS 0x2c40 | |
| 492 | −#define MGA_SECEND 0x2c44 | |
| 493 | −#define MGA_SETUPADDRESS 0x2cd0 | |
| 494 | −#define MGA_SETUPEND 0x2cd4 | |
| 495 | −#define MGA_SGN 0x1c58 | |
| 496 | −#define MGA_SOFTRAP 0x2c48 | |
| 497 | −#define MGA_SRCORG 0x2cb4 | |
| 498 | −# define MGA_SRMMAP_MASK (1 << 0) | |
| 499 | −# define MGA_SRCMAP_FB (0 << 0) | |
| 500 | −# define MGA_SRCMAP_SYSMEM (1 << 0) | |
| 501 | −# define MGA_SRCACC_MASK (1 << 1) | |
| 502 | −# define MGA_SRCACC_PCI (0 << 1) | |
| 503 | −# define MGA_SRCACC_AGP (1 << 1) | |
| 504 | −#define MGA_STATUS 0x1e14 | |
| 505 | −# define MGA_SOFTRAPEN (1 << 0) | |
| 506 | −# define MGA_VSYNCPEN (1 << 4) | |
| 507 | −# define MGA_VLINEPEN (1 << 5) | |
| 508 | −# define MGA_DWGENGSTS (1 << 16) | |
| 509 | −# define MGA_ENDPRDMASTS (1 << 17) | |
| 510 | −#define MGA_STENCIL 0x2cc8 | |
| 511 | −#define MGA_STENCILCTL 0x2ccc | |
| 512 | − | |
| 513 | −#define MGA_TDUALSTAGE0 0x2cf8 | |
| 514 | −#define MGA_TDUALSTAGE1 0x2cfc | |
| 515 | −#define MGA_TEXBORDERCOL 0x2c5c | |
| 516 | −#define MGA_TEXCTL 0x2c30 | |
| 517 | −#define MGA_TEXCTL2 0x2c3c | |
| 518 | −# define MGA_DUALTEX (1 << 7) | |
| 519 | −# define MGA_G400_TC2_MAGIC (1 << 15) | |
| 520 | −# define MGA_MAP1_ENABLE (1 << 31) | |
| 521 | −#define MGA_TEXFILTER 0x2c58 | |
| 522 | −#define MGA_TEXHEIGHT 0x2c2c | |
| 523 | −#define MGA_TEXORG 0x2c24 | |
| 524 | −# define MGA_TEXORGMAP_MASK (1 << 0) | |
| 525 | −# define MGA_TEXORGMAP_FB (0 << 0) | |
| 526 | −# define MGA_TEXORGMAP_SYSMEM (1 << 0) | |
| 527 | −# define MGA_TEXORGACC_MASK (1 << 1) | |
| 528 | −# define MGA_TEXORGACC_PCI (0 << 1) | |
| 529 | −# define MGA_TEXORGACC_AGP (1 << 1) | |
| 530 | −#define MGA_TEXORG1 0x2ca4 | |
| 531 | −#define MGA_TEXORG2 0x2ca8 | |
| 532 | −#define MGA_TEXORG3 0x2cac | |
| 533 | −#define MGA_TEXORG4 0x2cb0 | |
| 534 | −#define MGA_TEXTRANS 0x2c34 | |
| 535 | −#define MGA_TEXTRANSHIGH 0x2c38 | |
| 536 | −#define MGA_TEXWIDTH 0x2c28 | |
| 537 | − | |
| 538 | −#define MGA_WACCEPTSEQ 0x1dd4 | |
| 539 | −#define MGA_WCODEADDR 0x1e6c | |
| 540 | −#define MGA_WFLAG 0x1dc4 | |
| 541 | −#define MGA_WFLAG1 0x1de0 | |
| 542 | −#define MGA_WFLAGNB 0x1e64 | |
| 543 | −#define MGA_WFLAGNB1 0x1e08 | |
| 544 | −#define MGA_WGETMSB 0x1dc8 | |
| 545 | −#define MGA_WIADDR 0x1dc0 | |
| 546 | −#define MGA_WIADDR2 0x1dd8 | |
| 547 | −# define MGA_WMODE_SUSPEND (0 << 0) | |
| 548 | −# define MGA_WMODE_RESUME (1 << 0) | |
| 549 | −# define MGA_WMODE_JUMP (2 << 0) | |
| 550 | −# define MGA_WMODE_START (3 << 0) | |
| 551 | −# define MGA_WAGP_ENABLE (1 << 2) | |
| 552 | −#define MGA_WMISC 0x1e70 | |
| 553 | −# define MGA_WUCODECACHE_ENABLE (1 << 0) | |
| 554 | −# define MGA_WMASTER_ENABLE (1 << 1) | |
| 555 | −# define MGA_WCACHEFLUSH_ENABLE (1 << 3) | |
| 556 | −#define MGA_WVRTXSZ 0x1dcc | |
| 557 | − | |
| 558 | −#define MGA_YBOT 0x1c9c | |
| 559 | −#define MGA_YDST 0x1c90 | |
| 560 | −#define MGA_YDSTLEN 0x1c88 | |
| 561 | −#define MGA_YDSTORG 0x1c94 | |
| 562 | −#define MGA_YTOP 0x1c98 | |
| 563 | − | |
| 564 | −#define MGA_ZORG 0x1c0c | |
| 565 | − | |
| 566 | −/* This finishes the current batch of commands | |
| 567 | − */ | |
| 568 | −#define MGA_EXEC 0x0100 | |
| 569 | − | |
| 570 | −/* AGP PLL encoding (for G200 only). | |
| 571 | − */ | |
| 572 | −#define MGA_AGP_PLL 0x1e4c | |
| 573 | −# define MGA_AGP2XPLL_DISABLE (0 << 0) | |
| 574 | −# define MGA_AGP2XPLL_ENABLE (1 << 0) | |
| 575 | − | |
| 576 | −/* Warp registers | |
| 577 | − */ | |
| 578 | −#define MGA_WR0 0x2d00 | |
| 579 | −#define MGA_WR1 0x2d04 | |
| 580 | −#define MGA_WR2 0x2d08 | |
| 581 | −#define MGA_WR3 0x2d0c | |
| 582 | −#define MGA_WR4 0x2d10 | |
| 583 | −#define MGA_WR5 0x2d14 | |
| 584 | −#define MGA_WR6 0x2d18 | |
| 585 | −#define MGA_WR7 0x2d1c | |
| 586 | −#define MGA_WR8 0x2d20 | |
| 587 | −#define MGA_WR9 0x2d24 | |
| 588 | −#define MGA_WR10 0x2d28 | |
| 589 | −#define MGA_WR11 0x2d2c | |
| 590 | −#define MGA_WR12 0x2d30 | |
| 591 | −#define MGA_WR13 0x2d34 | |
| 592 | −#define MGA_WR14 0x2d38 | |
| 593 | −#define MGA_WR15 0x2d3c | |
| 594 | −#define MGA_WR16 0x2d40 | |
| 595 | −#define MGA_WR17 0x2d44 | |
| 596 | −#define MGA_WR18 0x2d48 | |
| 597 | −#define MGA_WR19 0x2d4c | |
| 598 | −#define MGA_WR20 0x2d50 | |
| 599 | −#define MGA_WR21 0x2d54 | |
| 600 | −#define MGA_WR22 0x2d58 | |
| 601 | −#define MGA_WR23 0x2d5c | |
| 602 | −#define MGA_WR24 0x2d60 | |
| 603 | −#define MGA_WR25 0x2d64 | |
| 604 | −#define MGA_WR26 0x2d68 | |
| 605 | −#define MGA_WR27 0x2d6c | |
| 606 | −#define MGA_WR28 0x2d70 | |
| 607 | −#define MGA_WR29 0x2d74 | |
| 608 | −#define MGA_WR30 0x2d78 | |
| 609 | −#define MGA_WR31 0x2d7c | |
| 610 | −#define MGA_WR32 0x2d80 | |
| 611 | −#define MGA_WR33 0x2d84 | |
| 612 | −#define MGA_WR34 0x2d88 | |
| 613 | −#define MGA_WR35 0x2d8c | |
| 614 | −#define MGA_WR36 0x2d90 | |
| 615 | −#define MGA_WR37 0x2d94 | |
| 616 | −#define MGA_WR38 0x2d98 | |
| 617 | −#define MGA_WR39 0x2d9c | |
| 618 | −#define MGA_WR40 0x2da0 | |
| 619 | −#define MGA_WR41 0x2da4 | |
| 620 | −#define MGA_WR42 0x2da8 | |
| 621 | −#define MGA_WR43 0x2dac | |
| 622 | −#define MGA_WR44 0x2db0 | |
| 623 | −#define MGA_WR45 0x2db4 | |
| 624 | −#define MGA_WR46 0x2db8 | |
| 625 | −#define MGA_WR47 0x2dbc | |
| 626 | −#define MGA_WR48 0x2dc0 | |
| 627 | −#define MGA_WR49 0x2dc4 | |
| 628 | −#define MGA_WR50 0x2dc8 | |
| 629 | −#define MGA_WR51 0x2dcc | |
| 630 | −#define MGA_WR52 0x2dd0 | |
| 631 | −#define MGA_WR53 0x2dd4 | |
| 632 | −#define MGA_WR54 0x2dd8 | |
| 633 | −#define MGA_WR55 0x2ddc | |
| 634 | −#define MGA_WR56 0x2de0 | |
| 635 | −#define MGA_WR57 0x2de4 | |
| 636 | −#define MGA_WR58 0x2de8 | |
| 637 | −#define MGA_WR59 0x2dec | |
| 638 | −#define MGA_WR60 0x2df0 | |
| 639 | −#define MGA_WR61 0x2df4 | |
| 640 | −#define MGA_WR62 0x2df8 | |
| 641 | −#define MGA_WR63 0x2dfc | |
| 642 | −# define MGA_G400_WR_MAGIC (1 << 6) | |
| 643 | −# define MGA_G400_WR56_MAGIC 0x46480000 /* 12800.0f */ | |
| 644 | − | |
| 645 | −#define MGA_ILOAD_ALIGN 64 | |
| 646 | −#define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1) | |
| 647 | − | |
| 648 | −#define MGA_DWGCTL_FLUSH (MGA_OPCOD_TEXTURE_TRAP | \ | |
| 649 | − MGA_ATYPE_I | \ | |
| 650 | − MGA_ZMODE_NOZCMP | \ | |
| 651 | − MGA_ARZERO | \ | |
| 652 | − MGA_SGNZERO | \ | |
| 653 | − MGA_BOP_SRC | \ | |
| 654 | − (15 << MGA_TRANS_SHIFT)) | |
| 655 | − | |
| 656 | −#define MGA_DWGCTL_CLEAR (MGA_OPCOD_TRAP | \ | |
| 657 | − MGA_ZMODE_NOZCMP | \ | |
| 658 | − MGA_SOLID | \ | |
| 659 | − MGA_ARZERO | \ | |
| 660 | − MGA_SGNZERO | \ | |
| 661 | − MGA_SHIFTZERO | \ | |
| 662 | − MGA_BOP_SRC | \ | |
| 663 | − (0 << MGA_TRANS_SHIFT) | \ | |
| 664 | − MGA_BLTMOD_BMONOLEF | \ | |
| 665 | − MGA_TRANSC | \ | |
| 666 | − MGA_CLIPDIS) | |
| 667 | − | |
| 668 | −#define MGA_DWGCTL_COPY (MGA_OPCOD_BITBLT | \ | |
| 669 | − MGA_ATYPE_RPL | \ | |
| 670 | − MGA_SGNZERO | \ | |
| 671 | − MGA_SHIFTZERO | \ | |
| 672 | − MGA_BOP_SRC | \ | |
| 673 | − (0 << MGA_TRANS_SHIFT) | \ | |
| 674 | − MGA_BLTMOD_BFCOL | \ | |
| 675 | − MGA_CLIPDIS) | |
| 676 | − | |
| 677 | −/* Simple idle test. | |
| 678 | − */ | |
| 679 | −static __inline__ int mga_is_idle(drm_mga_private_t *dev_priv) | |
| 680 | −{ | |
| 681 | − u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; | |
| 682 | − return (status == MGA_ENDPRDMASTS); | |
| 683 | −} | |
| 684 | − | |
| 685 | −#endif | |
| @@ -1,197 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * \file mga_ioc32.c | |
| 3 | − * | |
| 4 | − * 32-bit ioctl compatibility routines for the MGA DRM. | |
| 5 | − * | |
| 6 | − * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich | |
| 7 | − * | |
| 8 | − * | |
| 9 | − * Copyright (C) Paul Mackerras 2005 | |
| 10 | − * Copyright (C) Egbert Eich 2003,2004 | |
| 11 | − * Copyright (C) Dave Airlie 2005 | |
| 12 | − * All Rights Reserved. | |
| 13 | − * | |
| 14 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 15 | − * copy of this software and associated documentation files (the "Software"), | |
| 16 | − * to deal in the Software without restriction, including without limitation | |
| 17 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 18 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 19 | − * Software is furnished to do so, subject to the following conditions: | |
| 20 | − * | |
| 21 | − * The above copyright notice and this permission notice (including the next | |
| 22 | − * paragraph) shall be included in all copies or substantial portions of the | |
| 23 | − * Software. | |
| 24 | − * | |
| 25 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 26 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 27 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 28 | − * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
| 29 | − * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 30 | − * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 31 | − * IN THE SOFTWARE. | |
| 32 | − */ | |
| 33 | − | |
| 34 | −#include <linux/compat.h> | |
| 35 | − | |
| 36 | −#include "mga_drv.h" | |
| 37 | − | |
| 38 | −typedef struct drm32_mga_init { | |
| 39 | − int func; | |
| 40 | − u32 sarea_priv_offset; | |
| 41 | − struct_group(always32bit, | |
| 42 | − int chipset; | |
| 43 | − int sgram; | |
| 44 | − unsigned int maccess; | |
| 45 | − unsigned int fb_cpp; | |
| 46 | − unsigned int front_offset, front_pitch; | |
| 47 | − unsigned int back_offset, back_pitch; | |
| 48 | − unsigned int depth_cpp; | |
| 49 | − unsigned int depth_offset, depth_pitch; | |
| 50 | − unsigned int texture_offset[MGA_NR_TEX_HEAPS]; | |
| 51 | − unsigned int texture_size[MGA_NR_TEX_HEAPS]; | |
| 52 | − ); | |
| 53 | − u32 fb_offset; | |
| 54 | − u32 mmio_offset; | |
| 55 | − u32 status_offset; | |
| 56 | − u32 warp_offset; | |
| 57 | − u32 primary_offset; | |
| 58 | − u32 buffers_offset; | |
| 59 | −} drm_mga_init32_t; | |
| 60 | − | |
| 61 | −static int compat_mga_init(struct file *file, unsigned int cmd, | |
| 62 | − unsigned long arg) | |
| 63 | −{ | |
| 64 | − drm_mga_init32_t init32; | |
| 65 | − drm_mga_init_t init; | |
| 66 | − | |
| 67 | − if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) | |
| 68 | − return -EFAULT; | |
| 69 | − | |
| 70 | − init.func = init32.func; | |
| 71 | − init.sarea_priv_offset = init32.sarea_priv_offset; | |
| 72 | − memcpy(&init.always32bit, &init32.always32bit, | |
| 73 | − sizeof(init32.always32bit)); | |
| 74 | − init.fb_offset = init32.fb_offset; | |
| 75 | − init.mmio_offset = init32.mmio_offset; | |
| 76 | − init.status_offset = init32.status_offset; | |
| 77 | − init.warp_offset = init32.warp_offset; | |
| 78 | − init.primary_offset = init32.primary_offset; | |
| 79 | − init.buffers_offset = init32.buffers_offset; | |
| 80 | − | |
| 81 | − return drm_ioctl_kernel(file, mga_dma_init, &init, | |
| 82 | − DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); | |
| 83 | −} | |
| 84 | − | |
| 85 | −typedef struct drm_mga_getparam32 { | |
| 86 | − int param; | |
| 87 | − u32 value; | |
| 88 | −} drm_mga_getparam32_t; | |
| 89 | − | |
| 90 | −static int compat_mga_getparam(struct file *file, unsigned int cmd, | |
| 91 | − unsigned long arg) | |
| 92 | −{ | |
| 93 | − drm_mga_getparam32_t getparam32; | |
| 94 | − drm_mga_getparam_t getparam; | |
| 95 | − | |
| 96 | − if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) | |
| 97 | − return -EFAULT; | |
| 98 | − | |
| 99 | − getparam.param = getparam32.param; | |
| 100 | − getparam.value = compat_ptr(getparam32.value); | |
| 101 | − return drm_ioctl_kernel(file, mga_getparam, &getparam, DRM_AUTH); | |
| 102 | −} | |
| 103 | − | |
| 104 | −typedef struct drm_mga_drm_bootstrap32 { | |
| 105 | − u32 texture_handle; | |
| 106 | − u32 texture_size; | |
| 107 | − u32 primary_size; | |
| 108 | − u32 secondary_bin_count; | |
| 109 | − u32 secondary_bin_size; | |
| 110 | − u32 agp_mode; | |
| 111 | − u8 agp_size; | |
| 112 | −} drm_mga_dma_bootstrap32_t; | |
| 113 | − | |
| 114 | −static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, | |
| 115 | − unsigned long arg) | |
| 116 | −{ | |
| 117 | − drm_mga_dma_bootstrap32_t dma_bootstrap32; | |
| 118 | − drm_mga_dma_bootstrap_t dma_bootstrap; | |
| 119 | − int err; | |
| 120 | − | |
| 121 | − if (copy_from_user(&dma_bootstrap32, (void __user *)arg, | |
| 122 | − sizeof(dma_bootstrap32))) | |
| 123 | − return -EFAULT; | |
| 124 | − | |
| 125 | − dma_bootstrap.texture_handle = dma_bootstrap32.texture_handle; | |
| 126 | − dma_bootstrap.texture_size = dma_bootstrap32.texture_size; | |
| 127 | − dma_bootstrap.primary_size = dma_bootstrap32.primary_size; | |
| 128 | − dma_bootstrap.secondary_bin_count = dma_bootstrap32.secondary_bin_count; | |
| 129 | − dma_bootstrap.secondary_bin_size = dma_bootstrap32.secondary_bin_size; | |
| 130 | − dma_bootstrap.agp_mode = dma_bootstrap32.agp_mode; | |
| 131 | − dma_bootstrap.agp_size = dma_bootstrap32.agp_size; | |
| 132 | − | |
| 133 | − err = drm_ioctl_kernel(file, mga_dma_bootstrap, &dma_bootstrap, | |
| 134 | − DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); | |
| 135 | − if (err) | |
| 136 | − return err; | |
| 137 | − | |
| 138 | − dma_bootstrap32.texture_handle = dma_bootstrap.texture_handle; | |
| 139 | − dma_bootstrap32.texture_size = dma_bootstrap.texture_size; | |
| 140 | − dma_bootstrap32.primary_size = dma_bootstrap.primary_size; | |
| 141 | − dma_bootstrap32.secondary_bin_count = dma_bootstrap.secondary_bin_count; | |
| 142 | − dma_bootstrap32.secondary_bin_size = dma_bootstrap.secondary_bin_size; | |
| 143 | − dma_bootstrap32.agp_mode = dma_bootstrap.agp_mode; | |
| 144 | − dma_bootstrap32.agp_size = dma_bootstrap.agp_size; | |
| 145 | − if (copy_to_user((void __user *)arg, &dma_bootstrap32, | |
| 146 | − sizeof(dma_bootstrap32))) | |
| 147 | − return -EFAULT; | |
| 148 | − | |
| 149 | − return 0; | |
| 150 | −} | |
| 151 | − | |
| 152 | −static struct { | |
| 153 | − drm_ioctl_compat_t *fn; | |
| 154 | − char *name; | |
| 155 | −} mga_compat_ioctls[] = { | |
| 156 | −#define DRM_IOCTL32_DEF(n, f)[DRM_##n] = {.fn = f, .name = #n} | |
| 157 | − DRM_IOCTL32_DEF(MGA_INIT, compat_mga_init), | |
| 158 | − DRM_IOCTL32_DEF(MGA_GETPARAM, compat_mga_getparam), | |
| 159 | − DRM_IOCTL32_DEF(MGA_DMA_BOOTSTRAP, compat_mga_dma_bootstrap), | |
| 160 | −}; | |
| 161 | − | |
| 162 | −/** | |
| 163 | − * mga_compat_ioctl - Called whenever a 32-bit process running under | |
| 164 | − * a 64-bit kernel performs an ioctl on /dev/dri/card<n>. | |
| 165 | − * | |
| 166 | − * @filp: file pointer. | |
| 167 | − * @cmd: command. | |
| 168 | − * @arg: user argument. | |
| 169 | − * return: zero on success or negative number on failure. | |
| 170 | − */ | |
| 171 | −long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |
| 172 | −{ | |
| 173 | − unsigned int nr = DRM_IOCTL_NR(cmd); | |
| 174 | − struct drm_file *file_priv = filp->private_data; | |
| 175 | − drm_ioctl_compat_t *fn = NULL; | |
| 176 | − int ret; | |
| 177 | − | |
| 178 | − if (nr < DRM_COMMAND_BASE) | |
| 179 | − return drm_compat_ioctl(filp, cmd, arg); | |
| 180 | − | |
| 181 | − if (nr >= DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls)) | |
| 182 | − return drm_ioctl(filp, cmd, arg); | |
| 183 | − | |
| 184 | − fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE].fn; | |
| 185 | − if (!fn) | |
| 186 | − return drm_ioctl(filp, cmd, arg); | |
| 187 | − | |
| 188 | − DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", | |
| 189 | − task_pid_nr(current), | |
| 190 | − (long)old_encode_dev(file_priv->minor->kdev->devt), | |
| 191 | − file_priv->authenticated, | |
| 192 | − mga_compat_ioctls[nr - DRM_COMMAND_BASE].name); | |
| 193 | − ret = (*fn) (filp, cmd, arg); | |
| 194 | − if (ret) | |
| 195 | − DRM_DEBUG("ret = %d\n", ret); | |
| 196 | − return ret; | |
| 197 | −} | |
| @@ -1,169 +0,0 @@ | ||
| 1 | −/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- | |
| 2 | − */ | |
| 3 | −/* | |
| 4 | − * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. | |
| 5 | − * | |
| 6 | − * The Weather Channel (TM) funded Tungsten Graphics to develop the | |
| 7 | − * initial release of the Radeon 8500 driver under the XFree86 license. | |
| 8 | − * This notice must be preserved. | |
| 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 | − * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 25 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 26 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 27 | − * DEALINGS IN THE SOFTWARE. | |
| 28 | − * | |
| 29 | − * Authors: | |
| 30 | − * Keith Whitwell <keith@tungstengraphics.com> | |
| 31 | − * Eric Anholt <anholt@FreeBSD.org> | |
| 32 | − */ | |
| 33 | − | |
| 34 | −#include "mga_drv.h" | |
| 35 | − | |
| 36 | −u32 mga_get_vblank_counter(struct drm_device *dev, unsigned int pipe) | |
| 37 | −{ | |
| 38 | − const drm_mga_private_t *const dev_priv = | |
| 39 | − (drm_mga_private_t *) dev->dev_private; | |
| 40 | − | |
| 41 | − if (pipe != 0) | |
| 42 | − return 0; | |
| 43 | − | |
| 44 | − return atomic_read(&dev_priv->vbl_received); | |
| 45 | −} | |
| 46 | − | |
| 47 | − | |
| 48 | −irqreturn_t mga_driver_irq_handler(int irq, void *arg) | |
| 49 | −{ | |
| 50 | − struct drm_device *dev = (struct drm_device *) arg; | |
| 51 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 52 | − int status; | |
| 53 | − int handled = 0; | |
| 54 | − | |
| 55 | − status = MGA_READ(MGA_STATUS); | |
| 56 | − | |
| 57 | − /* VBLANK interrupt */ | |
| 58 | − if (status & MGA_VLINEPEN) { | |
| 59 | − MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); | |
| 60 | − atomic_inc(&dev_priv->vbl_received); | |
| 61 | − drm_handle_vblank(dev, 0); | |
| 62 | − handled = 1; | |
| 63 | − } | |
| 64 | − | |
| 65 | − /* SOFTRAP interrupt */ | |
| 66 | − if (status & MGA_SOFTRAPEN) { | |
| 67 | − const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); | |
| 68 | − const u32 prim_end = MGA_READ(MGA_PRIMEND); | |
| 69 | − | |
| 70 | − | |
| 71 | − MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); | |
| 72 | − | |
| 73 | − /* In addition to clearing the interrupt-pending bit, we | |
| 74 | − * have to write to MGA_PRIMEND to re-start the DMA operation. | |
| 75 | − */ | |
| 76 | − if ((prim_start & ~0x03) != (prim_end & ~0x03)) | |
| 77 | − MGA_WRITE(MGA_PRIMEND, prim_end); | |
| 78 | − | |
| 79 | − atomic_inc(&dev_priv->last_fence_retired); | |
| 80 | − wake_up(&dev_priv->fence_queue); | |
| 81 | − handled = 1; | |
| 82 | − } | |
| 83 | − | |
| 84 | − if (handled) | |
| 85 | − return IRQ_HANDLED; | |
| 86 | − return IRQ_NONE; | |
| 87 | −} | |
| 88 | − | |
| 89 | −int mga_enable_vblank(struct drm_device *dev, unsigned int pipe) | |
| 90 | −{ | |
| 91 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 92 | − | |
| 93 | − if (pipe != 0) { | |
| 94 | − DRM_ERROR("tried to enable vblank on non-existent crtc %u\n", | |
| 95 | − pipe); | |
| 96 | − return 0; | |
| 97 | − } | |
| 98 | − | |
| 99 | − MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); | |
| 100 | − return 0; | |
| 101 | −} | |
| 102 | − | |
| 103 | − | |
| 104 | −void mga_disable_vblank(struct drm_device *dev, unsigned int pipe) | |
| 105 | −{ | |
| 106 | − if (pipe != 0) { | |
| 107 | − DRM_ERROR("tried to disable vblank on non-existent crtc %u\n", | |
| 108 | − pipe); | |
| 109 | − } | |
| 110 | − | |
| 111 | − /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have | |
| 112 | − * a nice hardware counter that tracks the number of refreshes when | |
| 113 | − * the interrupt is disabled, and the kernel doesn't know the refresh | |
| 114 | − * rate to calculate an estimate. | |
| 115 | − */ | |
| 116 | − /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ | |
| 117 | −} | |
| 118 | − | |
| 119 | −void mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence) | |
| 120 | −{ | |
| 121 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 122 | − unsigned int cur_fence; | |
| 123 | − | |
| 124 | − /* Assume that the user has missed the current sequence number | |
| 125 | − * by about a day rather than she wants to wait for years | |
| 126 | − * using fences. | |
| 127 | − */ | |
| 128 | − wait_event_timeout(dev_priv->fence_queue, | |
| 129 | − (((cur_fence = atomic_read(&dev_priv->last_fence_retired)) | |
| 130 | − - *sequence) <= (1 << 23)), | |
| 131 | − msecs_to_jiffies(3000)); | |
| 132 | − | |
| 133 | − *sequence = cur_fence; | |
| 134 | −} | |
| 135 | − | |
| 136 | −void mga_driver_irq_preinstall(struct drm_device *dev) | |
| 137 | −{ | |
| 138 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 139 | − | |
| 140 | − /* Disable *all* interrupts */ | |
| 141 | − MGA_WRITE(MGA_IEN, 0); | |
| 142 | − /* Clear bits if they're already high */ | |
| 143 | − MGA_WRITE(MGA_ICLEAR, ~0); | |
| 144 | −} | |
| 145 | − | |
| 146 | −int mga_driver_irq_postinstall(struct drm_device *dev) | |
| 147 | −{ | |
| 148 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 149 | − | |
| 150 | − init_waitqueue_head(&dev_priv->fence_queue); | |
| 151 | − | |
| 152 | − /* Turn on soft trap interrupt. Vertical blank interrupts are enabled | |
| 153 | − * in mga_enable_vblank. | |
| 154 | − */ | |
| 155 | − MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); | |
| 156 | − return 0; | |
| 157 | −} | |
| 158 | − | |
| 159 | −void mga_driver_irq_uninstall(struct drm_device *dev) | |
| 160 | −{ | |
| 161 | − drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | |
| 162 | − if (!dev_priv) | |
| 163 | − return; | |
| 164 | − | |
| 165 | − /* Disable *all* interrupts */ | |
| 166 | − MGA_WRITE(MGA_IEN, 0); | |
| 167 | − | |
| 168 | − dev->irq_enabled = false; | |
| 169 | −} | |
| @@ -1,1099 +0,0 @@ | ||
| 1 | −/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*- | |
| 2 | − * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com | |
| 3 | − * | |
| 4 | − * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | |
| 5 | − * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | |
| 6 | − * All Rights Reserved. | |
| 7 | − * | |
| 8 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | − * copy of this software and associated documentation files (the "Software"), | |
| 10 | − * to deal in the Software without restriction, including without limitation | |
| 11 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | − * Software is furnished to do so, subject to the following conditions: | |
| 14 | − * | |
| 15 | − * The above copyright notice and this permission notice (including the next | |
| 16 | − * paragraph) shall be included in all copies or substantial portions of the | |
| 17 | − * Software. | |
| 18 | − * | |
| 19 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | − * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 23 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 24 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 25 | − * OTHER DEALINGS IN THE SOFTWARE. | |
| 26 | − * | |
| 27 | − * Authors: | |
| 28 | − * Jeff Hartmann <jhartmann@valinux.com> | |
| 29 | − * Keith Whitwell <keith@tungstengraphics.com> | |
| 30 | − * | |
| 31 | − * Rewritten by: | |
| 32 | − * Gareth Hughes <gareth@valinux.com> | |
| 33 | − */ | |
| 34 | − | |
| 35 | −#include "mga_drv.h" | |
| 36 | − | |
| 37 | −/* ================================================================ | |
| 38 | − * DMA hardware state programming functions | |
| 39 | − */ | |
| 40 | − | |
| 41 | −static void mga_emit_clip_rect(drm_mga_private_t *dev_priv, | |
| 42 | − struct drm_clip_rect *box) | |
| 43 | −{ | |
| 44 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 45 | − drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | |
| 46 | − unsigned int pitch = dev_priv->front_pitch; | |
| 47 | − DMA_LOCALS; | |
| 48 | − | |
| 49 | − BEGIN_DMA(2); | |
| 50 | − | |
| 51 | − /* Force reset of DWGCTL on G400 (eliminates clip disable bit). | |
| 52 | − */ | |
| 53 | − if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { | |
| 54 | − DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl, | |
| 55 | − MGA_LEN + MGA_EXEC, 0x80000000, | |
| 56 | − MGA_DWGCTL, ctx->dwgctl, | |
| 57 | − MGA_LEN + MGA_EXEC, 0x80000000); | |
| 58 | − } | |
| 59 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 60 | − MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1, | |
| 61 | − MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch); | |
| 62 | − | |
| 63 | − ADVANCE_DMA(); | |
| 64 | −} | |
| 65 | − | |
| 66 | −static __inline__ void mga_g200_emit_context(drm_mga_private_t *dev_priv) | |
| 67 | −{ | |
| 68 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 69 | − drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | |
| 70 | − DMA_LOCALS; | |
| 71 | − | |
| 72 | − BEGIN_DMA(3); | |
| 73 | − | |
| 74 | − DMA_BLOCK(MGA_DSTORG, ctx->dstorg, | |
| 75 | − MGA_MACCESS, ctx->maccess, | |
| 76 | − MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); | |
| 77 | − | |
| 78 | − DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, | |
| 79 | − MGA_FOGCOL, ctx->fogcolor, | |
| 80 | − MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); | |
| 81 | − | |
| 82 | − DMA_BLOCK(MGA_FCOL, ctx->fcol, | |
| 83 | − MGA_DMAPAD, 0x00000000, | |
| 84 | − MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); | |
| 85 | − | |
| 86 | − ADVANCE_DMA(); | |
| 87 | −} | |
| 88 | − | |
| 89 | −static __inline__ void mga_g400_emit_context(drm_mga_private_t *dev_priv) | |
| 90 | −{ | |
| 91 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 92 | − drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | |
| 93 | − DMA_LOCALS; | |
| 94 | − | |
| 95 | − BEGIN_DMA(4); | |
| 96 | − | |
| 97 | − DMA_BLOCK(MGA_DSTORG, ctx->dstorg, | |
| 98 | − MGA_MACCESS, ctx->maccess, | |
| 99 | − MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); | |
| 100 | − | |
| 101 | − DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, | |
| 102 | − MGA_FOGCOL, ctx->fogcolor, | |
| 103 | − MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); | |
| 104 | − | |
| 105 | − DMA_BLOCK(MGA_WFLAG1, ctx->wflag, | |
| 106 | − MGA_TDUALSTAGE0, ctx->tdualstage0, | |
| 107 | − MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol); | |
| 108 | − | |
| 109 | − DMA_BLOCK(MGA_STENCIL, ctx->stencil, | |
| 110 | − MGA_STENCILCTL, ctx->stencilctl, | |
| 111 | − MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); | |
| 112 | − | |
| 113 | − ADVANCE_DMA(); | |
| 114 | −} | |
| 115 | − | |
| 116 | −static __inline__ void mga_g200_emit_tex0(drm_mga_private_t *dev_priv) | |
| 117 | −{ | |
| 118 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 119 | − drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; | |
| 120 | − DMA_LOCALS; | |
| 121 | − | |
| 122 | − BEGIN_DMA(4); | |
| 123 | − | |
| 124 | − DMA_BLOCK(MGA_TEXCTL2, tex->texctl2, | |
| 125 | − MGA_TEXCTL, tex->texctl, | |
| 126 | − MGA_TEXFILTER, tex->texfilter, | |
| 127 | − MGA_TEXBORDERCOL, tex->texbordercol); | |
| 128 | − | |
| 129 | − DMA_BLOCK(MGA_TEXORG, tex->texorg, | |
| 130 | − MGA_TEXORG1, tex->texorg1, | |
| 131 | − MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); | |
| 132 | − | |
| 133 | − DMA_BLOCK(MGA_TEXORG4, tex->texorg4, | |
| 134 | − MGA_TEXWIDTH, tex->texwidth, | |
| 135 | − MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth); | |
| 136 | − | |
| 137 | − DMA_BLOCK(MGA_WR34, tex->texheight, | |
| 138 | − MGA_TEXTRANS, 0x0000ffff, | |
| 139 | − MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000); | |
| 140 | − | |
| 141 | − ADVANCE_DMA(); | |
| 142 | −} | |
| 143 | − | |
| 144 | −static __inline__ void mga_g400_emit_tex0(drm_mga_private_t *dev_priv) | |
| 145 | −{ | |
| 146 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 147 | − drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; | |
| 148 | − DMA_LOCALS; | |
| 149 | − | |
| 150 | −/* printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */ | |
| 151 | −/* tex->texctl, tex->texctl2); */ | |
| 152 | − | |
| 153 | − BEGIN_DMA(6); | |
| 154 | − | |
| 155 | − DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC, | |
| 156 | − MGA_TEXCTL, tex->texctl, | |
| 157 | − MGA_TEXFILTER, tex->texfilter, | |
| 158 | − MGA_TEXBORDERCOL, tex->texbordercol); | |
| 159 | − | |
| 160 | − DMA_BLOCK(MGA_TEXORG, tex->texorg, | |
| 161 | − MGA_TEXORG1, tex->texorg1, | |
| 162 | − MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); | |
| 163 | − | |
| 164 | − DMA_BLOCK(MGA_TEXORG4, tex->texorg4, | |
| 165 | − MGA_TEXWIDTH, tex->texwidth, | |
| 166 | − MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); | |
| 167 | − | |
| 168 | − DMA_BLOCK(MGA_WR57, 0x00000000, | |
| 169 | − MGA_WR53, 0x00000000, | |
| 170 | − MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC); | |
| 171 | − | |
| 172 | − DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC, | |
| 173 | − MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC, | |
| 174 | − MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC, | |
| 175 | − MGA_DMAPAD, 0x00000000); | |
| 176 | − | |
| 177 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 178 | − MGA_DMAPAD, 0x00000000, | |
| 179 | − MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff); | |
| 180 | − | |
| 181 | − ADVANCE_DMA(); | |
| 182 | −} | |
| 183 | − | |
| 184 | −static __inline__ void mga_g400_emit_tex1(drm_mga_private_t *dev_priv) | |
| 185 | −{ | |
| 186 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 187 | − drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; | |
| 188 | − DMA_LOCALS; | |
| 189 | − | |
| 190 | −/* printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg, */ | |
| 191 | −/* tex->texctl, tex->texctl2); */ | |
| 192 | − | |
| 193 | − BEGIN_DMA(5); | |
| 194 | − | |
| 195 | − DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 | | |
| 196 | − MGA_MAP1_ENABLE | | |
| 197 | − MGA_G400_TC2_MAGIC), | |
| 198 | − MGA_TEXCTL, tex->texctl, | |
| 199 | − MGA_TEXFILTER, tex->texfilter, | |
| 200 | − MGA_TEXBORDERCOL, tex->texbordercol); | |
| 201 | − | |
| 202 | − DMA_BLOCK(MGA_TEXORG, tex->texorg, | |
| 203 | − MGA_TEXORG1, tex->texorg1, | |
| 204 | − MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); | |
| 205 | − | |
| 206 | − DMA_BLOCK(MGA_TEXORG4, tex->texorg4, | |
| 207 | − MGA_TEXWIDTH, tex->texwidth, | |
| 208 | − MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); | |
| 209 | − | |
| 210 | − DMA_BLOCK(MGA_WR57, 0x00000000, | |
| 211 | − MGA_WR53, 0x00000000, | |
| 212 | − MGA_WR61, 0x00000000, | |
| 213 | − MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC); | |
| 214 | − | |
| 215 | − DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC, | |
| 216 | − MGA_TEXTRANS, 0x0000ffff, | |
| 217 | − MGA_TEXTRANSHIGH, 0x0000ffff, | |
| 218 | − MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC); | |
| 219 | − | |
| 220 | − ADVANCE_DMA(); | |
| 221 | −} | |
| 222 | − | |
| 223 | −static __inline__ void mga_g200_emit_pipe(drm_mga_private_t *dev_priv) | |
| 224 | −{ | |
| 225 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 226 | − unsigned int pipe = sarea_priv->warp_pipe; | |
| 227 | − DMA_LOCALS; | |
| 228 | − | |
| 229 | − BEGIN_DMA(3); | |
| 230 | − | |
| 231 | − DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND, | |
| 232 | − MGA_WVRTXSZ, 0x00000007, | |
| 233 | − MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000); | |
| 234 | − | |
| 235 | − DMA_BLOCK(MGA_WR25, 0x00000100, | |
| 236 | − MGA_WR34, 0x00000000, | |
| 237 | − MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff); | |
| 238 | − | |
| 239 | − /* Padding required due to hardware bug. | |
| 240 | − */ | |
| 241 | − DMA_BLOCK(MGA_DMAPAD, 0xffffffff, | |
| 242 | − MGA_DMAPAD, 0xffffffff, | |
| 243 | − MGA_DMAPAD, 0xffffffff, | |
| 244 | − MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | | |
| 245 | − MGA_WMODE_START | dev_priv->wagp_enable)); | |
| 246 | − | |
| 247 | − ADVANCE_DMA(); | |
| 248 | −} | |
| 249 | − | |
| 250 | −static __inline__ void mga_g400_emit_pipe(drm_mga_private_t *dev_priv) | |
| 251 | −{ | |
| 252 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 253 | − unsigned int pipe = sarea_priv->warp_pipe; | |
| 254 | − DMA_LOCALS; | |
| 255 | − | |
| 256 | −/* printk("mga_g400_emit_pipe %x\n", pipe); */ | |
| 257 | − | |
| 258 | − BEGIN_DMA(10); | |
| 259 | − | |
| 260 | − DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND, | |
| 261 | − MGA_DMAPAD, 0x00000000, | |
| 262 | − MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); | |
| 263 | − | |
| 264 | − if (pipe & MGA_T2) { | |
| 265 | − DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09, | |
| 266 | − MGA_DMAPAD, 0x00000000, | |
| 267 | − MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); | |
| 268 | − | |
| 269 | − DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, | |
| 270 | − MGA_WACCEPTSEQ, 0x00000000, | |
| 271 | − MGA_WACCEPTSEQ, 0x00000000, | |
| 272 | − MGA_WACCEPTSEQ, 0x1e000000); | |
| 273 | − } else { | |
| 274 | − if (dev_priv->warp_pipe & MGA_T2) { | |
| 275 | − /* Flush the WARP pipe */ | |
| 276 | − DMA_BLOCK(MGA_YDST, 0x00000000, | |
| 277 | − MGA_FXLEFT, 0x00000000, | |
| 278 | − MGA_FXRIGHT, 0x00000001, | |
| 279 | − MGA_DWGCTL, MGA_DWGCTL_FLUSH); | |
| 280 | − | |
| 281 | − DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001, | |
| 282 | − MGA_DWGSYNC, 0x00007000, | |
| 283 | − MGA_TEXCTL2, MGA_G400_TC2_MAGIC, | |
| 284 | − MGA_LEN + MGA_EXEC, 0x00000000); | |
| 285 | − | |
| 286 | − DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX | | |
| 287 | − MGA_G400_TC2_MAGIC), | |
| 288 | − MGA_LEN + MGA_EXEC, 0x00000000, | |
| 289 | − MGA_TEXCTL2, MGA_G400_TC2_MAGIC, | |
| 290 | − MGA_DMAPAD, 0x00000000); | |
| 291 | − } | |
| 292 | − | |
| 293 | − DMA_BLOCK(MGA_WVRTXSZ, 0x00001807, | |
| 294 | − MGA_DMAPAD, 0x00000000, | |
| 295 | − MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); | |
| 296 | − | |
| 297 | − DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, | |
| 298 | − MGA_WACCEPTSEQ, 0x00000000, | |
| 299 | − MGA_WACCEPTSEQ, 0x00000000, | |
| 300 | − MGA_WACCEPTSEQ, 0x18000000); | |
| 301 | − } | |
| 302 | − | |
| 303 | − DMA_BLOCK(MGA_WFLAG, 0x00000000, | |
| 304 | − MGA_WFLAG1, 0x00000000, | |
| 305 | − MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000); | |
| 306 | − | |
| 307 | − DMA_BLOCK(MGA_WR49, 0x00000000, /* tex0 */ | |
| 308 | − MGA_WR57, 0x00000000, /* tex0 */ | |
| 309 | − MGA_WR53, 0x00000000, /* tex1 */ | |
| 310 | − MGA_WR61, 0x00000000); /* tex1 */ | |
| 311 | − | |
| 312 | − DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */ | |
| 313 | − MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */ | |
| 314 | − MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */ | |
| 315 | − MGA_WR60, MGA_G400_WR_MAGIC); /* tex1 height */ | |
| 316 | − | |
| 317 | − /* Padding required due to hardware bug */ | |
| 318 | − DMA_BLOCK(MGA_DMAPAD, 0xffffffff, | |
| 319 | − MGA_DMAPAD, 0xffffffff, | |
| 320 | − MGA_DMAPAD, 0xffffffff, | |
| 321 | − MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | | |
| 322 | − MGA_WMODE_START | dev_priv->wagp_enable)); | |
| 323 | − | |
| 324 | − ADVANCE_DMA(); | |
| 325 | −} | |
| 326 | − | |
| 327 | −static void mga_g200_emit_state(drm_mga_private_t *dev_priv) | |
| 328 | −{ | |
| 329 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 330 | − unsigned int dirty = sarea_priv->dirty; | |
| 331 | − | |
| 332 | − if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { | |
| 333 | − mga_g200_emit_pipe(dev_priv); | |
| 334 | − dev_priv->warp_pipe = sarea_priv->warp_pipe; | |
| 335 | − } | |
| 336 | − | |
| 337 | − if (dirty & MGA_UPLOAD_CONTEXT) { | |
| 338 | − mga_g200_emit_context(dev_priv); | |
| 339 | − sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; | |
| 340 | − } | |
| 341 | − | |
| 342 | − if (dirty & MGA_UPLOAD_TEX0) { | |
| 343 | − mga_g200_emit_tex0(dev_priv); | |
| 344 | − sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; | |
| 345 | − } | |
| 346 | −} | |
| 347 | − | |
| 348 | −static void mga_g400_emit_state(drm_mga_private_t *dev_priv) | |
| 349 | −{ | |
| 350 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 351 | − unsigned int dirty = sarea_priv->dirty; | |
| 352 | − int multitex = sarea_priv->warp_pipe & MGA_T2; | |
| 353 | − | |
| 354 | − if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { | |
| 355 | − mga_g400_emit_pipe(dev_priv); | |
| 356 | − dev_priv->warp_pipe = sarea_priv->warp_pipe; | |
| 357 | − } | |
| 358 | − | |
| 359 | − if (dirty & MGA_UPLOAD_CONTEXT) { | |
| 360 | − mga_g400_emit_context(dev_priv); | |
| 361 | − sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; | |
| 362 | − } | |
| 363 | − | |
| 364 | − if (dirty & MGA_UPLOAD_TEX0) { | |
| 365 | − mga_g400_emit_tex0(dev_priv); | |
| 366 | − sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; | |
| 367 | − } | |
| 368 | − | |
| 369 | − if ((dirty & MGA_UPLOAD_TEX1) && multitex) { | |
| 370 | − mga_g400_emit_tex1(dev_priv); | |
| 371 | − sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; | |
| 372 | − } | |
| 373 | −} | |
| 374 | − | |
| 375 | −/* ================================================================ | |
| 376 | − * SAREA state verification | |
| 377 | − */ | |
| 378 | − | |
| 379 | −/* Disallow all write destinations except the front and backbuffer. | |
| 380 | − */ | |
| 381 | −static int mga_verify_context(drm_mga_private_t *dev_priv) | |
| 382 | −{ | |
| 383 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 384 | − drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | |
| 385 | − | |
| 386 | − if (ctx->dstorg != dev_priv->front_offset && | |
| 387 | − ctx->dstorg != dev_priv->back_offset) { | |
| 388 | − DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n", | |
| 389 | − ctx->dstorg, dev_priv->front_offset, | |
| 390 | − dev_priv->back_offset); | |
| 391 | − ctx->dstorg = 0; | |
| 392 | − return -EINVAL; | |
| 393 | − } | |
| 394 | − | |
| 395 | − return 0; | |
| 396 | −} | |
| 397 | − | |
| 398 | −/* Disallow texture reads from PCI space. | |
| 399 | − */ | |
| 400 | −static int mga_verify_tex(drm_mga_private_t *dev_priv, int unit) | |
| 401 | −{ | |
| 402 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 403 | − drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; | |
| 404 | − unsigned int org; | |
| 405 | − | |
| 406 | − org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK); | |
| 407 | − | |
| 408 | − if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) { | |
| 409 | − DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit); | |
| 410 | − tex->texorg = 0; | |
| 411 | − return -EINVAL; | |
| 412 | − } | |
| 413 | − | |
| 414 | − return 0; | |
| 415 | −} | |
| 416 | − | |
| 417 | −static int mga_verify_state(drm_mga_private_t *dev_priv) | |
| 418 | −{ | |
| 419 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 420 | − unsigned int dirty = sarea_priv->dirty; | |
| 421 | − int ret = 0; | |
| 422 | − | |
| 423 | − if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) | |
| 424 | − sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; | |
| 425 | − | |
| 426 | − if (dirty & MGA_UPLOAD_CONTEXT) | |
| 427 | − ret |= mga_verify_context(dev_priv); | |
| 428 | − | |
| 429 | − if (dirty & MGA_UPLOAD_TEX0) | |
| 430 | − ret |= mga_verify_tex(dev_priv, 0); | |
| 431 | − | |
| 432 | − if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { | |
| 433 | − if (dirty & MGA_UPLOAD_TEX1) | |
| 434 | − ret |= mga_verify_tex(dev_priv, 1); | |
| 435 | − | |
| 436 | − if (dirty & MGA_UPLOAD_PIPE) | |
| 437 | − ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES); | |
| 438 | − } else { | |
| 439 | − if (dirty & MGA_UPLOAD_PIPE) | |
| 440 | − ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES); | |
| 441 | − } | |
| 442 | − | |
| 443 | − return (ret == 0); | |
| 444 | −} | |
| 445 | − | |
| 446 | −static int mga_verify_iload(drm_mga_private_t *dev_priv, | |
| 447 | − unsigned int dstorg, unsigned int length) | |
| 448 | −{ | |
| 449 | − if (dstorg < dev_priv->texture_offset || | |
| 450 | − dstorg + length > (dev_priv->texture_offset + | |
| 451 | − dev_priv->texture_size)) { | |
| 452 | − DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg); | |
| 453 | − return -EINVAL; | |
| 454 | − } | |
| 455 | − | |
| 456 | − if (length & MGA_ILOAD_MASK) { | |
| 457 | − DRM_ERROR("*** bad iload length: 0x%x\n", | |
| 458 | − length & MGA_ILOAD_MASK); | |
| 459 | − return -EINVAL; | |
| 460 | − } | |
| 461 | − | |
| 462 | − return 0; | |
| 463 | −} | |
| 464 | − | |
| 465 | −static int mga_verify_blit(drm_mga_private_t *dev_priv, | |
| 466 | − unsigned int srcorg, unsigned int dstorg) | |
| 467 | −{ | |
| 468 | − if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || | |
| 469 | − (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) { | |
| 470 | − DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg); | |
| 471 | − return -EINVAL; | |
| 472 | − } | |
| 473 | − return 0; | |
| 474 | −} | |
| 475 | − | |
| 476 | −/* ================================================================ | |
| 477 | − * | |
| 478 | − */ | |
| 479 | − | |
| 480 | −static void mga_dma_dispatch_clear(struct drm_device *dev, drm_mga_clear_t *clear) | |
| 481 | −{ | |
| 482 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 483 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 484 | − drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | |
| 485 | − struct drm_clip_rect *pbox = sarea_priv->boxes; | |
| 486 | − int nbox = sarea_priv->nbox; | |
| 487 | − int i; | |
| 488 | − DMA_LOCALS; | |
| 489 | − DRM_DEBUG("\n"); | |
| 490 | − | |
| 491 | − BEGIN_DMA(1); | |
| 492 | − | |
| 493 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 494 | − MGA_DMAPAD, 0x00000000, | |
| 495 | − MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); | |
| 496 | − | |
| 497 | − ADVANCE_DMA(); | |
| 498 | − | |
| 499 | − for (i = 0; i < nbox; i++) { | |
| 500 | − struct drm_clip_rect *box = &pbox[i]; | |
| 501 | − u32 height = box->y2 - box->y1; | |
| 502 | − | |
| 503 | − DRM_DEBUG(" from=%d,%d to=%d,%d\n", | |
| 504 | − box->x1, box->y1, box->x2, box->y2); | |
| 505 | − | |
| 506 | − if (clear->flags & MGA_FRONT) { | |
| 507 | − BEGIN_DMA(2); | |
| 508 | − | |
| 509 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 510 | − MGA_PLNWT, clear->color_mask, | |
| 511 | − MGA_YDSTLEN, (box->y1 << 16) | height, | |
| 512 | − MGA_FXBNDRY, (box->x2 << 16) | box->x1); | |
| 513 | − | |
| 514 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 515 | − MGA_FCOL, clear->clear_color, | |
| 516 | − MGA_DSTORG, dev_priv->front_offset, | |
| 517 | − MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); | |
| 518 | − | |
| 519 | − ADVANCE_DMA(); | |
| 520 | − } | |
| 521 | − | |
| 522 | − if (clear->flags & MGA_BACK) { | |
| 523 | − BEGIN_DMA(2); | |
| 524 | − | |
| 525 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 526 | − MGA_PLNWT, clear->color_mask, | |
| 527 | − MGA_YDSTLEN, (box->y1 << 16) | height, | |
| 528 | − MGA_FXBNDRY, (box->x2 << 16) | box->x1); | |
| 529 | − | |
| 530 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 531 | − MGA_FCOL, clear->clear_color, | |
| 532 | − MGA_DSTORG, dev_priv->back_offset, | |
| 533 | − MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); | |
| 534 | − | |
| 535 | − ADVANCE_DMA(); | |
| 536 | − } | |
| 537 | − | |
| 538 | − if (clear->flags & MGA_DEPTH) { | |
| 539 | − BEGIN_DMA(2); | |
| 540 | − | |
| 541 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 542 | − MGA_PLNWT, clear->depth_mask, | |
| 543 | − MGA_YDSTLEN, (box->y1 << 16) | height, | |
| 544 | − MGA_FXBNDRY, (box->x2 << 16) | box->x1); | |
| 545 | − | |
| 546 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 547 | − MGA_FCOL, clear->clear_depth, | |
| 548 | − MGA_DSTORG, dev_priv->depth_offset, | |
| 549 | − MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); | |
| 550 | − | |
| 551 | − ADVANCE_DMA(); | |
| 552 | − } | |
| 553 | − | |
| 554 | − } | |
| 555 | − | |
| 556 | − BEGIN_DMA(1); | |
| 557 | − | |
| 558 | − /* Force reset of DWGCTL */ | |
| 559 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 560 | − MGA_DMAPAD, 0x00000000, | |
| 561 | − MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); | |
| 562 | − | |
| 563 | − ADVANCE_DMA(); | |
| 564 | − | |
| 565 | − FLUSH_DMA(); | |
| 566 | −} | |
| 567 | − | |
| 568 | −static void mga_dma_dispatch_swap(struct drm_device *dev) | |
| 569 | −{ | |
| 570 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 571 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 572 | − drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | |
| 573 | − struct drm_clip_rect *pbox = sarea_priv->boxes; | |
| 574 | − int nbox = sarea_priv->nbox; | |
| 575 | − int i; | |
| 576 | − DMA_LOCALS; | |
| 577 | − DRM_DEBUG("\n"); | |
| 578 | − | |
| 579 | − sarea_priv->last_frame.head = dev_priv->prim.tail; | |
| 580 | − sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; | |
| 581 | − | |
| 582 | − BEGIN_DMA(4 + nbox); | |
| 583 | − | |
| 584 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 585 | − MGA_DMAPAD, 0x00000000, | |
| 586 | − MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); | |
| 587 | − | |
| 588 | − DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset, | |
| 589 | − MGA_MACCESS, dev_priv->maccess, | |
| 590 | − MGA_SRCORG, dev_priv->back_offset, | |
| 591 | − MGA_AR5, dev_priv->front_pitch); | |
| 592 | − | |
| 593 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 594 | − MGA_DMAPAD, 0x00000000, | |
| 595 | − MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY); | |
| 596 | − | |
| 597 | − for (i = 0; i < nbox; i++) { | |
| 598 | − struct drm_clip_rect *box = &pbox[i]; | |
| 599 | − u32 height = box->y2 - box->y1; | |
| 600 | − u32 start = box->y1 * dev_priv->front_pitch; | |
| 601 | − | |
| 602 | − DRM_DEBUG(" from=%d,%d to=%d,%d\n", | |
| 603 | − box->x1, box->y1, box->x2, box->y2); | |
| 604 | − | |
| 605 | − DMA_BLOCK(MGA_AR0, start + box->x2 - 1, | |
| 606 | − MGA_AR3, start + box->x1, | |
| 607 | − MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, | |
| 608 | − MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height); | |
| 609 | − } | |
| 610 | − | |
| 611 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 612 | − MGA_PLNWT, ctx->plnwt, | |
| 613 | − MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl); | |
| 614 | − | |
| 615 | − ADVANCE_DMA(); | |
| 616 | − | |
| 617 | − FLUSH_DMA(); | |
| 618 | − | |
| 619 | − DRM_DEBUG("... done.\n"); | |
| 620 | −} | |
| 621 | − | |
| 622 | −static void mga_dma_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) | |
| 623 | −{ | |
| 624 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 625 | − drm_mga_buf_priv_t *buf_priv = buf->dev_private; | |
| 626 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 627 | − u32 address = (u32) buf->bus_address; | |
| 628 | − u32 length = (u32) buf->used; | |
| 629 | − int i = 0; | |
| 630 | − DMA_LOCALS; | |
| 631 | − DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); | |
| 632 | − | |
| 633 | − if (buf->used) { | |
| 634 | − buf_priv->dispatched = 1; | |
| 635 | − | |
| 636 | − MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); | |
| 637 | − | |
| 638 | − do { | |
| 639 | − if (i < sarea_priv->nbox) { | |
| 640 | − mga_emit_clip_rect(dev_priv, | |
| 641 | − &sarea_priv->boxes[i]); | |
| 642 | − } | |
| 643 | − | |
| 644 | − BEGIN_DMA(1); | |
| 645 | − | |
| 646 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 647 | − MGA_DMAPAD, 0x00000000, | |
| 648 | − MGA_SECADDRESS, (address | | |
| 649 | − MGA_DMA_VERTEX), | |
| 650 | − MGA_SECEND, ((address + length) | | |
| 651 | − dev_priv->dma_access)); | |
| 652 | − | |
| 653 | − ADVANCE_DMA(); | |
| 654 | − } while (++i < sarea_priv->nbox); | |
| 655 | − } | |
| 656 | − | |
| 657 | − if (buf_priv->discard) { | |
| 658 | − AGE_BUFFER(buf_priv); | |
| 659 | − buf->pending = 0; | |
| 660 | − buf->used = 0; | |
| 661 | − buf_priv->dispatched = 0; | |
| 662 | − | |
| 663 | − mga_freelist_put(dev, buf); | |
| 664 | − } | |
| 665 | − | |
| 666 | − FLUSH_DMA(); | |
| 667 | −} | |
| 668 | − | |
| 669 | −static void mga_dma_dispatch_indices(struct drm_device *dev, struct drm_buf *buf, | |
| 670 | − unsigned int start, unsigned int end) | |
| 671 | −{ | |
| 672 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 673 | − drm_mga_buf_priv_t *buf_priv = buf->dev_private; | |
| 674 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 675 | − u32 address = (u32) buf->bus_address; | |
| 676 | − int i = 0; | |
| 677 | − DMA_LOCALS; | |
| 678 | − DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end); | |
| 679 | − | |
| 680 | − if (start != end) { | |
| 681 | − buf_priv->dispatched = 1; | |
| 682 | − | |
| 683 | − MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); | |
| 684 | − | |
| 685 | − do { | |
| 686 | − if (i < sarea_priv->nbox) { | |
| 687 | − mga_emit_clip_rect(dev_priv, | |
| 688 | − &sarea_priv->boxes[i]); | |
| 689 | − } | |
| 690 | − | |
| 691 | − BEGIN_DMA(1); | |
| 692 | − | |
| 693 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 694 | − MGA_DMAPAD, 0x00000000, | |
| 695 | − MGA_SETUPADDRESS, address + start, | |
| 696 | − MGA_SETUPEND, ((address + end) | | |
| 697 | − dev_priv->dma_access)); | |
| 698 | − | |
| 699 | − ADVANCE_DMA(); | |
| 700 | − } while (++i < sarea_priv->nbox); | |
| 701 | − } | |
| 702 | − | |
| 703 | − if (buf_priv->discard) { | |
| 704 | − AGE_BUFFER(buf_priv); | |
| 705 | − buf->pending = 0; | |
| 706 | − buf->used = 0; | |
| 707 | − buf_priv->dispatched = 0; | |
| 708 | − | |
| 709 | − mga_freelist_put(dev, buf); | |
| 710 | − } | |
| 711 | − | |
| 712 | − FLUSH_DMA(); | |
| 713 | −} | |
| 714 | − | |
| 715 | −/* This copies a 64 byte aligned agp region to the frambuffer with a | |
| 716 | − * standard blit, the ioctl needs to do checking. | |
| 717 | − */ | |
| 718 | −static void mga_dma_dispatch_iload(struct drm_device *dev, struct drm_buf *buf, | |
| 719 | − unsigned int dstorg, unsigned int length) | |
| 720 | −{ | |
| 721 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 722 | − drm_mga_buf_priv_t *buf_priv = buf->dev_private; | |
| 723 | − drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; | |
| 724 | − u32 srcorg = | |
| 725 | − buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM; | |
| 726 | − u32 y2; | |
| 727 | − DMA_LOCALS; | |
| 728 | − DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); | |
| 729 | − | |
| 730 | − y2 = length / 64; | |
| 731 | − | |
| 732 | − BEGIN_DMA(5); | |
| 733 | − | |
| 734 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 735 | − MGA_DMAPAD, 0x00000000, | |
| 736 | − MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); | |
| 737 | − | |
| 738 | − DMA_BLOCK(MGA_DSTORG, dstorg, | |
| 739 | − MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64); | |
| 740 | − | |
| 741 | − DMA_BLOCK(MGA_PITCH, 64, | |
| 742 | − MGA_PLNWT, 0xffffffff, | |
| 743 | − MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY); | |
| 744 | − | |
| 745 | − DMA_BLOCK(MGA_AR0, 63, | |
| 746 | − MGA_AR3, 0, | |
| 747 | − MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2); | |
| 748 | − | |
| 749 | − DMA_BLOCK(MGA_PLNWT, ctx->plnwt, | |
| 750 | − MGA_SRCORG, dev_priv->front_offset, | |
| 751 | − MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000); | |
| 752 | − | |
| 753 | − ADVANCE_DMA(); | |
| 754 | − | |
| 755 | − AGE_BUFFER(buf_priv); | |
| 756 | − | |
| 757 | − buf->pending = 0; | |
| 758 | − buf->used = 0; | |
| 759 | − buf_priv->dispatched = 0; | |
| 760 | − | |
| 761 | − mga_freelist_put(dev, buf); | |
| 762 | − | |
| 763 | − FLUSH_DMA(); | |
| 764 | −} | |
| 765 | − | |
| 766 | −static void mga_dma_dispatch_blit(struct drm_device *dev, drm_mga_blit_t *blit) | |
| 767 | −{ | |
| 768 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 769 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 770 | − drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | |
| 771 | − struct drm_clip_rect *pbox = sarea_priv->boxes; | |
| 772 | − int nbox = sarea_priv->nbox; | |
| 773 | − u32 scandir = 0, i; | |
| 774 | − DMA_LOCALS; | |
| 775 | − DRM_DEBUG("\n"); | |
| 776 | − | |
| 777 | − BEGIN_DMA(4 + nbox); | |
| 778 | − | |
| 779 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 780 | − MGA_DMAPAD, 0x00000000, | |
| 781 | − MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); | |
| 782 | − | |
| 783 | − DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY, | |
| 784 | − MGA_PLNWT, blit->planemask, | |
| 785 | − MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg); | |
| 786 | − | |
| 787 | − DMA_BLOCK(MGA_SGN, scandir, | |
| 788 | − MGA_MACCESS, dev_priv->maccess, | |
| 789 | − MGA_AR5, blit->ydir * blit->src_pitch, | |
| 790 | − MGA_PITCH, blit->dst_pitch); | |
| 791 | − | |
| 792 | − for (i = 0; i < nbox; i++) { | |
| 793 | − int srcx = pbox[i].x1 + blit->delta_sx; | |
| 794 | − int srcy = pbox[i].y1 + blit->delta_sy; | |
| 795 | − int dstx = pbox[i].x1 + blit->delta_dx; | |
| 796 | − int dsty = pbox[i].y1 + blit->delta_dy; | |
| 797 | − int h = pbox[i].y2 - pbox[i].y1; | |
| 798 | − int w = pbox[i].x2 - pbox[i].x1 - 1; | |
| 799 | − int start; | |
| 800 | − | |
| 801 | − if (blit->ydir == -1) | |
| 802 | − srcy = blit->height - srcy - 1; | |
| 803 | − | |
| 804 | − start = srcy * blit->src_pitch + srcx; | |
| 805 | − | |
| 806 | − DMA_BLOCK(MGA_AR0, start + w, | |
| 807 | − MGA_AR3, start, | |
| 808 | − MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), | |
| 809 | − MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h); | |
| 810 | − } | |
| 811 | − | |
| 812 | − /* Do something to flush AGP? | |
| 813 | − */ | |
| 814 | − | |
| 815 | − /* Force reset of DWGCTL */ | |
| 816 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 817 | − MGA_PLNWT, ctx->plnwt, | |
| 818 | − MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl); | |
| 819 | − | |
| 820 | − ADVANCE_DMA(); | |
| 821 | −} | |
| 822 | − | |
| 823 | −/* ================================================================ | |
| 824 | − * | |
| 825 | − */ | |
| 826 | − | |
| 827 | −static int mga_dma_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 828 | −{ | |
| 829 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 830 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 831 | − drm_mga_clear_t *clear = data; | |
| 832 | − | |
| 833 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 834 | − | |
| 835 | − if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) | |
| 836 | − sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; | |
| 837 | − | |
| 838 | − WRAP_TEST_WITH_RETURN(dev_priv); | |
| 839 | − | |
| 840 | − mga_dma_dispatch_clear(dev, clear); | |
| 841 | − | |
| 842 | − /* Make sure we restore the 3D state next time. | |
| 843 | − */ | |
| 844 | − dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; | |
| 845 | − | |
| 846 | − return 0; | |
| 847 | −} | |
| 848 | − | |
| 849 | −static int mga_dma_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 850 | −{ | |
| 851 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 852 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 853 | − | |
| 854 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 855 | − | |
| 856 | − if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) | |
| 857 | − sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; | |
| 858 | − | |
| 859 | − WRAP_TEST_WITH_RETURN(dev_priv); | |
| 860 | − | |
| 861 | − mga_dma_dispatch_swap(dev); | |
| 862 | − | |
| 863 | − /* Make sure we restore the 3D state next time. | |
| 864 | − */ | |
| 865 | − dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; | |
| 866 | − | |
| 867 | − return 0; | |
| 868 | −} | |
| 869 | − | |
| 870 | −static int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 871 | −{ | |
| 872 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 873 | − struct drm_device_dma *dma = dev->dma; | |
| 874 | − struct drm_buf *buf; | |
| 875 | − drm_mga_buf_priv_t *buf_priv; | |
| 876 | − drm_mga_vertex_t *vertex = data; | |
| 877 | − | |
| 878 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 879 | − | |
| 880 | − if (vertex->idx < 0 || vertex->idx > dma->buf_count) | |
| 881 | − return -EINVAL; | |
| 882 | − buf = dma->buflist[vertex->idx]; | |
| 883 | − buf_priv = buf->dev_private; | |
| 884 | − | |
| 885 | − buf->used = vertex->used; | |
| 886 | − buf_priv->discard = vertex->discard; | |
| 887 | − | |
| 888 | − if (!mga_verify_state(dev_priv)) { | |
| 889 | − if (vertex->discard) { | |
| 890 | − if (buf_priv->dispatched == 1) | |
| 891 | − AGE_BUFFER(buf_priv); | |
| 892 | − buf_priv->dispatched = 0; | |
| 893 | − mga_freelist_put(dev, buf); | |
| 894 | − } | |
| 895 | − return -EINVAL; | |
| 896 | − } | |
| 897 | − | |
| 898 | − WRAP_TEST_WITH_RETURN(dev_priv); | |
| 899 | − | |
| 900 | − mga_dma_dispatch_vertex(dev, buf); | |
| 901 | − | |
| 902 | − return 0; | |
| 903 | −} | |
| 904 | − | |
| 905 | −static int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 906 | −{ | |
| 907 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 908 | − struct drm_device_dma *dma = dev->dma; | |
| 909 | − struct drm_buf *buf; | |
| 910 | − drm_mga_buf_priv_t *buf_priv; | |
| 911 | − drm_mga_indices_t *indices = data; | |
| 912 | − | |
| 913 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 914 | − | |
| 915 | − if (indices->idx < 0 || indices->idx > dma->buf_count) | |
| 916 | − return -EINVAL; | |
| 917 | − | |
| 918 | − buf = dma->buflist[indices->idx]; | |
| 919 | − buf_priv = buf->dev_private; | |
| 920 | − | |
| 921 | − buf_priv->discard = indices->discard; | |
| 922 | − | |
| 923 | − if (!mga_verify_state(dev_priv)) { | |
| 924 | − if (indices->discard) { | |
| 925 | − if (buf_priv->dispatched == 1) | |
| 926 | − AGE_BUFFER(buf_priv); | |
| 927 | − buf_priv->dispatched = 0; | |
| 928 | − mga_freelist_put(dev, buf); | |
| 929 | − } | |
| 930 | − return -EINVAL; | |
| 931 | − } | |
| 932 | − | |
| 933 | − WRAP_TEST_WITH_RETURN(dev_priv); | |
| 934 | − | |
| 935 | − mga_dma_dispatch_indices(dev, buf, indices->start, indices->end); | |
| 936 | − | |
| 937 | − return 0; | |
| 938 | −} | |
| 939 | − | |
| 940 | −static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 941 | −{ | |
| 942 | − struct drm_device_dma *dma = dev->dma; | |
| 943 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 944 | − struct drm_buf *buf; | |
| 945 | − drm_mga_iload_t *iload = data; | |
| 946 | − DRM_DEBUG("\n"); | |
| 947 | − | |
| 948 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 949 | − | |
| 950 | −#if 0 | |
| 951 | − if (mga_do_wait_for_idle(dev_priv) < 0) { | |
| 952 | − if (MGA_DMA_DEBUG) | |
| 953 | − DRM_INFO("-EBUSY\n"); | |
| 954 | − return -EBUSY; | |
| 955 | − } | |
| 956 | −#endif | |
| 957 | − if (iload->idx < 0 || iload->idx > dma->buf_count) | |
| 958 | − return -EINVAL; | |
| 959 | − | |
| 960 | − buf = dma->buflist[iload->idx]; | |
| 961 | − | |
| 962 | − if (mga_verify_iload(dev_priv, iload->dstorg, iload->length)) { | |
| 963 | − mga_freelist_put(dev, buf); | |
| 964 | − return -EINVAL; | |
| 965 | − } | |
| 966 | − | |
| 967 | − WRAP_TEST_WITH_RETURN(dev_priv); | |
| 968 | − | |
| 969 | − mga_dma_dispatch_iload(dev, buf, iload->dstorg, iload->length); | |
| 970 | − | |
| 971 | − /* Make sure we restore the 3D state next time. | |
| 972 | − */ | |
| 973 | − dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; | |
| 974 | − | |
| 975 | − return 0; | |
| 976 | −} | |
| 977 | − | |
| 978 | −static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 979 | −{ | |
| 980 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 981 | − drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | |
| 982 | − drm_mga_blit_t *blit = data; | |
| 983 | − DRM_DEBUG("\n"); | |
| 984 | − | |
| 985 | − LOCK_TEST_WITH_RETURN(dev, file_priv); | |
| 986 | − | |
| 987 | − if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) | |
| 988 | − sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; | |
| 989 | − | |
| 990 | − if (mga_verify_blit(dev_priv, blit->srcorg, blit->dstorg)) | |
| 991 | − return -EINVAL; | |
| 992 | − | |
| 993 | − WRAP_TEST_WITH_RETURN(dev_priv); | |
| 994 | − | |
| 995 | − mga_dma_dispatch_blit(dev, blit); | |
| 996 | − | |
| 997 | − /* Make sure we restore the 3D state next time. | |
| 998 | − */ | |
| 999 | − dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; | |
| 1000 | − | |
| 1001 | − return 0; | |
| 1002 | −} | |
| 1003 | − | |
| 1004 | −int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 1005 | −{ | |
| 1006 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 1007 | − drm_mga_getparam_t *param = data; | |
| 1008 | − struct pci_dev *pdev = to_pci_dev(dev->dev); | |
| 1009 | − int value; | |
| 1010 | − | |
| 1011 | − if (!dev_priv) { | |
| 1012 | − DRM_ERROR("called with no initialization\n"); | |
| 1013 | − return -EINVAL; | |
| 1014 | − } | |
| 1015 | − | |
| 1016 | − DRM_DEBUG("pid=%d\n", task_pid_nr(current)); | |
| 1017 | − | |
| 1018 | − switch (param->param) { | |
| 1019 | − case MGA_PARAM_IRQ_NR: | |
| 1020 | − value = pdev->irq; | |
| 1021 | − break; | |
| 1022 | − case MGA_PARAM_CARD_TYPE: | |
| 1023 | − value = dev_priv->chipset; | |
| 1024 | − break; | |
| 1025 | − default: | |
| 1026 | − return -EINVAL; | |
| 1027 | − } | |
| 1028 | − | |
| 1029 | − if (copy_to_user(param->value, &value, sizeof(int))) { | |
| 1030 | − DRM_ERROR("copy_to_user\n"); | |
| 1031 | − return -EFAULT; | |
| 1032 | − } | |
| 1033 | − | |
| 1034 | − return 0; | |
| 1035 | −} | |
| 1036 | − | |
| 1037 | −static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *file_priv) | |
| 1038 | −{ | |
| 1039 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 1040 | − u32 *fence = data; | |
| 1041 | − DMA_LOCALS; | |
| 1042 | − | |
| 1043 | − if (!dev_priv) { | |
| 1044 | − DRM_ERROR("called with no initialization\n"); | |
| 1045 | − return -EINVAL; | |
| 1046 | − } | |
| 1047 | − | |
| 1048 | − DRM_DEBUG("pid=%d\n", task_pid_nr(current)); | |
| 1049 | − | |
| 1050 | − /* I would normal do this assignment in the declaration of fence, | |
| 1051 | − * but dev_priv may be NULL. | |
| 1052 | − */ | |
| 1053 | − | |
| 1054 | − *fence = dev_priv->next_fence_to_post; | |
| 1055 | − dev_priv->next_fence_to_post++; | |
| 1056 | − | |
| 1057 | − BEGIN_DMA(1); | |
| 1058 | − DMA_BLOCK(MGA_DMAPAD, 0x00000000, | |
| 1059 | − MGA_DMAPAD, 0x00000000, | |
| 1060 | − MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000); | |
| 1061 | − ADVANCE_DMA(); | |
| 1062 | − | |
| 1063 | − return 0; | |
| 1064 | −} | |
| 1065 | − | |
| 1066 | −static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file * | |
| 1067 | −file_priv) | |
| 1068 | −{ | |
| 1069 | − drm_mga_private_t *dev_priv = dev->dev_private; | |
| 1070 | − u32 *fence = data; | |
| 1071 | − | |
| 1072 | − if (!dev_priv) { | |
| 1073 | − DRM_ERROR("called with no initialization\n"); | |
| 1074 | − return -EINVAL; | |
| 1075 | − } | |
| 1076 | − | |
| 1077 | − DRM_DEBUG("pid=%d\n", task_pid_nr(current)); | |
| 1078 | − | |
| 1079 | − mga_driver_fence_wait(dev, fence); | |
| 1080 | − return 0; | |
| 1081 | −} | |
| 1082 | − | |
| 1083 | −const struct drm_ioctl_desc mga_ioctls[] = { | |
| 1084 | − DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | |
| 1085 | − DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH), | |
| 1086 | − DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH), | |
| 1087 | − DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH), | |
| 1088 | − DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH), | |
| 1089 | − DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH), | |
| 1090 | − DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH), | |
| 1091 | − DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH), | |
| 1092 | − DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH), | |
| 1093 | − DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH), | |
| 1094 | − DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH), | |
| 1095 | − DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), | |
| 1096 | − DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | |
| 1097 | −}; | |
| 1098 | − | |
| 1099 | −int mga_max_ioctl = ARRAY_SIZE(mga_ioctls); | |
| @@ -1,167 +0,0 @@ | ||
| 1 | −/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*- | |
| 2 | − * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com | |
| 3 | − * | |
| 4 | − * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | |
| 5 | − * All Rights Reserved. | |
| 6 | − * | |
| 7 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 8 | − * copy of this software and associated documentation files (the "Software"), | |
| 9 | − * to deal in the Software without restriction, including without limitation | |
| 10 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 11 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 12 | − * Software is furnished to do so, subject to the following conditions: | |
| 13 | − * | |
| 14 | − * The above copyright notice and this permission notice (including the next | |
| 15 | − * paragraph) shall be included in all copies or substantial portions of the | |
| 16 | − * Software. | |
| 17 | − * | |
| 18 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 19 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 20 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 21 | − * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 22 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 23 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 24 | − * OTHER DEALINGS IN THE SOFTWARE. | |
| 25 | − * | |
| 26 | − * Authors: | |
| 27 | − * Gareth Hughes <gareth@valinux.com> | |
| 28 | − */ | |
| 29 | − | |
| 30 | −#include <linux/firmware.h> | |
| 31 | −#include <linux/ihex.h> | |
| 32 | −#include <linux/module.h> | |
| 33 | −#include <linux/platform_device.h> | |
| 34 | − | |
| 35 | −#include "mga_drv.h" | |
| 36 | − | |
| 37 | −#define FIRMWARE_G200 "matrox/g200_warp.fw" | |
| 38 | −#define FIRMWARE_G400 "matrox/g400_warp.fw" | |
| 39 | − | |
| 40 | −MODULE_FIRMWARE(FIRMWARE_G200); | |
| 41 | −MODULE_FIRMWARE(FIRMWARE_G400); | |
| 42 | − | |
| 43 | −#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ | |
| 44 | − | |
| 45 | −#define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN) | |
| 46 | − | |
| 47 | −int mga_warp_install_microcode(drm_mga_private_t *dev_priv) | |
| 48 | −{ | |
| 49 | − unsigned char *vcbase = dev_priv->warp->handle; | |
| 50 | − unsigned long pcbase = dev_priv->warp->offset; | |
| 51 | − const char *firmware_name; | |
| 52 | − struct platform_device *pdev; | |
| 53 | − const struct firmware *fw = NULL; | |
| 54 | − const struct ihex_binrec *rec; | |
| 55 | − unsigned int size; | |
| 56 | − int n_pipes, where; | |
| 57 | − int rc = 0; | |
| 58 | − | |
| 59 | − switch (dev_priv->chipset) { | |
| 60 | − case MGA_CARD_TYPE_G400: | |
| 61 | − case MGA_CARD_TYPE_G550: | |
| 62 | − firmware_name = FIRMWARE_G400; | |
| 63 | − n_pipes = MGA_MAX_G400_PIPES; | |
| 64 | − break; | |
| 65 | − case MGA_CARD_TYPE_G200: | |
| 66 | − firmware_name = FIRMWARE_G200; | |
| 67 | − n_pipes = MGA_MAX_G200_PIPES; | |
| 68 | − break; | |
| 69 | − default: | |
| 70 | − return -EINVAL; | |
| 71 | − } | |
| 72 | − | |
| 73 | − pdev = platform_device_register_simple("mga_warp", 0, NULL, 0); | |
| 74 | − if (IS_ERR(pdev)) { | |
| 75 | − DRM_ERROR("mga: Failed to register microcode\n"); | |
| 76 | − return PTR_ERR(pdev); | |
| 77 | − } | |
| 78 | − rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); | |
| 79 | − platform_device_unregister(pdev); | |
| 80 | − if (rc) { | |
| 81 | − DRM_ERROR("mga: Failed to load microcode \"%s\"\n", | |
| 82 | − firmware_name); | |
| 83 | − return rc; | |
| 84 | − } | |
| 85 | − | |
| 86 | − size = 0; | |
| 87 | − where = 0; | |
| 88 | − for (rec = (const struct ihex_binrec *)fw->data; | |
| 89 | − rec; | |
| 90 | − rec = ihex_next_binrec(rec)) { | |
| 91 | − size += WARP_UCODE_SIZE(be16_to_cpu(rec->len)); | |
| 92 | − where++; | |
| 93 | − } | |
| 94 | − | |
| 95 | − if (where != n_pipes) { | |
| 96 | − DRM_ERROR("mga: Invalid microcode \"%s\"\n", firmware_name); | |
| 97 | − rc = -EINVAL; | |
| 98 | − goto out; | |
| 99 | − } | |
| 100 | − size = PAGE_ALIGN(size); | |
| 101 | − DRM_DEBUG("MGA ucode size = %d bytes\n", size); | |
| 102 | − if (size > dev_priv->warp->size) { | |
| 103 | − DRM_ERROR("microcode too large! (%u > %lu)\n", | |
| 104 | − size, dev_priv->warp->size); | |
| 105 | − rc = -ENOMEM; | |
| 106 | − goto out; | |
| 107 | − } | |
| 108 | − | |
| 109 | − memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); | |
| 110 | − | |
| 111 | − where = 0; | |
| 112 | − for (rec = (const struct ihex_binrec *)fw->data; | |
| 113 | − rec; | |
| 114 | − rec = ihex_next_binrec(rec)) { | |
| 115 | − unsigned int src_size, dst_size; | |
| 116 | − | |
| 117 | − DRM_DEBUG(" pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase); | |
| 118 | − dev_priv->warp_pipe_phys[where] = pcbase; | |
| 119 | − src_size = be16_to_cpu(rec->len); | |
| 120 | − dst_size = WARP_UCODE_SIZE(src_size); | |
| 121 | − memcpy(vcbase, rec->data, src_size); | |
| 122 | − pcbase += dst_size; | |
| 123 | − vcbase += dst_size; | |
| 124 | − where++; | |
| 125 | − } | |
| 126 | − | |
| 127 | −out: | |
| 128 | − release_firmware(fw); | |
| 129 | − return rc; | |
| 130 | −} | |
| 131 | − | |
| 132 | −#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) | |
| 133 | − | |
| 134 | −int mga_warp_init(drm_mga_private_t *dev_priv) | |
| 135 | −{ | |
| 136 | − u32 wmisc; | |
| 137 | − | |
| 138 | − /* FIXME: Get rid of these damned magic numbers... | |
| 139 | − */ | |
| 140 | − switch (dev_priv->chipset) { | |
| 141 | − case MGA_CARD_TYPE_G400: | |
| 142 | − case MGA_CARD_TYPE_G550: | |
| 143 | − MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND); | |
| 144 | − MGA_WRITE(MGA_WGETMSB, 0x00000E00); | |
| 145 | − MGA_WRITE(MGA_WVRTXSZ, 0x00001807); | |
| 146 | − MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000); | |
| 147 | − break; | |
| 148 | − case MGA_CARD_TYPE_G200: | |
| 149 | − MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND); | |
| 150 | − MGA_WRITE(MGA_WGETMSB, 0x1606); | |
| 151 | − MGA_WRITE(MGA_WVRTXSZ, 7); | |
| 152 | − break; | |
| 153 | − default: | |
| 154 | − return -EINVAL; | |
| 155 | − } | |
| 156 | − | |
| 157 | − MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE | | |
| 158 | − MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE)); | |
| 159 | − wmisc = MGA_READ(MGA_WMISC); | |
| 160 | − if (wmisc != WMISC_EXPECTED) { | |
| 161 | − DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n", | |
| 162 | − wmisc, WMISC_EXPECTED); | |
| 163 | − return -EINVAL; | |
| 164 | − } | |
| 165 | − | |
| 166 | − return 0; | |
| 167 | −} | |
| @@ -1,429 +0,0 @@ | ||
| 1 | −/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- | |
| 2 | − * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com | |
| 3 | − * | |
| 4 | − * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | |
| 5 | − * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | |
| 6 | − * All rights reserved. | |
| 7 | − * | |
| 8 | − * Permission is hereby granted, free of charge, to any person obtaining a | |
| 9 | − * copy of this software and associated documentation files (the "Software"), | |
| 10 | − * to deal in the Software without restriction, including without limitation | |
| 11 | − * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 12 | − * and/or sell copies of the Software, and to permit persons to whom the | |
| 13 | − * Software is furnished to do so, subject to the following conditions: | |
| 14 | − * | |
| 15 | − * The above copyright notice and this permission notice (including the next | |
| 16 | − * paragraph) shall be included in all copies or substantial portions of the | |
| 17 | − * Software. | |
| 18 | − * | |
| 19 | − * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 20 | − * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 21 | − * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 22 | − * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 23 | − * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 24 | − * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 25 | − * OTHER DEALINGS IN THE SOFTWARE. | |
| 26 | − * | |
| 27 | − * Authors: | |
| 28 | − * Jeff Hartmann <jhartmann@valinux.com> | |
| 29 | − * Keith Whitwell <keith@tungstengraphics.com> | |
| 30 | − * | |
| 31 | − * Rewritten by: | |
| 32 | − * Gareth Hughes <gareth@valinux.com> | |
| 33 | − */ | |
| 34 | − | |
| 35 | −#ifndef __MGA_DRM_H__ | |
| 36 | −#define __MGA_DRM_H__ | |
| 37 | − | |
| 38 | −#include "drm.h" | |
| 39 | − | |
| 40 | −#if defined(__cplusplus) | |
| 41 | −extern "C" { | |
| 42 | −#endif | |
| 43 | − | |
| 44 | −/* WARNING: If you change any of these defines, make sure to change the | |
| 45 | − * defines in the Xserver file (mga_sarea.h) | |
| 46 | − */ | |
| 47 | − | |
| 48 | −#ifndef __MGA_SAREA_DEFINES__ | |
| 49 | −#define __MGA_SAREA_DEFINES__ | |
| 50 | − | |
| 51 | −/* WARP pipe flags | |
| 52 | − */ | |
| 53 | −#define MGA_F 0x1 /* fog */ | |
| 54 | −#define MGA_A 0x2 /* alpha */ | |
| 55 | −#define MGA_S 0x4 /* specular */ | |
| 56 | −#define MGA_T2 0x8 /* multitexture */ | |
| 57 | − | |
| 58 | −#define MGA_WARP_TGZ 0 | |
| 59 | −#define MGA_WARP_TGZF (MGA_F) | |
| 60 | −#define MGA_WARP_TGZA (MGA_A) | |
| 61 | −#define MGA_WARP_TGZAF (MGA_F|MGA_A) | |
| 62 | −#define MGA_WARP_TGZS (MGA_S) | |
| 63 | −#define MGA_WARP_TGZSF (MGA_S|MGA_F) | |
| 64 | −#define MGA_WARP_TGZSA (MGA_S|MGA_A) | |
| 65 | −#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A) | |
| 66 | −#define MGA_WARP_T2GZ (MGA_T2) | |
| 67 | −#define MGA_WARP_T2GZF (MGA_T2|MGA_F) | |
| 68 | −#define MGA_WARP_T2GZA (MGA_T2|MGA_A) | |
| 69 | −#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F) | |
| 70 | −#define MGA_WARP_T2GZS (MGA_T2|MGA_S) | |
| 71 | −#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F) | |
| 72 | −#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A) | |
| 73 | −#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A) | |
| 74 | − | |
| 75 | −#define MGA_MAX_G200_PIPES 8 /* no multitex */ | |
| 76 | −#define MGA_MAX_G400_PIPES 16 | |
| 77 | −#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES | |
| 78 | −#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */ | |
| 79 | − | |
| 80 | −#define MGA_CARD_TYPE_G200 1 | |
| 81 | −#define MGA_CARD_TYPE_G400 2 | |
| 82 | −#define MGA_CARD_TYPE_G450 3 /* not currently used */ | |
| 83 | −#define MGA_CARD_TYPE_G550 4 | |
| 84 | − | |
| 85 | −#define MGA_FRONT 0x1 | |
| 86 | −#define MGA_BACK 0x2 | |
| 87 | −#define MGA_DEPTH 0x4 | |
| 88 | − | |
| 89 | −/* What needs to be changed for the current vertex dma buffer? | |
| 90 | − */ | |
| 91 | −#define MGA_UPLOAD_CONTEXT 0x1 | |
| 92 | −#define MGA_UPLOAD_TEX0 0x2 | |
| 93 | −#define MGA_UPLOAD_TEX1 0x4 | |
| 94 | −#define MGA_UPLOAD_PIPE 0x8 | |
| 95 | −#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */ | |
| 96 | −#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */ | |
| 97 | −#define MGA_UPLOAD_2D 0x40 | |
| 98 | −#define MGA_WAIT_AGE 0x80 /* handled client-side */ | |
| 99 | −#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ | |
| 100 | −#if 0 | |
| 101 | −#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock | |
| 102 | − quiescent */ | |
| 103 | −#endif | |
| 104 | − | |
| 105 | −/* 32 buffers of 64k each, total 2 meg. | |
| 106 | − */ | |
| 107 | −#define MGA_BUFFER_SIZE (1 << 16) | |
| 108 | −#define MGA_NUM_BUFFERS 128 | |
| 109 | − | |
| 110 | −/* Keep these small for testing. | |
| 111 | − */ | |
| 112 | −#define MGA_NR_SAREA_CLIPRECTS 8 | |
| 113 | − | |
| 114 | −/* 2 heaps (1 for card, 1 for agp), each divided into up to 128 | |
| 115 | − * regions, subject to a minimum region size of (1<<16) == 64k. | |
| 116 | − * | |
| 117 | − * Clients may subdivide regions internally, but when sharing between | |
| 118 | − * clients, the region size is the minimum granularity. | |
| 119 | − */ | |
| 120 | − | |
| 121 | −#define MGA_CARD_HEAP 0 | |
| 122 | −#define MGA_AGP_HEAP 1 | |
| 123 | −#define MGA_NR_TEX_HEAPS 2 | |
| 124 | −#define MGA_NR_TEX_REGIONS 16 | |
| 125 | −#define MGA_LOG_MIN_TEX_REGION_SIZE 16 | |
| 126 | − | |
| 127 | −#define DRM_MGA_IDLE_RETRY 2048 | |
| 128 | − | |
| 129 | −#endif /* __MGA_SAREA_DEFINES__ */ | |
| 130 | − | |
| 131 | −/* Setup registers for 3D context | |
| 132 | − */ | |
| 133 | −typedef struct { | |
| 134 | − unsigned int dstorg; | |
| 135 | − unsigned int maccess; | |
| 136 | − unsigned int plnwt; | |
| 137 | − unsigned int dwgctl; | |
| 138 | − unsigned int alphactrl; | |
| 139 | − unsigned int fogcolor; | |
| 140 | − unsigned int wflag; | |
| 141 | − unsigned int tdualstage0; | |
| 142 | − unsigned int tdualstage1; | |
| 143 | − unsigned int fcol; | |
| 144 | − unsigned int stencil; | |
| 145 | − unsigned int stencilctl; | |
| 146 | −} drm_mga_context_regs_t; | |
| 147 | − | |
| 148 | −/* Setup registers for 2D, X server | |
| 149 | − */ | |
| 150 | −typedef struct { | |
| 151 | − unsigned int pitch; | |
| 152 | −} drm_mga_server_regs_t; | |
| 153 | − | |
| 154 | −/* Setup registers for each texture unit | |
| 155 | − */ | |
| 156 | −typedef struct { | |
| 157 | − unsigned int texctl; | |
| 158 | − unsigned int texctl2; | |
| 159 | − unsigned int texfilter; | |
| 160 | − unsigned int texbordercol; | |
| 161 | − unsigned int texorg; | |
| 162 | − unsigned int texwidth; | |
| 163 | − unsigned int texheight; | |
| 164 | − unsigned int texorg1; | |
| 165 | − unsigned int texorg2; | |
| 166 | − unsigned int texorg3; | |
| 167 | − unsigned int texorg4; | |
| 168 | −} drm_mga_texture_regs_t; | |
| 169 | − | |
| 170 | −/* General aging mechanism | |
| 171 | − */ | |
| 172 | −typedef struct { | |
| 173 | − unsigned int head; /* Position of head pointer */ | |
| 174 | − unsigned int wrap; /* Primary DMA wrap count */ | |
| 175 | −} drm_mga_age_t; | |
| 176 | − | |
| 177 | −typedef struct _drm_mga_sarea { | |
| 178 | − /* The channel for communication of state information to the kernel | |
| 179 | − * on firing a vertex dma buffer. | |
| 180 | − */ | |
| 181 | − drm_mga_context_regs_t context_state; | |
| 182 | − drm_mga_server_regs_t server_state; | |
| 183 | − drm_mga_texture_regs_t tex_state[2]; | |
| 184 | − unsigned int warp_pipe; | |
| 185 | − unsigned int dirty; | |
| 186 | − unsigned int vertsize; | |
| 187 | − | |
| 188 | − /* The current cliprects, or a subset thereof. | |
| 189 | − */ | |
| 190 | − struct drm_clip_rect boxes[MGA_NR_SAREA_CLIPRECTS]; | |
| 191 | − unsigned int nbox; | |
| 192 | − | |
| 193 | − /* Information about the most recently used 3d drawable. The | |
| 194 | − * client fills in the req_* fields, the server fills in the | |
| 195 | − * exported_ fields and puts the cliprects into boxes, above. | |
| 196 | − * | |
| 197 | − * The client clears the exported_drawable field before | |
| 198 | − * clobbering the boxes data. | |
| 199 | − */ | |
| 200 | − unsigned int req_drawable; /* the X drawable id */ | |
| 201 | − unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ | |
| 202 | − | |
| 203 | − unsigned int exported_drawable; | |
| 204 | − unsigned int exported_index; | |
| 205 | − unsigned int exported_stamp; | |
| 206 | − unsigned int exported_buffers; | |
| 207 | − unsigned int exported_nfront; | |
| 208 | − unsigned int exported_nback; | |
| 209 | − int exported_back_x, exported_front_x, exported_w; | |
| 210 | − int exported_back_y, exported_front_y, exported_h; | |
| 211 | − struct drm_clip_rect exported_boxes[MGA_NR_SAREA_CLIPRECTS]; | |
| 212 | − | |
| 213 | − /* Counters for aging textures and for client-side throttling. | |
| 214 | − */ | |
| 215 | − unsigned int status[4]; | |
| 216 | − unsigned int last_wrap; | |
| 217 | − | |
| 218 | − drm_mga_age_t last_frame; | |
| 219 | − unsigned int last_enqueue; /* last time a buffer was enqueued */ | |
| 220 | − unsigned int last_dispatch; /* age of the most recently dispatched buffer */ | |
| 221 | − unsigned int last_quiescent; /* */ | |
| 222 | − | |
| 223 | − /* LRU lists for texture memory in agp space and on the card. | |
| 224 | − */ | |
| 225 | − struct drm_tex_region texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1]; | |
| 226 | − unsigned int texAge[MGA_NR_TEX_HEAPS]; | |
| 227 | − | |
| 228 | − /* Mechanism to validate card state. | |
| 229 | − */ | |
| 230 | − int ctxOwner; | |
| 231 | −} drm_mga_sarea_t; | |
| 232 | − | |
| 233 | −/* MGA specific ioctls | |
| 234 | − * The device specific ioctl range is 0x40 to 0x79. | |
| 235 | − */ | |
| 236 | −#define DRM_MGA_INIT 0x00 | |
| 237 | −#define DRM_MGA_FLUSH 0x01 | |
| 238 | −#define DRM_MGA_RESET 0x02 | |
| 239 | −#define DRM_MGA_SWAP 0x03 | |
| 240 | −#define DRM_MGA_CLEAR 0x04 | |
| 241 | −#define DRM_MGA_VERTEX 0x05 | |
| 242 | −#define DRM_MGA_INDICES 0x06 | |
| 243 | −#define DRM_MGA_ILOAD 0x07 | |
| 244 | −#define DRM_MGA_BLIT 0x08 | |
| 245 | −#define DRM_MGA_GETPARAM 0x09 | |
| 246 | − | |
| 247 | −/* 3.2: | |
| 248 | − * ioctls for operating on fences. | |
| 249 | − */ | |
| 250 | −#define DRM_MGA_SET_FENCE 0x0a | |
| 251 | −#define DRM_MGA_WAIT_FENCE 0x0b | |
| 252 | −#define DRM_MGA_DMA_BOOTSTRAP 0x0c | |
| 253 | − | |
| 254 | −#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) | |
| 255 | −#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock) | |
| 256 | −#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) | |
| 257 | −#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP) | |
| 258 | −#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t) | |
| 259 | −#define DRM_IOCTL_MGA_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_VERTEX, drm_mga_vertex_t) | |
| 260 | −#define DRM_IOCTL_MGA_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INDICES, drm_mga_indices_t) | |
| 261 | −#define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t) | |
| 262 | −#define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t) | |
| 263 | −#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t) | |
| 264 | −#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, __u32) | |
| 265 | −#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, __u32) | |
| 266 | −#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t) | |
| 267 | − | |
| 268 | −typedef struct _drm_mga_warp_index { | |
| 269 | − int installed; | |
| 270 | − unsigned long phys_addr; | |
| 271 | − int size; | |
| 272 | −} drm_mga_warp_index_t; | |
| 273 | − | |
| 274 | −typedef struct drm_mga_init { | |
| 275 | − enum { | |
| 276 | − MGA_INIT_DMA = 0x01, | |
| 277 | − MGA_CLEANUP_DMA = 0x02 | |
| 278 | − } func; | |
| 279 | − | |
| 280 | − unsigned long sarea_priv_offset; | |
| 281 | − | |
| 282 | − __struct_group(/* no tag */, always32bit, /* no attrs */, | |
| 283 | − int chipset; | |
| 284 | − int sgram; | |
| 285 | − | |
| 286 | − unsigned int maccess; | |
| 287 | − | |
| 288 | − unsigned int fb_cpp; | |
| 289 | − unsigned int front_offset, front_pitch; | |
| 290 | − unsigned int back_offset, back_pitch; | |
| 291 | − | |
| 292 | − unsigned int depth_cpp; | |
| 293 | − unsigned int depth_offset, depth_pitch; | |
| 294 | − | |
| 295 | − unsigned int texture_offset[MGA_NR_TEX_HEAPS]; | |
| 296 | − unsigned int texture_size[MGA_NR_TEX_HEAPS]; | |
| 297 | − ); | |
| 298 | − | |
| 299 | − unsigned long fb_offset; | |
| 300 | − unsigned long mmio_offset; | |
| 301 | − unsigned long status_offset; | |
| 302 | − unsigned long warp_offset; | |
| 303 | − unsigned long primary_offset; | |
| 304 | − unsigned long buffers_offset; | |
| 305 | −} drm_mga_init_t; | |
| 306 | − | |
| 307 | −typedef struct drm_mga_dma_bootstrap { | |
| 308 | − /** | |
| 309 | − * \name AGP texture region | |
| 310 | − * | |
| 311 | − * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will | |
| 312 | − * be filled in with the actual AGP texture settings. | |
| 313 | − * | |
| 314 | − * \warning | |
| 315 | − * If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode | |
| 316 | − * is zero, it means that PCI memory (most likely through the use of | |
| 317 | − * an IOMMU) is being used for "AGP" textures. | |
| 318 | − */ | |
| 319 | − /*@{ */ | |
| 320 | − unsigned long texture_handle; /**< Handle used to map AGP textures. */ | |
| 321 | − __u32 texture_size; /**< Size of the AGP texture region. */ | |
| 322 | − /*@} */ | |
| 323 | − | |
| 324 | − /** | |
| 325 | − * Requested size of the primary DMA region. | |
| 326 | − * | |
| 327 | − * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be | |
| 328 | − * filled in with the actual AGP mode. If AGP was not available | |
| 329 | − */ | |
| 330 | − __u32 primary_size; | |
| 331 | − | |
| 332 | − /** | |
| 333 | − * Requested number of secondary DMA buffers. | |
| 334 | − * | |
| 335 | − * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be | |
| 336 | − * filled in with the actual number of secondary DMA buffers | |
| 337 | − * allocated. Particularly when PCI DMA is used, this may be | |
| 338 | − * (subtantially) less than the number requested. | |
| 339 | − */ | |
| 340 | − __u32 secondary_bin_count; | |
| 341 | − | |
| 342 | − /** | |
| 343 | − * Requested size of each secondary DMA buffer. | |
| 344 | − * | |
| 345 | − * While the kernel \b is free to reduce | |
| 346 | − * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed | |
| 347 | − * to reduce dma_mga_dma_bootstrap::secondary_bin_size. | |
| 348 | − */ | |
| 349 | − __u32 secondary_bin_size; | |
| 350 | − | |
| 351 | − /** | |
| 352 | − * Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X, | |
| 353 | − * \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is | |
| 354 | − * zero, it means that PCI DMA should be used, even if AGP is | |
| 355 | − * possible. | |
| 356 | − * | |
| 357 | − * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be | |
| 358 | − * filled in with the actual AGP mode. If AGP was not available | |
| 359 | − * (i.e., PCI DMA was used), this value will be zero. | |
| 360 | − */ | |
| 361 | − __u32 agp_mode; | |
| 362 | − | |
| 363 | − /** | |
| 364 | − * Desired AGP GART size, measured in megabytes. | |
| 365 | − */ | |
| 366 | − __u8 agp_size; | |
| 367 | −} drm_mga_dma_bootstrap_t; | |
| 368 | − | |
| 369 | −typedef struct drm_mga_clear { | |
| 370 | − unsigned int flags; | |
| 371 | − unsigned int clear_color; | |
| 372 | − unsigned int clear_depth; | |
| 373 | − unsigned int color_mask; | |
| 374 | − unsigned int depth_mask; | |
| 375 | −} drm_mga_clear_t; | |
| 376 | − | |
| 377 | −typedef struct drm_mga_vertex { | |
| 378 | − int idx; /* buffer to queue */ | |
| 379 | − int used; /* bytes in use */ | |
| 380 | − int discard; /* client finished with buffer? */ | |
| 381 | −} drm_mga_vertex_t; | |
| 382 | − | |
| 383 | −typedef struct drm_mga_indices { | |
| 384 | − int idx; /* buffer to queue */ | |
| 385 | − unsigned int start; | |
| 386 | − unsigned int end; | |
| 387 | − int discard; /* client finished with buffer? */ | |
| 388 | −} drm_mga_indices_t; | |
| 389 | − | |
| 390 | −typedef struct drm_mga_iload { | |
| 391 | − int idx; | |
| 392 | − unsigned int dstorg; | |
| 393 | − unsigned int length; | |
| 394 | −} drm_mga_iload_t; | |
| 395 | − | |
| 396 | −typedef struct _drm_mga_blit { | |
| 397 | − unsigned int planemask; | |
| 398 | − unsigned int srcorg; | |
| 399 | − unsigned int dstorg; | |
| 400 | − int src_pitch, dst_pitch; | |
| 401 | − int delta_sx, delta_sy; | |
| 402 | − int delta_dx, delta_dy; | |
| 403 | − int height, ydir; /* flip image vertically */ | |
| 404 | − int source_pitch, dest_pitch; | |
| 405 | −} drm_mga_blit_t; | |
| 406 | − | |
| 407 | −/* 3.1: An ioctl to get parameters that aren't available to the 3d | |
| 408 | − * client any other way. | |
| 409 | − */ | |
| 410 | −#define MGA_PARAM_IRQ_NR 1 | |
| 411 | − | |
| 412 | −/* 3.2: Query the actual card type. The DDX only distinguishes between | |
| 413 | − * G200 chips and non-G200 chips, which it calls G400. It turns out that | |
| 414 | − * there are some very sublte differences between the G4x0 chips and the G550 | |
| 415 | − * chips. Using this parameter query, a client-side driver can detect the | |
| 416 | − * difference between a G4x0 and a G550. | |
| 417 | − */ | |
| 418 | −#define MGA_PARAM_CARD_TYPE 2 | |
| 419 | − | |
| 420 | −typedef struct drm_mga_getparam { | |
| 421 | − int param; | |
| 422 | − void __user *value; | |
| 423 | −} drm_mga_getparam_t; | |
| 424 | − | |
| 425 | −#if defined(__cplusplus) | |
| 426 | −} | |
| 427 | −#endif | |
| 428 | − | |
| 429 | −#endif | |