xref: /dflybsd-src/sys/dev/drm/drm_dma.c (revision 1dedbd3b06c68f627b7825694444529d5eb2b1bf)
11b13d190SFrançois Tigeot /**
21b13d190SFrançois Tigeot  * \file drm_dma.c
31b13d190SFrançois Tigeot  * DMA IOCTL and function support
41b13d190SFrançois Tigeot  *
51b13d190SFrançois Tigeot  * \author Rickard E. (Rik) Faith <faith@valinux.com>
61b13d190SFrançois Tigeot  * \author Gareth Hughes <gareth@valinux.com>
71b13d190SFrançois Tigeot  */
81b13d190SFrançois Tigeot 
91b13d190SFrançois Tigeot /*
101b13d190SFrançois Tigeot  * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
111b13d190SFrançois Tigeot  *
127f3c3d6fSHasso Tepper  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
137f3c3d6fSHasso Tepper  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
147f3c3d6fSHasso Tepper  * All Rights Reserved.
157f3c3d6fSHasso Tepper  *
167f3c3d6fSHasso Tepper  * Permission is hereby granted, free of charge, to any person obtaining a
177f3c3d6fSHasso Tepper  * copy of this software and associated documentation files (the "Software"),
187f3c3d6fSHasso Tepper  * to deal in the Software without restriction, including without limitation
197f3c3d6fSHasso Tepper  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
207f3c3d6fSHasso Tepper  * and/or sell copies of the Software, and to permit persons to whom the
217f3c3d6fSHasso Tepper  * Software is furnished to do so, subject to the following conditions:
227f3c3d6fSHasso Tepper  *
237f3c3d6fSHasso Tepper  * The above copyright notice and this permission notice (including the next
247f3c3d6fSHasso Tepper  * paragraph) shall be included in all copies or substantial portions of the
257f3c3d6fSHasso Tepper  * Software.
267f3c3d6fSHasso Tepper  *
277f3c3d6fSHasso Tepper  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
287f3c3d6fSHasso Tepper  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
297f3c3d6fSHasso Tepper  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
307f3c3d6fSHasso Tepper  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
317f3c3d6fSHasso Tepper  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
327f3c3d6fSHasso Tepper  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
337f3c3d6fSHasso Tepper  * OTHER DEALINGS IN THE SOFTWARE.
347f3c3d6fSHasso Tepper  */
357f3c3d6fSHasso Tepper 
361b13d190SFrançois Tigeot #include <linux/export.h>
3718e26a6dSFrançois Tigeot #include <drm/drmP.h>
381b13d190SFrançois Tigeot #include "drm_legacy.h"
397f3c3d6fSHasso Tepper 
401b13d190SFrançois Tigeot /**
411b13d190SFrançois Tigeot  * Initialize the DMA data.
421b13d190SFrançois Tigeot  *
431b13d190SFrançois Tigeot  * \param dev DRM device.
441b13d190SFrançois Tigeot  * \return zero on success or a negative value on failure.
451b13d190SFrançois Tigeot  *
461b13d190SFrançois Tigeot  * Allocate and initialize a drm_device_dma structure.
471b13d190SFrançois Tigeot  */
drm_legacy_dma_setup(struct drm_device * dev)481b13d190SFrançois Tigeot int drm_legacy_dma_setup(struct drm_device *dev)
497f3c3d6fSHasso Tepper {
50394ce297SFrançois Tigeot 	int i;
517f3c3d6fSHasso Tepper 
521b13d190SFrançois Tigeot 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
53*1dedbd3bSFrançois Tigeot 	    !drm_core_check_feature(dev, DRIVER_LEGACY))
541b13d190SFrançois Tigeot 		return 0;
551b13d190SFrançois Tigeot 
561b13d190SFrançois Tigeot 	dev->buf_use = 0;
571b13d190SFrançois Tigeot 	atomic_set(&dev->buf_alloc, 0);
581b13d190SFrançois Tigeot 
591b13d190SFrançois Tigeot 	dev->dma = kzalloc(sizeof(*dev->dma), GFP_KERNEL);
601b13d190SFrançois Tigeot 	if (!dev->dma)
611b13d190SFrançois Tigeot 		return -ENOMEM;
627f3c3d6fSHasso Tepper 
63394ce297SFrançois Tigeot 	for (i = 0; i <= DRM_MAX_ORDER; i++)
64394ce297SFrançois Tigeot 		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
657f3c3d6fSHasso Tepper 
667f3c3d6fSHasso Tepper 	return 0;
677f3c3d6fSHasso Tepper }
687f3c3d6fSHasso Tepper 
691b13d190SFrançois Tigeot /**
701b13d190SFrançois Tigeot  * Cleanup the DMA resources.
711b13d190SFrançois Tigeot  *
721b13d190SFrançois Tigeot  * \param dev DRM device.
731b13d190SFrançois Tigeot  *
741b13d190SFrançois Tigeot  * Free all pages associated with DMA buffers, the buffers and pages lists, and
751b13d190SFrançois Tigeot  * finally the drm_device::dma structure itself.
761b13d190SFrançois Tigeot  */
drm_legacy_dma_takedown(struct drm_device * dev)771b13d190SFrançois Tigeot void drm_legacy_dma_takedown(struct drm_device *dev)
787f3c3d6fSHasso Tepper {
794250aa95Szrj 	struct drm_device_dma *dma = dev->dma;
807f3c3d6fSHasso Tepper 	int i, j;
817f3c3d6fSHasso Tepper 
82394ce297SFrançois Tigeot 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
83*1dedbd3bSFrançois Tigeot 	    !drm_core_check_feature(dev, DRIVER_LEGACY))
84394ce297SFrançois Tigeot 		return;
85394ce297SFrançois Tigeot 
86394ce297SFrançois Tigeot 	if (!dma)
877f3c3d6fSHasso Tepper 		return;
887f3c3d6fSHasso Tepper 
897f3c3d6fSHasso Tepper 	/* Clear dma buffers */
907f3c3d6fSHasso Tepper 	for (i = 0; i <= DRM_MAX_ORDER; i++) {
917f3c3d6fSHasso Tepper 		if (dma->bufs[i].seg_count) {
927f3c3d6fSHasso Tepper 			DRM_DEBUG("order %d: buf_count = %d,"
93394ce297SFrançois Tigeot 				  " seg_count = %d\n",
94394ce297SFrançois Tigeot 				  i,
95394ce297SFrançois Tigeot 				  dma->bufs[i].buf_count,
967f3c3d6fSHasso Tepper 				  dma->bufs[i].seg_count);
977f3c3d6fSHasso Tepper 			for (j = 0; j < dma->bufs[i].seg_count; j++) {
98394ce297SFrançois Tigeot 				if (dma->bufs[i].seglist[j]) {
997f3c3d6fSHasso Tepper 					drm_pci_free(dev, dma->bufs[i].seglist[j]);
1007f3c3d6fSHasso Tepper 				}
101394ce297SFrançois Tigeot 			}
1024250aa95Szrj 			kfree(dma->bufs[i].seglist);
1037f3c3d6fSHasso Tepper 		}
1047f3c3d6fSHasso Tepper 		if (dma->bufs[i].buf_count) {
1057f3c3d6fSHasso Tepper 			for (j = 0; j < dma->bufs[i].buf_count; j++) {
1064250aa95Szrj 				kfree(dma->bufs[i].buflist[j].dev_private);
1077f3c3d6fSHasso Tepper 			}
1084250aa95Szrj 			kfree(dma->bufs[i].buflist);
1097f3c3d6fSHasso Tepper 		}
1107f3c3d6fSHasso Tepper 	}
1117f3c3d6fSHasso Tepper 
1124250aa95Szrj 	kfree(dma->buflist);
1134250aa95Szrj 	kfree(dma->pagelist);
1144250aa95Szrj 	kfree(dev->dma);
1157f3c3d6fSHasso Tepper 	dev->dma = NULL;
1167f3c3d6fSHasso Tepper }
1177f3c3d6fSHasso Tepper 
1184250aa95Szrj /**
1194250aa95Szrj  * Free a buffer.
1204250aa95Szrj  *
1214250aa95Szrj  * \param dev DRM device.
1224250aa95Szrj  * \param buf buffer to free.
1234250aa95Szrj  *
1244250aa95Szrj  * Resets the fields of \p buf.
1254250aa95Szrj  */
drm_legacy_free_buffer(struct drm_device * dev,struct drm_buf * buf)1261b13d190SFrançois Tigeot void drm_legacy_free_buffer(struct drm_device *dev, struct drm_buf * buf)
1277f3c3d6fSHasso Tepper {
128b3705d71SHasso Tepper 	if (!buf)
129b3705d71SHasso Tepper 		return;
1307f3c3d6fSHasso Tepper 
131394ce297SFrançois Tigeot 	buf->waiting = 0;
1327f3c3d6fSHasso Tepper 	buf->pending = 0;
1337f3c3d6fSHasso Tepper 	buf->file_priv = NULL;
1347f3c3d6fSHasso Tepper 	buf->used = 0;
1357f3c3d6fSHasso Tepper }
1367f3c3d6fSHasso Tepper 
1374250aa95Szrj /**
1384250aa95Szrj  * Reclaim the buffers.
1394250aa95Szrj  *
1404250aa95Szrj  * \param file_priv DRM file private.
1414250aa95Szrj  *
1424250aa95Szrj  * Frees each buffer associated with \p file_priv not already on the hardware.
1434250aa95Szrj  */
drm_legacy_reclaim_buffers(struct drm_device * dev,struct drm_file * file_priv)1441b13d190SFrançois Tigeot void drm_legacy_reclaim_buffers(struct drm_device *dev,
1451b13d190SFrançois Tigeot 				struct drm_file *file_priv)
1467f3c3d6fSHasso Tepper {
1474250aa95Szrj 	struct drm_device_dma *dma = dev->dma;
1487f3c3d6fSHasso Tepper 	int i;
1497f3c3d6fSHasso Tepper 
150b3705d71SHasso Tepper 	if (!dma)
151b3705d71SHasso Tepper 		return;
1527f3c3d6fSHasso Tepper 	for (i = 0; i < dma->buf_count; i++) {
1537f3c3d6fSHasso Tepper 		if (dma->buflist[i]->file_priv == file_priv) {
1547f3c3d6fSHasso Tepper 			switch (dma->buflist[i]->list) {
1557f3c3d6fSHasso Tepper 			case DRM_LIST_NONE:
1561b13d190SFrançois Tigeot 				drm_legacy_free_buffer(dev, dma->buflist[i]);
1577f3c3d6fSHasso Tepper 				break;
1587f3c3d6fSHasso Tepper 			case DRM_LIST_WAIT:
1597f3c3d6fSHasso Tepper 				dma->buflist[i]->list = DRM_LIST_RECLAIM;
1607f3c3d6fSHasso Tepper 				break;
1617f3c3d6fSHasso Tepper 			default:
1627f3c3d6fSHasso Tepper 				/* Buffer already on hardware. */
1637f3c3d6fSHasso Tepper 				break;
1647f3c3d6fSHasso Tepper 			}
1657f3c3d6fSHasso Tepper 		}
1667f3c3d6fSHasso Tepper 	}
1677f3c3d6fSHasso Tepper }
168