/**
 * \file ati_pcigart.h 
 * ATI PCI GART support
 *
 * \author Gareth Hughes <gareth@valinux.com>
 */

/*
 * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
 *
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "drmP.h"

#if PAGE_SIZE == 65536
# define ATI_PCIGART_TABLE_ORDER	0
# define ATI_PCIGART_TABLE_PAGES	(1 << 0)
#elif PAGE_SIZE == 16384
# define ATI_PCIGART_TABLE_ORDER	1
# define ATI_PCIGART_TABLE_PAGES	(1 << 1)
#elif PAGE_SIZE == 8192
# define ATI_PCIGART_TABLE_ORDER 	2
# define ATI_PCIGART_TABLE_PAGES 	(1 << 2)
#elif PAGE_SIZE == 4096
# define ATI_PCIGART_TABLE_ORDER 	3
# define ATI_PCIGART_TABLE_PAGES 	(1 << 3)
#else
# error - PAGE_SIZE not 64K, 16K, 8K or 4K
#endif

# define ATI_MAX_PCIGART_PAGES		8192	/**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */

static unsigned long drm_ati_alloc_pcigart_table( void )
{
	unsigned long address;
	struct page *page;
	int i;
	DRM_DEBUG( "%s\n", __FUNCTION__ );

	address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
	if ( address == 0UL ) {
		return 0;
	}

	page = virt_to_page( address );

	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
		get_page(page);
		SetPageReserved( page );
	}

	DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
	return address;
}

static void drm_ati_free_pcigart_table( unsigned long address )
{
	struct page *page;
	int i;
	DRM_DEBUG( "%s\n", __FUNCTION__ );

	page = virt_to_page( address );

	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
		__put_page(page);
		ClearPageReserved( page );
	}

	free_pages( address, ATI_PCIGART_TABLE_ORDER );
}

int drm_ati_pcigart_cleanup( drm_device_t *dev,
			      unsigned long addr,
			      dma_addr_t bus_addr)
{
	drm_sg_mem_t *entry = dev->sg;
	unsigned long pages;
	int i;

	/* we need to support large memory configurations */
	if ( !entry ) {
		DRM_ERROR( "no scatter/gather memory!\n" );
		return 0;
	}

	if ( bus_addr ) {
		pci_unmap_single(dev->pdev, bus_addr,
				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
				 PCI_DMA_TODEVICE);

		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
		        ? entry->pages : ATI_MAX_PCIGART_PAGES;

		for ( i = 0 ; i < pages ; i++ ) {
			if ( !entry->busaddr[i] ) break;
			pci_unmap_single(dev->pdev, entry->busaddr[i],
					 PAGE_SIZE, PCI_DMA_TODEVICE);
		}
	}

	if ( addr ) {
		drm_ati_free_pcigart_table( addr );
	}

	return 1;
}
EXPORT_SYMBOL(drm_ati_pcigart_cleanup);

int drm_ati_pcigart_init( drm_device_t *dev,
			   unsigned long *addr,
			   dma_addr_t *bus_addr)
{
	drm_sg_mem_t *entry = dev->sg;
	unsigned long address = 0;
	unsigned long pages;
	u32 *pci_gart, page_base, bus_address = 0;
	int i, j, ret = 0;

	if ( !entry ) {
		DRM_ERROR( "no scatter/gather memory!\n" );
		goto done;
	}

	address = drm_ati_alloc_pcigart_table();
	if ( !address ) {
		DRM_ERROR( "cannot allocate PCI GART page!\n" );
		goto done;
	}

	if ( !dev->pdev ) {
		DRM_ERROR( "PCI device unknown!\n" );
		goto done;
	}

	bus_address = pci_map_single(dev->pdev, (void *)address,
				  ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
				  PCI_DMA_TODEVICE);
	if (bus_address == 0) {
		DRM_ERROR( "unable to map PCIGART pages!\n" );
		drm_ati_free_pcigart_table( address );
		address = 0;
		goto done;
	}

	pci_gart = (u32 *)address;

	pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
		? entry->pages : ATI_MAX_PCIGART_PAGES;

	memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );

	for ( i = 0 ; i < pages ; i++ ) {
		/* we need to support large memory configurations */
		entry->busaddr[i] = pci_map_single(dev->pdev,
					   page_address( entry->pagelist[i] ),
					   PAGE_SIZE,
					   PCI_DMA_TODEVICE);
		if (entry->busaddr[i] == 0) {
			DRM_ERROR( "unable to map PCIGART pages!\n" );
			drm_ati_pcigart_cleanup( dev, address, bus_address );
			address = 0;
			bus_address = 0;
			goto done;
		}
		page_base = (u32) entry->busaddr[i];

		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
			*pci_gart++ = cpu_to_le32( page_base );
			page_base += ATI_PCIGART_PAGE_SIZE;
		}
	}

	ret = 1;

#if defined(__i386__) || defined(__x86_64__)
	wbinvd();
#else
	mb();
#endif

done:
	*addr = address;
	*bus_addr = bus_address;
	return ret;
}
EXPORT_SYMBOL(drm_ati_pcigart_init);
