From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/nvidia/nvidia_accel.h | 246 +++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/nvidia/nvidia_accel.h (limited to 'Source/DirectFB/gfxdrivers/nvidia/nvidia_accel.h') diff --git a/Source/DirectFB/gfxdrivers/nvidia/nvidia_accel.h b/Source/DirectFB/gfxdrivers/nvidia/nvidia_accel.h new file mode 100755 index 0000000..2858947 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/nvidia/nvidia_accel.h @@ -0,0 +1,246 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __NVIDIA_ACCEL_H__ +#define __NVIDIA_ACCEL_H__ + +#include + +#include "nvidia.h" +#include "nvidia_regs.h" + + +static __inline__ void +nv_out8( volatile void *mmioaddr, u32 reg, u8 value ) +{ + *((volatile u8*)(mmioaddr+reg)) = value; +} + +static __inline__ void +nv_out16( volatile void *mmioaddr, u32 reg, u16 value ) +{ + *((volatile u16*)(mmioaddr+reg)) = value; +} + +static __inline__ void +nv_out32( volatile void *mmioaddr, u32 reg, u32 value ) +{ + *((volatile u32*)(mmioaddr+reg)) = value; +} + +static __inline__ u8 +nv_in8( volatile void *mmioaddr, u32 reg ) +{ + return *((volatile u8*)(mmioaddr+reg)); +} + +static __inline__ u16 +nv_in16( volatile void *mmioaddr, u32 reg ) +{ + return *((volatile u16*)(mmioaddr+reg)); +} + +static __inline__ u32 +nv_in32( volatile void *mmioaddr, u32 reg ) +{ + return *((volatile u32*)(mmioaddr+reg)); +} + +static __inline__ void +nv_outcrtc( volatile void *mmioaddr, u8 reg, u8 value ) +{ + nv_out8( mmioaddr, PCIO_CRTC_INDEX, reg ); + nv_out8( mmioaddr, PCIO_CRTC_DATA, value ); +} + +static __inline__ u8 +nv_incrtc( volatile void *mmioaddr, u8 reg ) +{ + nv_out8( mmioaddr, PCIO_CRTC_INDEX, reg ); + return nv_in8( mmioaddr, PCIO_CRTC_DATA ); +} + +#define WAIT_MAX 10000000 + +static inline void +nv_waitidle( NVidiaDriverData *nvdrv, NVidiaDeviceData *nvdev ) +{ + u32 status; + int waitcycles = 0; + + do { + status = nv_in32( nvdrv->mmio_base, PGRAPH_STATUS ); + if (++waitcycles > WAIT_MAX) { + D_BREAK( "Engine timed out" ); + /* avoid card crash */ + _exit(-1); + } + } while (status & PGRAPH_STATUS_STATE_BUSY); + + nvdev->idle_waitcycles += waitcycles; +} + +/* + * FIFO control + */ + +static inline void +nv_waitfifo( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + unsigned int space ) +{ + volatile void *mmio = nvdrv->mmio_base; + int waitcycles = 0; + + nvdev->waitfree_sum += (space); + nvdev->waitfree_calls++; + + if (nvdev->fifo_free < space) { + do { +#ifdef WORDS_BIGENDIAN + nvdev->fifo_free = nv_in16( mmio, FIFO_FREE ) >> 2; +#else + nvdev->fifo_free = nv_in32( mmio, FIFO_FREE ) >> 2; +#endif + if (++waitcycles > WAIT_MAX) { + D_BREAK( "FIFO timed out" ); + /* avoid card crash */ + _exit(-1); + } + } while (nvdev->fifo_free < space); + + nvdev->free_waitcycles += waitcycles; + } else + nvdev->cache_hits++; + + nvdev->fifo_free -= space; +} + +/* + * DMA control + */ + +static inline void +nv_emitdma( NVidiaDriverData *nvdrv, NVidiaDeviceData *nvdev ) +{ + if (nvdev->dma_put != nvdev->dma_cur) { + volatile u8 scratch; + + /* flush MTRR buffers */ + scratch = nv_in8( nvdrv->fb_base, 0 ); + nv_out32( nvdrv->mmio_base, DMA_PUT, nvdev->dma_cur << 2 ); + + nvdev->dma_put = nvdev->dma_cur; + } +} + +static inline void +nv_waitdma( NVidiaDriverData *nvdrv, + NVidiaDeviceData *nvdev, + unsigned int space ) +{ + volatile void *mmio = nvdrv->mmio_base; + volatile void *ring = nvdrv->dma_base; + int waitcycles = 0; + + nvdev->waitfree_sum += (space); + nvdev->waitfree_calls++; + + if (nvdev->dma_free < space) { + do { + nvdev->dma_get = nv_in32( mmio, DMA_GET ) >> 2; + + if (nvdev->dma_put >= nvdev->dma_get) { + nvdev->dma_free = nvdev->dma_max - nvdev->dma_cur; + + if (nvdev->dma_free < space) { + /* rewind ring */ + nv_out32( ring, nvdev->dma_cur << 2, 0x20000000 ); + + if (!nvdev->dma_get) { + if (!nvdev->dma_put) { + nvdev->dma_cur = 1; + nv_emitdma( nvdrv, nvdev ); + } + + do { + nvdev->dma_get = nv_in32( mmio, DMA_GET ) >> 2; + if (++waitcycles > WAIT_MAX) { + D_BREAK( "DMA timed out" ); + /* avoid card crash */ + _exit(-1); + } + } while (!nvdev->dma_get); + } + + nvdev->dma_cur = 0; + nv_emitdma( nvdrv, nvdev ); + + nvdev->dma_free = nvdev->dma_get - 1; + } + } + else { + nvdev->dma_free = nvdev->dma_get - nvdev->dma_cur - 1; + } + + if (++waitcycles > WAIT_MAX) { + D_BREAK( "DMA timed out" ); + /* avoid card crash */ + _exit(-1); + } + } while (nvdev->dma_free < space); + + nvdev->free_waitcycles += waitcycles; + } else + nvdev->cache_hits++; + + nvdev->dma_free -= space; +} + +/* Begin writing into ring/fifo */ +#define nv_begin( subc, start, size ) { \ + if (nvdev->use_dma) { \ + nv_waitdma( nvdrv, nvdev, (size)+1 ); \ + nv_out32( nvdrv->dma_base, nvdev->dma_cur << 2, \ + ((size) << 18) | ((subc)*0x2000 + (start)) ); \ + nvdev->cmd_ptr = nvdrv->dma_base; \ + nvdev->cmd_ptr += nvdev->dma_cur + 1; \ + nvdev->dma_cur += (size) + 1; \ + D_ASSERT( nvdev->dma_cur <= nvdev->dma_max ); \ + } else { \ + nv_waitfifo( nvdrv, nvdev, size ); \ + nvdev->cmd_ptr = (nvdrv->mmio_base + FIFO_ADDRESS + \ + (subc)*0x2000 + (start)); \ + } \ +} + +/* Output to ring/register */ +#define nv_outr( value ) *nvdev->cmd_ptr++ = (value) + + +#endif /* __NVIDIA_ACCEL_H__ */ -- cgit