This repository has been archived on 2025-06-06. You can view files and clone it, but cannot push or open issues or pull requests.
Files
android-g900/Start_WM/test6/inc/GFRmRDMA.h
2010-10-16 00:02:07 +06:00

412 lines
13 KiB
C
Executable File

/* Copyright (c) 2006 NVIDIA Corporation. All rights reserved.
*
* NVIDIA Corporation and its licensors retain all intellectual property
* and proprietary rights in and to this software, related documentation
* and any modifications thereto. Any use, reproduction, disclosure or
* distribution of this software and related documentation without an
* express license agreement from NVIDIA Corporation is strictly prohibited.
*/
/** @File: GFRmRDMA.h
GFSDK Read DMA memmory manager.
*/
#ifndef __GFRMRDMA_H__
#define __GFRMRDMA_H__
#include "GF.h"
/** @addtogroup groupRDMA RDMA ReadDMA API
<ul>
<li> @ref pageRDMAAppNotes
</ul>
*/
/*@{*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/** eGFRmRDMAClientID: Enumeration of client id's. SC15 has 4
RDMA (Read DMA) FIFO's. Modules specified below can be
attached to the RDMA FIFO's. See @
*/
typedef enum
{
RDMA_CLID_CPU = 0,
RDMA_CLID_DSP,
RDMA_CLID_I2S,
RDMA_CLID_SD,
RDMA_CLID_MPEGE,
RDMA_CLID_JPEGE,
RDMA_CLID_EPP,
RDMA_CLID_VI,
RDMA_CLIDS
} eGFRmRDMAClientID;
/** RDMA buffer header.
For non-rectangular (or linear) reads
RDMA expects a header in the memory. The header formart is as specified
below. GFRmRDMAReadHeader function returns the header in this format.
@See GFRmRDMAReadHeader()
*/
typedef struct _RDMA_BUF_HEADER
{
NvU32 bufferSize;
NvU32 raiseVector;
NvU32 channel;
NvU8 raiseEnable;
NvU8 frameStart;
NvU8 frameEnd;
NvU8 largeHdr;
NvU32 extHeader;
} RDMA_BUFFER_HEADER, *pRDMA_BUFFER_HEADER;
/* RDMA flags */
/** RDMA_NONRECT::flags and RDMA_RECT::flags flagbit:
No byte swap.
*/
#define GF_RDMA_FLAGS_SWAP_NONE 0x00000000
/** RDMA_NONRECT::flags and RDMA_RECT::flags flagbit:
Swap bytes in a word. example: 0xaabbccdd to 0xbbaaddcc.
*/
#define GF_RDMA_FLAGS_SWAP_BYTE_IN_WORD 0x00000001
/** RDMA_NONRECT::flags and RDMA_RECT::flags flagbit:
Swap bytes in dword: 0xaabbccdd to 0xddccbbaa.
*/
#define GF_RDMA_FLAGS_SWAP_BYTE_IN_DWORD 0x00000002
/** RDMA_NONRECT::flags and RDMA_RECT::flags flagbit:
Swap word in dword example: 0xaabbccdd to 0xccddaabb.
*/
#define GF_RDMA_FLAGS_SWAP_WORD_IN_DWORD 0x00000003
/** RDMA_NONRECT::flags and RDMA_RECT::flags bitmask:
mask out byte swap options GF_RDMA_FLAGS_SWAP_*.
*/
#define GF_RDMA_FLAGS_SWAP_MASK 0x00000003
/** RDMA_NONRECT::flags and RDMA_RECT::flags flagbit:
Tells the RDMA engine to output header. Will output a header into the data stream,
which has to be read with GFRmRDMAReadHeader() before calling GFRmRDMARead().
This flag is relevant only in non-rectangular reads.
*/
#define GF_RDMA_FLAGS_STR_HEADER 0x00010000
/** RDMA_RECT
Setup information for the RDMA.
*/
typedef struct _RDMA_RECT
{
/** physical addess of the buffer in the SC15 Memory view. 32-bit alignment
* required. */
NvU32 baseOffset;
/** client id. See @eGFRmRDMAClientID */
eGFRmRDMAClientID clid;
/** buffers/stride/width/lines of the rectangular buffer.
Need to comply with the following constraints provided
by the hardware
- if width is not a multiple of 4 bytes (one word):
- stride equals width, stride should be the exact stride in bytes (eg. line_stride[1:0] not equal to 0)
- if stride is bigger than width, stride should be rounded down to the nearest word
(eg. line_stride[1:0] should be zero)
For example: width = 42 bytes, stride = 82 -> stride should be programmed to 80
width = 42 bytes, stride = 42 -> stride should be programmed to 42
*/
NvU32 buffers;
NvU32 stride;
NvU32 width;
NvU32 lines;
/* use the RDMA flags defined above as GF_RDMS_FLAGS_* */
NvU32 flags; //!< Flagbits, see GF_RDMA_FLAGS_*
/* Timeout in msec. If <=0, then no timeout */
NvU32 timeout;
} RDMA_RECT, *pRDMA_RECT;
/** RDMA_NONRECT
Setup structure for non-rectangular reads.
*/
typedef struct _RDMA_NONRECT
{
/** Physical addess of the buffer in the GPU address space. Needs to be
* 32-bit aligned. */
NvU32 baseOffset;
/** client id. See @eGFRmRDMAClientID */
eGFRmRDMAClientID clid;
NvU32 buffers;
NvU32 stride;
/* use the RDMA flags defined above as GF_RDMS_FLAGS_* */
NvU32 flags; //!< Flagbits, see GF_RDMA_FLAGS_*
/* Timeout in msec. If =0, then no timeout */
NvU32 timeout;
} RDMA_NONRECT, *pRDMA_NONRECT;
/** There are four read dma channels, the RM manages the allocation/
freeing of these channels. This function allocates a channel.
@param RmHandle Handle to the Rm allocated via call to GFRmOpen.
@param DmaHandle Pointer to an allocated handle.
@retval GF_SUCCESS if a RDMA channel is available, and returns
RDMA handle on allocation.
The release function will return GF_ERROR
if the read dma is already released.
*/
GF_RETTYPE
GFRmRDMAAlloc(GFRmHandle RmHandle, GFRmRdmaHandle *DmaHandle);
/** There are four read dma channels, the RM manages the allocation/
freeing of these channels. This function frees an allocated
channel.
@param hRm Handle to the Rm allocated via call to GFRmOpen.
@param phDma Pointer to the DMA handle to be released.
*/
void
GFRmRDMARelease(GFRmHandle hRm, GFRmRdmaHandle *phDma);
/** Setup non-rectangular RDMA.
When the flag GF_RDMA_FLAGS_STR_HEADER is set, buffer header is written to the
memory by the RDMA client. So, when the cpu reads the data, buffer
header comes first and then the data. Buffer header has the information
of buffer, like its size etc.
So, an example sequence would be
- Call setup with GF_RDMA_FLAGS_STR_HEADER flag set.
- Read header with the GFRmRDMAReadHeader(...)
- Read buffer size of data with GFRmRDMARead() funtion.
Buffer size is in the buffer header.
If this flag is not set, then the there is no buffer header.
In this case it is assumed that the the size of the buffer is prefixed
and known to the module API writers.
So, an example sequence would be
- Call setup GF_RDMA_FLAGS_STR_HEADER flag not set.
- Read buffer size of data with GFRmRDMARead() funtion.
Buffer size is known to the callers.
baseOffset of pReq structure needs to be 32-bit aligned.
@param DmaHandle Handle returned by @GFRmRDMAAlloc function.
@param pReq Populated RDMA req structure. See @RDMA_NONRECT
*/
GF_RETTYPE
GFRmRDMASetupNONRect(GFRmRdmaHandle DmaHandle, pRDMA_NONRECT pReq);
/** Setup RDMA for rectangular read.
Requirement:
baseOffset of pReq structure needs to be 32-bit aligned.
@param DmaHandle Handle returned by @GFRmRDMAAlloc function.
@param pReq Populated RDMA req structure. See @RDMA_RECT
*/
GF_RETTYPE
GFRmRDMASetupRect(GFRmRdmaHandle DmaHandle, pRDMA_RECT pReq);
/** Reads the RDMA FIFO status register and returns the
available number of FIFO slots. A slot is 32-bit.
@param DmaHandle Handle returned by @GFRmRDMAAlloc function.
*/
NvU32 GFRmRDMAFIFOAvailIn32Bits(GFRmRdmaHandle DmaHandle);
/** Reads memory from SC15 internal/external
memory to the system memory pointed by the dstAddr. Need
to pass the same rectangular attributes passed, when the
RDMA is setup.
@param DmaHandle Handle returned by @GFRmRDMAAlloc function.
@param dstAddr aligned or non-aligned dest pointer. Aligned
pointer results in faster reads.
@param width Width in bytes to read.
@param height Height of the rectangular region.
@retval Returns GF_SUCCESS or GF_ERROR.
*/
GF_RETTYPE
GFRmRDMARectRead(GFRmRdmaHandle DmaHandle, void *dstAddr, NvU32 width, NvU32 height);
/** Reads memory from SC15 internal/external
memory to the system memory pointed by the dstAddr.
@param DmaHandle Handle returned by @GFRmRDMAAlloc function.
@param dstAddr aligned or non-aligned dest pointer. Aligned
pointer results in faster reads.
@param sizeInBytes Number of bytes to read.
@retval Returns GF_SUCCESS or GF_ERROR.
*/
GF_RETTYPE
GFRmRDMARead(GFRmRdmaHandle DmaHandle, void *dstAddr, NvU32 sizeInBytes);
/** Reads buffer header. Once this info is read
API's will know how much data to read or expect.
@param DmaHandle Handle returned by @GFRmRDMAAlloc function.
@param header Pointer to RDMA header structure. See @RDMA_BUFFER_HEADER
*/
GF_RETTYPE
GFRmRDMAReadHeader(GFRmRdmaHandle DmaHandle, pRDMA_BUFFER_HEADER header);
/** Cleanup the RDMA FIFO, by reading out any extra DOWRDS
GFRmRDMARead might not have read.
In general this function need not be used.
*/
GF_RETTYPE
GFRmRDMACleanup(GFRmRdmaHandle DmaHandle);
/** Gets the actual RDMA channel number from the DMA handle. This is
usefull for DSP development. Host code allocates the DMAHandle
gets the DMA number from that and creates the DMA handle on the
DSP side using GFXRmRDMAAlloc function. GFXRmRDMAAlloc needs to
know what DMA channel to use.
@param DmaHandle RDMA handle.
@param dmaNumber RDMA channel number used the handle.
*/
void
GFRmRDMAGetPortNumber(GFRmRdmaHandle DmaHandle, NvU32 *portNumber);
#if NVCPU_IS_XTENSA
// In XRM, it is expected that the dma handle is allocated on
// the Host side, and just the dma number is passed into code
// running on the Xtensa. These functions will setup a
// DMA handle that can used in the XRM.
GF_RETTYPE
GFXRmRDMAAlloc(NvU32 dmaNumber, GFRmRdmaHandle *DmaHandle);
GF_RETTYPE
GFXRmRDMARelease(GFRmRdmaHandle *DmaHandle);
#endif // NVCPU_IS_XTENSA
#ifdef __cplusplus
}
#endif /* __cplusplus */
/*@}*/
/** @page pageRDMAAppNotes RDMA Application Notes
General information about RDMA - RDMA is read DMA hw block. Unlike
traditional DMA, sw reads the data from the FIFO to system memory. This is
becasuse SC15 cannot bus master and write directly to the system memory.
RDMA will be faster becasue the data is buffered by the HOST1x Block and sw
reads back data in a tight loop.
SC15 RDMA supports 2 modes - Linear(AKA NON-Rect) and Rect mode.
In both modes the sequence of programming same - setup and then read the data.
RDMA setup is 2 step process.
- RDMA need to know which client will trigger the RDMA. It also need to other
parameters like which varies for linear and RECT modes.
In rect reads software has to setup the stride/width/number of lines.
This information is needed to describe a buffer. In case of non-rect
read a buffer header is expected, which describes the buffer. In both
cases one need to specify the number of buffers.
- Client module also need to be setup, as it notifies the RDMA hw block when
the data is ready. This step is not needed for CPU triggered case, as the
data is already available in the memory.
Sample program sequence:
Setup RDMA
Setup Client side register (example - vi, SD etc...). Not needed when
setup for CLID CPU.
wait till the data is available ()
{
Read the data(..)
}
Amount of data to read is either known a-priori (RECT mode) or read from
the header (linear mode).
As described ealier RDMA supports 2 modes
Linear RDMA - RDMA expects a header in the memory right before the data, when
it is triggered. That header describes the length and the attributes of the
buffer.
Depending on how the RDMA is setup, buffer header will be/will not be
(i.e RDMA_BUFFER_HEADER struct) readout. see #GF_RDMA_FLAGS_STR_HEADER
When the header is returned the usage looks like
RDMA_BUFFER_HEADER header;
GFRmRDMAReadHeader(...,&header);
While (header->bufferSize)
{
...
GFRmReadRDMA(...)
}
In this mode, it is important is to note that RDMA expect the buffer header
in the memory. So, this is not good for CPU triggerd case, as in that case
CPU should somehow write the buffer header to read the data already present
in the embedded memory.
Rect RDMA - In this mode, there is no concept of buffer header. Exact size
should be programmed in the RDMA registers when the Setup is done. So, sw
should know how much data to pull out. Requests for data more than available
will result in timeout errors.
A guideline: if an engine already generated the buffer for you, then use
non-rectangular read. Otherwise, use rect read.
*/
#endif /* __GFRMRDMA_H__ */