Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
   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
  47static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup);
  48
  49/* ================================================================
  50 * Engine control
  51 */
  52
  53int 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
  75static 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
 103void 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
 158void 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
 198void 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
 223static 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
 244static 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
 287static 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 */
 307static 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
 322static 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
 355int 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
 390int mga_driver_load(struct drm_device *dev, unsigned long flags)
 391{
 392	drm_mga_private_t *dev_priv;
 393	int ret;
 394
 395	/* There are PCI versions of the G450.  These cards have the
 396	 * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
 397	 * bridge chip.  We detect these cards, which are not currently
 398	 * supported by this driver, by looking at the device ID of the
 399	 * bus the "card" is on.  If vendor is 0x3388 (Hint Corp) and the
 400	 * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
 401	 * device.
 402	 */
 403	if ((dev->pdev->device == 0x0525) && dev->pdev->bus->self
 404	    && (dev->pdev->bus->self->vendor == 0x3388)
 405	    && (dev->pdev->bus->self->device == 0x0021)
 406	    && dev->agp) {
 407		/* FIXME: This should be quirked in the pci core, but oh well
 408		 * the hw probably stopped existing. */
 409		arch_phys_wc_del(dev->agp->agp_mtrr);
 410		kfree(dev->agp);
 411		dev->agp = NULL;
 412	}
 413	dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL);
 414	if (!dev_priv)
 415		return -ENOMEM;
 416
 417	dev->dev_private = (void *)dev_priv;
 418
 419	dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
 420	dev_priv->chipset = flags;
 421
 422	pci_set_master(dev->pdev);
 423
 424	dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
 425	dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
 426
 427	ret = drm_vblank_init(dev, 1);
 428
 429	if (ret) {
 430		(void) mga_driver_unload(dev);
 431		return ret;
 432	}
 433
 434	return 0;
 435}
 436
 437#if IS_ENABLED(CONFIG_AGP)
 438/**
 439 * Bootstrap the driver for AGP DMA.
 440 *
 441 * \todo
 442 * Investigate whether there is any benefit to storing the WARP microcode in
 443 * AGP memory.  If not, the microcode may as well always be put in PCI
 444 * memory.
 445 *
 446 * \todo
 447 * This routine needs to set dma_bs->agp_mode to the mode actually configured
 448 * in the hardware.  Looking just at the Linux AGP driver code, I don't see
 449 * an easy way to determine this.
 450 *
 451 * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap
 452 */
 453static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
 454				    drm_mga_dma_bootstrap_t *dma_bs)
 455{
 456	drm_mga_private_t *const dev_priv =
 457	    (drm_mga_private_t *) dev->dev_private;
 458	unsigned int warp_size = MGA_WARP_UCODE_SIZE;
 459	int err;
 460	unsigned offset;
 461	const unsigned secondary_size = dma_bs->secondary_bin_count
 462	    * dma_bs->secondary_bin_size;
 463	const unsigned agp_size = (dma_bs->agp_size << 20);
 464	struct drm_buf_desc req;
 465	struct drm_agp_mode mode;
 466	struct drm_agp_info info;
 467	struct drm_agp_buffer agp_req;
 468	struct drm_agp_binding bind_req;
 469
 470	/* Acquire AGP. */
 471	err = drm_agp_acquire(dev);
 472	if (err) {
 473		DRM_ERROR("Unable to acquire AGP: %d\n", err);
 474		return err;
 475	}
 476
 477	err = drm_agp_info(dev, &info);
 478	if (err) {
 479		DRM_ERROR("Unable to get AGP info: %d\n", err);
 480		return err;
 481	}
 482
 483	mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode;
 484	err = drm_agp_enable(dev, mode);
 485	if (err) {
 486		DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
 487		return err;
 488	}
 489
 490	/* In addition to the usual AGP mode configuration, the G200 AGP cards
 491	 * need to have the AGP mode "manually" set.
 492	 */
 493
 494	if (dev_priv->chipset == MGA_CARD_TYPE_G200) {
 495		if (mode.mode & 0x02)
 496			MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE);
 497		else
 498			MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE);
 499	}
 500
 501	/* Allocate and bind AGP memory. */
 502	agp_req.size = agp_size;
 503	agp_req.type = 0;
 504	err = drm_agp_alloc(dev, &agp_req);
 505	if (err) {
 506		dev_priv->agp_size = 0;
 507		DRM_ERROR("Unable to allocate %uMB AGP memory\n",
 508			  dma_bs->agp_size);
 509		return err;
 510	}
 511
 512	dev_priv->agp_size = agp_size;
 513	dev_priv->agp_handle = agp_req.handle;
 514
 515	bind_req.handle = agp_req.handle;
 516	bind_req.offset = 0;
 517	err = drm_agp_bind(dev, &bind_req);
 518	if (err) {
 519		DRM_ERROR("Unable to bind AGP memory: %d\n", err);
 520		return err;
 521	}
 522
 523	/* Make drm_legacy_addbufs happy by not trying to create a mapping for
 524	 * less than a page.
 525	 */
 526	if (warp_size < PAGE_SIZE)
 527		warp_size = PAGE_SIZE;
 528
 529	offset = 0;
 530	err = drm_legacy_addmap(dev, offset, warp_size,
 531				_DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
 532	if (err) {
 533		DRM_ERROR("Unable to map WARP microcode: %d\n", err);
 534		return err;
 535	}
 536
 537	offset += warp_size;
 538	err = drm_legacy_addmap(dev, offset, dma_bs->primary_size,
 539				_DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
 540	if (err) {
 541		DRM_ERROR("Unable to map primary DMA region: %d\n", err);
 542		return err;
 543	}
 544
 545	offset += dma_bs->primary_size;
 546	err = drm_legacy_addmap(dev, offset, secondary_size,
 547				_DRM_AGP, 0, &dev->agp_buffer_map);
 548	if (err) {
 549		DRM_ERROR("Unable to map secondary DMA region: %d\n", err);
 550		return err;
 551	}
 552
 553	(void)memset(&req, 0, sizeof(req));
 554	req.count = dma_bs->secondary_bin_count;
 555	req.size = dma_bs->secondary_bin_size;
 556	req.flags = _DRM_AGP_BUFFER;
 557	req.agp_start = offset;
 558
 559	err = drm_legacy_addbufs_agp(dev, &req);
 560	if (err) {
 561		DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
 562		return err;
 563	}
 564
 565	{
 566		struct drm_map_list *_entry;
 567		unsigned long agp_token = 0;
 568
 569		list_for_each_entry(_entry, &dev->maplist, head) {
 570			if (_entry->map == dev->agp_buffer_map)
 571				agp_token = _entry->user_token;
 572		}
 573		if (!agp_token)
 574			return -EFAULT;
 575
 576		dev->agp_buffer_token = agp_token;
 577	}
 578
 579	offset += secondary_size;
 580	err = drm_legacy_addmap(dev, offset, agp_size - offset,
 581				_DRM_AGP, 0, &dev_priv->agp_textures);
 582	if (err) {
 583		DRM_ERROR("Unable to map AGP texture region %d\n", err);
 584		return err;
 585	}
 586
 587	drm_legacy_ioremap(dev_priv->warp, dev);
 588	drm_legacy_ioremap(dev_priv->primary, dev);
 589	drm_legacy_ioremap(dev->agp_buffer_map, dev);
 590
 591	if (!dev_priv->warp->handle ||
 592	    !dev_priv->primary->handle || !dev->agp_buffer_map->handle) {
 593		DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n",
 594			  dev_priv->warp->handle, dev_priv->primary->handle,
 595			  dev->agp_buffer_map->handle);
 596		return -ENOMEM;
 597	}
 598
 599	dev_priv->dma_access = MGA_PAGPXFER;
 600	dev_priv->wagp_enable = MGA_WAGP_ENABLE;
 601
 602	DRM_INFO("Initialized card for AGP DMA.\n");
 603	return 0;
 604}
 605#else
 606static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
 607				    drm_mga_dma_bootstrap_t *dma_bs)
 608{
 609	return -EINVAL;
 610}
 611#endif
 612
 613/**
 614 * Bootstrap the driver for PCI DMA.
 615 *
 616 * \todo
 617 * The algorithm for decreasing the size of the primary DMA buffer could be
 618 * better.  The size should be rounded up to the nearest page size, then
 619 * decrease the request size by a single page each pass through the loop.
 620 *
 621 * \todo
 622 * Determine whether the maximum address passed to drm_pci_alloc is correct.
 623 * The same goes for drm_legacy_addbufs_pci.
 624 *
 625 * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap
 626 */
 627static int mga_do_pci_dma_bootstrap(struct drm_device *dev,
 628				    drm_mga_dma_bootstrap_t *dma_bs)
 629{
 630	drm_mga_private_t *const dev_priv =
 631	    (drm_mga_private_t *) dev->dev_private;
 632	unsigned int warp_size = MGA_WARP_UCODE_SIZE;
 633	unsigned int primary_size;
 634	unsigned int bin_count;
 635	int err;
 636	struct drm_buf_desc req;
 637
 638	if (dev->dma == NULL) {
 639		DRM_ERROR("dev->dma is NULL\n");
 640		return -EFAULT;
 641	}
 642
 643	/* Make drm_legacy_addbufs happy by not trying to create a mapping for
 644	 * less than a page.
 645	 */
 646	if (warp_size < PAGE_SIZE)
 647		warp_size = PAGE_SIZE;
 648
 649	/* The proper alignment is 0x100 for this mapping */
 650	err = drm_legacy_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
 651				_DRM_READ_ONLY, &dev_priv->warp);
 652	if (err != 0) {
 653		DRM_ERROR("Unable to create mapping for WARP microcode: %d\n",
 654			  err);
 655		return err;
 656	}
 657
 658	/* Other than the bottom two bits being used to encode other
 659	 * information, there don't appear to be any restrictions on the
 660	 * alignment of the primary or secondary DMA buffers.
 661	 */
 662
 663	for (primary_size = dma_bs->primary_size; primary_size != 0;
 664	     primary_size >>= 1) {
 665		/* The proper alignment for this mapping is 0x04 */
 666		err = drm_legacy_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
 667					_DRM_READ_ONLY, &dev_priv->primary);
 668		if (!err)
 669			break;
 670	}
 671
 672	if (err != 0) {
 673		DRM_ERROR("Unable to allocate primary DMA region: %d\n", err);
 674		return -ENOMEM;
 675	}
 676
 677	if (dev_priv->primary->size != dma_bs->primary_size) {
 678		DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
 679			 dma_bs->primary_size,
 680			 (unsigned)dev_priv->primary->size);
 681		dma_bs->primary_size = dev_priv->primary->size;
 682	}
 683
 684	for (bin_count = dma_bs->secondary_bin_count; bin_count > 0;
 685	     bin_count--) {
 686		(void)memset(&req, 0, sizeof(req));
 687		req.count = bin_count;
 688		req.size = dma_bs->secondary_bin_size;
 689
 690		err = drm_legacy_addbufs_pci(dev, &req);
 691		if (!err)
 692			break;
 693	}
 694
 695	if (bin_count == 0) {
 696		DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
 697		return err;
 698	}
 699
 700	if (bin_count != dma_bs->secondary_bin_count) {
 701		DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u "
 702			 "to %u.\n", dma_bs->secondary_bin_count, bin_count);
 703
 704		dma_bs->secondary_bin_count = bin_count;
 705	}
 706
 707	dev_priv->dma_access = 0;
 708	dev_priv->wagp_enable = 0;
 709
 710	dma_bs->agp_mode = 0;
 711
 712	DRM_INFO("Initialized card for PCI DMA.\n");
 713	return 0;
 714}
 715
 716static int mga_do_dma_bootstrap(struct drm_device *dev,
 717				drm_mga_dma_bootstrap_t *dma_bs)
 718{
 719	const int is_agp = (dma_bs->agp_mode != 0) && dev->agp;
 720	int err;
 721	drm_mga_private_t *const dev_priv =
 722	    (drm_mga_private_t *) dev->dev_private;
 723
 724	dev_priv->used_new_dma_init = 1;
 725
 726	/* The first steps are the same for both PCI and AGP based DMA.  Map
 727	 * the cards MMIO registers and map a status page.
 728	 */
 729	err = drm_legacy_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
 730				_DRM_REGISTERS, _DRM_READ_ONLY,
 731				&dev_priv->mmio);
 732	if (err) {
 733		DRM_ERROR("Unable to map MMIO region: %d\n", err);
 734		return err;
 735	}
 736
 737	err = drm_legacy_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
 738				_DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
 739			 &dev_priv->status);
 740	if (err) {
 741		DRM_ERROR("Unable to map status region: %d\n", err);
 742		return err;
 743	}
 744
 745	/* The DMA initialization procedure is slightly different for PCI and
 746	 * AGP cards.  AGP cards just allocate a large block of AGP memory and
 747	 * carve off portions of it for internal uses.  The remaining memory
 748	 * is returned to user-mode to be used for AGP textures.
 749	 */
 750	if (is_agp)
 751		err = mga_do_agp_dma_bootstrap(dev, dma_bs);
 752
 753	/* If we attempted to initialize the card for AGP DMA but failed,
 754	 * clean-up any mess that may have been created.
 755	 */
 756
 757	if (err)
 758		mga_do_cleanup_dma(dev, MINIMAL_CLEANUP);
 759
 760	/* Not only do we want to try and initialized PCI cards for PCI DMA,
 761	 * but we also try to initialized AGP cards that could not be
 762	 * initialized for AGP DMA.  This covers the case where we have an AGP
 763	 * card in a system with an unsupported AGP chipset.  In that case the
 764	 * card will be detected as AGP, but we won't be able to allocate any
 765	 * AGP memory, etc.
 766	 */
 767
 768	if (!is_agp || err)
 769		err = mga_do_pci_dma_bootstrap(dev, dma_bs);
 770
 771	return err;
 772}
 773
 774int mga_dma_bootstrap(struct drm_device *dev, void *data,
 775		      struct drm_file *file_priv)
 776{
 777	drm_mga_dma_bootstrap_t *bootstrap = data;
 778	int err;
 779	static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
 780	const drm_mga_private_t *const dev_priv =
 781		(drm_mga_private_t *) dev->dev_private;
 782
 783	err = mga_do_dma_bootstrap(dev, bootstrap);
 784	if (err) {
 785		mga_do_cleanup_dma(dev, FULL_CLEANUP);
 786		return err;
 787	}
 788
 789	if (dev_priv->agp_textures != NULL) {
 790		bootstrap->texture_handle = dev_priv->agp_textures->offset;
 791		bootstrap->texture_size = dev_priv->agp_textures->size;
 792	} else {
 793		bootstrap->texture_handle = 0;
 794		bootstrap->texture_size = 0;
 795	}
 796
 797	bootstrap->agp_mode = modes[bootstrap->agp_mode & 0x07];
 798
 799	return err;
 800}
 801
 802static int mga_do_init_dma(struct drm_device *dev, drm_mga_init_t *init)
 803{
 804	drm_mga_private_t *dev_priv;
 805	int ret;
 806	DRM_DEBUG("\n");
 807
 808	dev_priv = dev->dev_private;
 809
 810	if (init->sgram)
 811		dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;
 812	else
 813		dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
 814	dev_priv->maccess = init->maccess;
 815
 816	dev_priv->fb_cpp = init->fb_cpp;
 817	dev_priv->front_offset = init->front_offset;
 818	dev_priv->front_pitch = init->front_pitch;
 819	dev_priv->back_offset = init->back_offset;
 820	dev_priv->back_pitch = init->back_pitch;
 821
 822	dev_priv->depth_cpp = init->depth_cpp;
 823	dev_priv->depth_offset = init->depth_offset;
 824	dev_priv->depth_pitch = init->depth_pitch;
 825
 826	/* FIXME: Need to support AGP textures...
 827	 */
 828	dev_priv->texture_offset = init->texture_offset[0];
 829	dev_priv->texture_size = init->texture_size[0];
 830
 831	dev_priv->sarea = drm_legacy_getsarea(dev);
 832	if (!dev_priv->sarea) {
 833		DRM_ERROR("failed to find sarea!\n");
 834		return -EINVAL;
 835	}
 836
 837	if (!dev_priv->used_new_dma_init) {
 838
 839		dev_priv->dma_access = MGA_PAGPXFER;
 840		dev_priv->wagp_enable = MGA_WAGP_ENABLE;
 841
 842		dev_priv->status = drm_legacy_findmap(dev, init->status_offset);
 843		if (!dev_priv->status) {
 844			DRM_ERROR("failed to find status page!\n");
 845			return -EINVAL;
 846		}
 847		dev_priv->mmio = drm_legacy_findmap(dev, init->mmio_offset);
 848		if (!dev_priv->mmio) {
 849			DRM_ERROR("failed to find mmio region!\n");
 850			return -EINVAL;
 851		}
 852		dev_priv->warp = drm_legacy_findmap(dev, init->warp_offset);
 853		if (!dev_priv->warp) {
 854			DRM_ERROR("failed to find warp microcode region!\n");
 855			return -EINVAL;
 856		}
 857		dev_priv->primary = drm_legacy_findmap(dev, init->primary_offset);
 858		if (!dev_priv->primary) {
 859			DRM_ERROR("failed to find primary dma region!\n");
 860			return -EINVAL;
 861		}
 862		dev->agp_buffer_token = init->buffers_offset;
 863		dev->agp_buffer_map =
 864		    drm_legacy_findmap(dev, init->buffers_offset);
 865		if (!dev->agp_buffer_map) {
 866			DRM_ERROR("failed to find dma buffer region!\n");
 867			return -EINVAL;
 868		}
 869
 870		drm_legacy_ioremap(dev_priv->warp, dev);
 871		drm_legacy_ioremap(dev_priv->primary, dev);
 872		drm_legacy_ioremap(dev->agp_buffer_map, dev);
 873	}
 874
 875	dev_priv->sarea_priv =
 876	    (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle +
 877				 init->sarea_priv_offset);
 878
 879	if (!dev_priv->warp->handle ||
 880	    !dev_priv->primary->handle ||
 881	    ((dev_priv->dma_access != 0) &&
 882	     ((dev->agp_buffer_map == NULL) ||
 883	      (dev->agp_buffer_map->handle == NULL)))) {
 884		DRM_ERROR("failed to ioremap agp regions!\n");
 885		return -ENOMEM;
 886	}
 887
 888	ret = mga_warp_install_microcode(dev_priv);
 889	if (ret < 0) {
 890		DRM_ERROR("failed to install WARP ucode!: %d\n", ret);
 891		return ret;
 892	}
 893
 894	ret = mga_warp_init(dev_priv);
 895	if (ret < 0) {
 896		DRM_ERROR("failed to init WARP engine!: %d\n", ret);
 897		return ret;
 898	}
 899
 900	dev_priv->prim.status = (u32 *) dev_priv->status->handle;
 901
 902	mga_do_wait_for_idle(dev_priv);
 903
 904	/* Init the primary DMA registers.
 905	 */
 906	MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL);
 907#if 0
 908	MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 |	/* Soft trap, SECEND, SETUPEND */
 909		  MGA_PRIMPTREN1);	/* DWGSYNC */
 910#endif
 911
 912	dev_priv->prim.start = (u8 *) dev_priv->primary->handle;
 913	dev_priv->prim.end = ((u8 *) dev_priv->primary->handle
 914			      + dev_priv->primary->size);
 915	dev_priv->prim.size = dev_priv->primary->size;
 916
 917	dev_priv->prim.tail = 0;
 918	dev_priv->prim.space = dev_priv->prim.size;
 919	dev_priv->prim.wrapped = 0;
 920
 921	dev_priv->prim.last_flush = 0;
 922	dev_priv->prim.last_wrap = 0;
 923
 924	dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE;
 925
 926	dev_priv->prim.status[0] = dev_priv->primary->offset;
 927	dev_priv->prim.status[1] = 0;
 928
 929	dev_priv->sarea_priv->last_wrap = 0;
 930	dev_priv->sarea_priv->last_frame.head = 0;
 931	dev_priv->sarea_priv->last_frame.wrap = 0;
 932
 933	if (mga_freelist_init(dev, dev_priv) < 0) {
 934		DRM_ERROR("could not initialize freelist\n");
 935		return -ENOMEM;
 936	}
 937
 938	return 0;
 939}
 940
 941static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
 942{
 943	int err = 0;
 944	DRM_DEBUG("\n");
 945
 946	/* Make sure interrupts are disabled here because the uninstall ioctl
 947	 * may not have been called from userspace and after dev_private
 948	 * is freed, it's too late.
 949	 */
 950	if (dev->irq_enabled)
 951		drm_irq_uninstall(dev);
 952
 953	if (dev->dev_private) {
 954		drm_mga_private_t *dev_priv = dev->dev_private;
 955
 956		if ((dev_priv->warp != NULL)
 957		    && (dev_priv->warp->type != _DRM_CONSISTENT))
 958			drm_legacy_ioremapfree(dev_priv->warp, dev);
 959
 960		if ((dev_priv->primary != NULL)
 961		    && (dev_priv->primary->type != _DRM_CONSISTENT))
 962			drm_legacy_ioremapfree(dev_priv->primary, dev);
 963
 964		if (dev->agp_buffer_map != NULL)
 965			drm_legacy_ioremapfree(dev->agp_buffer_map, dev);
 966
 967		if (dev_priv->used_new_dma_init) {
 968#if IS_ENABLED(CONFIG_AGP)
 969			if (dev_priv->agp_handle != 0) {
 970				struct drm_agp_binding unbind_req;
 971				struct drm_agp_buffer free_req;
 972
 973				unbind_req.handle = dev_priv->agp_handle;
 974				drm_agp_unbind(dev, &unbind_req);
 975
 976				free_req.handle = dev_priv->agp_handle;
 977				drm_agp_free(dev, &free_req);
 978
 979				dev_priv->agp_textures = NULL;
 980				dev_priv->agp_size = 0;
 981				dev_priv->agp_handle = 0;
 982			}
 983
 984			if ((dev->agp != NULL) && dev->agp->acquired)
 985				err = drm_agp_release(dev);
 986#endif
 987		}
 988
 989		dev_priv->warp = NULL;
 990		dev_priv->primary = NULL;
 991		dev_priv->sarea = NULL;
 992		dev_priv->sarea_priv = NULL;
 993		dev->agp_buffer_map = NULL;
 994
 995		if (full_cleanup) {
 996			dev_priv->mmio = NULL;
 997			dev_priv->status = NULL;
 998			dev_priv->used_new_dma_init = 0;
 999		}
1000
1001		memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
1002		dev_priv->warp_pipe = 0;
1003		memset(dev_priv->warp_pipe_phys, 0,
1004		       sizeof(dev_priv->warp_pipe_phys));
1005
1006		if (dev_priv->head != NULL)
1007			mga_freelist_cleanup(dev);
1008	}
1009
1010	return err;
1011}
1012
1013int mga_dma_init(struct drm_device *dev, void *data,
1014		 struct drm_file *file_priv)
1015{
1016	drm_mga_init_t *init = data;
1017	int err;
1018
1019	LOCK_TEST_WITH_RETURN(dev, file_priv);
1020
1021	switch (init->func) {
1022	case MGA_INIT_DMA:
1023		err = mga_do_init_dma(dev, init);
1024		if (err)
1025			(void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
1026		return err;
1027	case MGA_CLEANUP_DMA:
1028		return mga_do_cleanup_dma(dev, FULL_CLEANUP);
1029	}
1030
1031	return -EINVAL;
1032}
1033
1034/* ================================================================
1035 * Primary DMA stream management
1036 */
1037
1038int mga_dma_flush(struct drm_device *dev, void *data,
1039		  struct drm_file *file_priv)
1040{
1041	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
1042	struct drm_lock *lock = data;
1043
1044	LOCK_TEST_WITH_RETURN(dev, file_priv);
1045
1046	DRM_DEBUG("%s%s%s\n",
1047		  (lock->flags & _DRM_LOCK_FLUSH) ? "flush, " : "",
1048		  (lock->flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
1049		  (lock->flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "");
1050
1051	WRAP_WAIT_WITH_RETURN(dev_priv);
1052
1053	if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL))
1054		mga_do_dma_flush(dev_priv);
1055
1056	if (lock->flags & _DRM_LOCK_QUIESCENT) {
1057#if MGA_DMA_DEBUG
1058		int ret = mga_do_wait_for_idle(dev_priv);
1059		if (ret < 0)
1060			DRM_INFO("-EBUSY\n");
1061		return ret;
1062#else
1063		return mga_do_wait_for_idle(dev_priv);
1064#endif
1065	} else {
1066		return 0;
1067	}
1068}
1069
1070int mga_dma_reset(struct drm_device *dev, void *data,
1071		  struct drm_file *file_priv)
1072{
1073	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
1074
1075	LOCK_TEST_WITH_RETURN(dev, file_priv);
1076
1077	return mga_do_dma_reset(dev_priv);
1078}
1079
1080/* ================================================================
1081 * DMA buffer management
1082 */
1083
1084static int mga_dma_get_buffers(struct drm_device *dev,
1085			       struct drm_file *file_priv, struct drm_dma *d)
1086{
1087	struct drm_buf *buf;
1088	int i;
1089
1090	for (i = d->granted_count; i < d->request_count; i++) {
1091		buf = mga_freelist_get(dev);
1092		if (!buf)
1093			return -EAGAIN;
1094
1095		buf->file_priv = file_priv;
1096
1097		if (copy_to_user(&d->request_indices[i],
1098				     &buf->idx, sizeof(buf->idx)))
1099			return -EFAULT;
1100		if (copy_to_user(&d->request_sizes[i],
1101				     &buf->total, sizeof(buf->total)))
1102			return -EFAULT;
1103
1104		d->granted_count++;
1105	}
1106	return 0;
1107}
1108
1109int mga_dma_buffers(struct drm_device *dev, void *data,
1110		    struct drm_file *file_priv)
1111{
1112	struct drm_device_dma *dma = dev->dma;
1113	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
1114	struct drm_dma *d = data;
1115	int ret = 0;
1116
1117	LOCK_TEST_WITH_RETURN(dev, file_priv);
1118
1119	/* Please don't send us buffers.
1120	 */
1121	if (d->send_count != 0) {
1122		DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
1123			  task_pid_nr(current), d->send_count);
1124		return -EINVAL;
1125	}
1126
1127	/* We'll send you buffers.
1128	 */
1129	if (d->request_count < 0 || d->request_count > dma->buf_count) {
1130		DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
1131			  task_pid_nr(current), d->request_count,
1132			  dma->buf_count);
1133		return -EINVAL;
1134	}
1135
1136	WRAP_TEST_WITH_RETURN(dev_priv);
1137
1138	d->granted_count = 0;
1139
1140	if (d->request_count)
1141		ret = mga_dma_get_buffers(dev, file_priv, d);
1142
1143	return ret;
1144}
1145
1146/**
1147 * Called just before the module is unloaded.
1148 */
1149void mga_driver_unload(struct drm_device *dev)
1150{
1151	kfree(dev->dev_private);
1152	dev->dev_private = NULL;
1153}
1154
1155/**
1156 * Called when the last opener of the device is closed.
1157 */
1158void mga_driver_lastclose(struct drm_device *dev)
1159{
1160	mga_do_cleanup_dma(dev, FULL_CLEANUP);
1161}
1162
1163int mga_driver_dma_quiescent(struct drm_device *dev)
1164{
1165	drm_mga_private_t *dev_priv = dev->dev_private;
1166	return mga_do_wait_for_idle(dev_priv);
1167}