summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_api.h
blob: 5e06adf21c045624f7603492ea32e64332dc59de (plain) (tree)
























                                                                               












                                                                               




                                       











































































































































































































                                                                                                                          

                           









































































































































































































                                                                                               
#ifndef __BESTCOMM_API_H
#define __BESTCOMM_API_H 1

/******************************************************************************
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
* 
* 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 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
* THE AUTHORS OR COPYRIGHT HOLDERS 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.
*
******************************************************************************/

/*!
 * \file	bestcomm_api.h
 *
 * Bestcomm_api.h is the only header necessary for inclusion by user
 * code. The include path the C compiler searches to find .h files
 * should contain bestcomm/capi and one of bestcomm/code_dma/image_*.
 * This second entry selects which set of BestComm tasks will be used.
 * Of course the appropriate files in image_* must also be compiled and
 * linked.
 */

#include "include/ppctypes.h"
#include "include/mgt5200/sdma.h"
#include "task_api/tasksetup_bdtable.h"
#include "task_api/bestcomm_cntrl.h"
#include "task_api/bestcomm_api_mem.h"

/*!
 * \brief	TaskSetup() debugging
 *
 * Define this macro as follows for debugging printf()s to see
 * what the API receives and sets from the TaskSetupParamSet_t
 * struct. Implemented in capi/task_api/tasksetup_general.h.
 *
 * \verbatim
 * >0  : print basic debug messages
 * >=10: also print C-API interface variables
 * >=20: also print task API interface variables
 * else: do nothing
 * \endverbatim
 */
#define DEBUG_BESTCOMM_API 0

/*!
 * \brief	Maximum number of tasks in the system.
 * This number is hardware-dependent and not user configuration.
 */
#define MAX_TASKS 16

/*
 * This may need to be removed in certain implementations.
 */
#ifndef NULL
# define NULL ((void *)0)
#endif	/* NULL */

typedef sint8 TaskId;
typedef sint32 BDIdx;

/*
 * Special "task IDs" for interrupt handling API functions
 */
/*! \brief	Debug interrupt "task ID" */
#define	DEBUG_INTR_ID	SDMA_INT_BIT_DBG

/*! \brief	TEA interrupt "task ID"	*/
#define TEA_INTR_ID		SDMA_INT_BIT_TEA

/*! \brief	Task start autostart enable */
#define TASK_AUTOSTART_ENABLE	1

/*! \brief	Task start autostart disable */
#define TASK_AUTOSTART_DISABLE	0

/*! \brief	Task start interrupt enable */
#define TASK_INTERRUPT_ENABLE	1

/*! \brief	Task start interrupt disable */
#define TASK_INTERRUPT_DISABLE	0

/*
 * Buffer descriptor flags to pass to TaskBDAssign().
 */
/*! \brief	Transmit frame done */
#define TASK_BD_TFD	(1 << SDMA_DRD_BIT_TFD)

/*! \brief	Interrupt on frame done	*/
#define TASK_BD_INT	(1 << SDMA_DRD_BIT_INT)

/*!
 * \brief	Data transfer size
 */
typedef enum {
	SZ_FLEX		= 3,	/*!< invalid for TaskSetupParamSet_t */
	SZ_UINT8	= 1,	/*!< 1-byte	*/
	SZ_UINT16	= 2,	/*!< 2-byte	*/
	SZ_UINT32	= 4		/*!< 4-byte	*/
} Sz_t;

/*!
 * \brief	API error codes
 */
typedef enum {
	TASK_ERR_NO_ERR			= -1,	/*!< No error					*/
	TASK_ERR_NO_INTR		= TASK_ERR_NO_ERR,
									/*!< No interrupt				*/
	TASK_ERR_INVALID_ARG	= -2,	/*!< Invalid function argument	*/
	TASK_ERR_BD_RING_FULL	= -3,	/*!< Buffer descriptor ring full*/
	TASK_ERR_API_ALREADY_INITIALIZED
							= -4,	/*!< API has already been initialized */
	TASK_ERR_SIZE_TOO_LARGE = -5,	/*!< Buffer descriptor cannot support size parameter */
	TASK_ERR_BD_RING_EMPTY	= -6,	/*!< Buffer descriptor ring is empty*/
	TASK_ERR_BD_BUSY		= -7,	/*!< The buffer descriptor is in use
										 by the BestComm			*/
	TASK_ERR_TASK_RUNNING	= -8	/*!< The task is running.		*/

} TaskErr_t;

/*!
 * \brief	BestComm initiators
 *
 * These are assigned by TaskSetup().
 */
typedef enum {

	INITIATOR_ALWAYS	=  0,
	INITIATOR_SCTMR_0	=  1,
	INITIATOR_SCTMR_1	=  2,
	INITIATOR_FEC_RX	=  3,
	INITIATOR_FEC_TX	=  4,
	INITIATOR_ATA_RX	=  5,
	INITIATOR_ATA_TX	=  6,
	INITIATOR_SCPCI_RX	=  7,
	INITIATOR_SCPCI_TX	=  8,
	INITIATOR_PSC3_RX	=  9,
	INITIATOR_PSC3_TX	= 10,
	INITIATOR_PSC2_RX	= 11,
	INITIATOR_PSC2_TX	= 12,
	INITIATOR_PSC1_RX	= 13,
	INITIATOR_PSC1_TX	= 14,
	INITIATOR_SCTMR_2	= 15,

	INITIATOR_SCLPC		= 16,
	INITIATOR_PSC5_RX	= 17,
	INITIATOR_PSC5_TX	= 18,
	INITIATOR_PSC4_RX	= 19,
	INITIATOR_PSC4_TX	= 20,
	INITIATOR_I2C2_RX	= 21,
	INITIATOR_I2C2_TX	= 22,
	INITIATOR_I2C1_RX	= 23,
	INITIATOR_I2C1_TX	= 24,
	INITIATOR_PSC6_RX	= 25,
	INITIATOR_PSC6_TX	= 26,
	INITIATOR_IRDA_RX	= 25,
	INITIATOR_IRDA_TX	= 26,
	INITIATOR_SCTMR_3	= 27,
	INITIATOR_SCTMR_4	= 28,
	INITIATOR_SCTMR_5	= 29,
	INITIATOR_SCTMR_6	= 30,
	INITIATOR_SCTMR_7	= 31

} MPC5200Initiator_t;

/*!
 * \brief	Parameters for TaskSetup()
 *
 * All parameters can be hard-coded by the task API. Hard-coded values
 * will be changed in the struct passed to TaskSetup() for the user to
 * examine later.
 */
typedef struct {
	uint32	NumBD;			/*!< Number of buffer descriptors				*/

	union {
	   uint32 MaxBuf;		/*!< Maximum buffer size						*/
	   uint32 NumBytes;		/*!< Number of bytes to transfer				*/
	} Size;					/*!< Buffer size union for BD and non-BD tasks	*/

	MPC5200Initiator_t
			Initiator;		/*!< BestComm initiator (ignored if hard-wired)	*/
	uint32	StartAddrSrc;	/*!< Address of the DMA source (e.g. a FIFO)	*/
	sint16	IncrSrc;		/*!< Amount to increment source pointer			*/
	Sz_t	SzSrc;			/*!< Size of source data access					*/
	uint32	StartAddrDst;	/*!< Address of the DMA destination (e.g. a FIFO) */
	sint16	IncrDst;		/*!< Amount to increment data pointer			*/
	Sz_t	SzDst;			/*!< Size of destination data access			*/
} TaskSetupParamSet_t;

/*!
 * \brief	Parameters for TaskDebug()
 *
 * TaskDebug() and the contents of this data structure are yet to be
 * determined.
 */
typedef struct {
	int dummy;				/* Some compilers don't like empty struct typedefs */
} TaskDebugParamSet_t;

/*!
 * \brief	Generic buffer descriptor.
 *
 * It is generally used as a pointer which should be cast to one of the
 * other BD types based on the number of buffers per descriptor.
 */
typedef struct {
	uint32 Status;			/*!< Status and length bits		*/
} TaskBD_t;

/*!
 * \brief	Single buffer descriptor.
 */
typedef struct {
	uint32 Status;			/*!< Status and length bits		*/
	uint32 DataPtr[1];		/*!< Pointer to data buffer		*/
} TaskBD1_t;

/*!
 * \brief	Dual buffer descriptor.
 */
typedef struct {
	uint32 Status;			/*!< Status and length bits		*/
	uint32 DataPtr[2];		/*!< Pointer to data buffers	*/
} TaskBD2_t;



/***************************
 * Start of API Prototypes
 ***************************/

#include "bestcomm_priv.h"
#include "dma_image.capi.h"
  
/*!
 * \brief	Initialize a single task.
 * \param	TaskName	Type of task to initialize. E.g. PCI transmit,
 *						ethernet receive, general purpose dual-pointer.
 *						Values expected can be found in the TaskName_t
 *						enum defined in dma_image.capi.h.
 * \param	TaskSetupParams	Task-specific parameters. The user must fill out
 *						the pertinent parts of a TaskSetupParamSet_t
 *						data structure.
 * \returns TaskId task identification token which is a required
 *			parameter for most other API functions.
 *
 * This function returns a task identification token which is a required
 * parameter for most other API functions.
 *
 * Certain values of the structure pointed to by TaskParams are set
 * as a side-effect based on task type. These may be examined after
 * a successful call to TaskSetup(). User-specified values may be
 * overridden.
 *
 * TaskId TaskSetup( TaskName_t TaskName,
 *                   TaskSetupParamSet_t *TaskSetupParams );
 */
#define			TaskSetup(TaskName, TaskSetupParams)	\
				TaskSetup_ ## TaskName (TaskName ## _api, TaskSetupParams)

const char		*TaskVersion(void);

int				TasksInitAPI(uint8 *MBarRef);

int				TasksInitAPI_VM(uint8 *MBarRef, uint8 *MBarPhys);

void			TasksLoadImage(sdma_regs *sdma);
int				TasksAttachImage(sdma_regs *sdma);

uint32			TasksGetSramOffset(void);
void			TasksSetSramOffset(uint32 sram_offset);

int				TaskStart(TaskId taskId, uint32 autoStartEnable,
						  TaskId autoStartTask, uint32 intrEnable);
int				TaskStop(TaskId taskId);
static int		TaskStatus(TaskId taskId);
BDIdx			TaskBDAssign(TaskId taskId, void *buffer0, void *buffer1,
							 int size, uint32 bdFlags);
BDIdx			TaskBDRelease(TaskId taskId);
BDIdx			TaskBDReset(TaskId taskId);
static TaskBD_t	*TaskGetBD(TaskId taskId, BDIdx bd);
static TaskBD_t	*TaskGetBDRing(TaskId taskId);
int				TaskDebug(TaskId taskId, TaskDebugParamSet_t *paramSet);
static int		TaskIntClear(TaskId taskId);
static TaskId	TaskIntStatus(TaskId taskId);
static int		TaskIntPending(TaskId taskId);
static TaskId	TaskIntSource(void);
static uint16	TaskBDInUse(TaskId taskId);


/*!
 * \brief	Get the enable/disable status of a task.
 * \param	taskId	Task handle passed back from a successful TaskSetup()
 * \returns	Boolean true indicates enabled or false indicates disabled
 *			or invalid taskId.
 */
static inline int TaskStatus(TaskId taskId)
{
	return SDMA_TASK_STATUS(SDMA_TCR, taskId) & 0x8000;
}

/*!
 * \brief	Return a pointer to a buffer descriptor at index BDIdx
 * \param	taskId	Task handle passed back from a successful TaskSetup()
 * \param	bd		Buffer descriptor handle returned by
 *					TaskBDAssign() or TaskBDRelease().
 * \returns	Pointer to the requested buffer descriptor or NULL on error.
 *
 * The returned pointer should be cast to the appropriate buffer
 * descriptor type, TaskBD1_t or TaskBD2_t.
 */
static inline TaskBD_t *TaskGetBD(TaskId taskId, BDIdx bd)
{
	TaskBD_t *bdTab;

	bdTab = TaskBDIdxTable[taskId].BDTablePtr;
	if (TaskBDIdxTable[taskId].numPtr == 1) {
		return (TaskBD_t *)&(((TaskBD1_t *)bdTab)[bd]);
	} else {
		return (TaskBD_t *)&(((TaskBD2_t *)bdTab)[bd]);
	}
}

/*!
 * \brief	Return a pointer to the first buffer descriptor in the ring.
 * \param	taskId	Task handle passed back from a successful TaskSetup()
 * \returns	Pointer to the array of buffer descriptors making up the
 *			ring or NULL on error.
 *
 * A device driver author may choose to use this in lieu of
 * TaskBDAssign()/TaskBDRelease() to get direct access to the
 * BD ring with the warning that the underlying data structure may change.
 * Use at one's own discretion.
 */
static inline TaskBD_t *TaskGetBDRing(TaskId taskId)
{
	return TaskBDIdxTable[taskId].BDTablePtr;
}

/*!
 * \brief	Clear the interrupt for a given BestComm task.
 * \param	taskId	Task handle passed back from a successful TaskSetup()
 * \returns	TASK_ERR_NO_ERR (which is not really an error) for success
 */
static inline int TaskIntClear(TaskId taskId)
{
	SDMA_CLEAR_IEVENT(SDMA_INT_PEND, taskId);
	return TASK_ERR_NO_ERR;	/* success */
}

/*!
 * \brief	Get the interrupt status for a given task.
 * \param	taskId	Task handle passed back from a successful TaskSetup()
 * \returns	TASK_ERR_NO_INTR (which is not really an error) for no interrupt
 *			pending, taskId for a regular interrupt, DEBUG_INTR_ID for
 *			a debug interrupt and TEA_INTR_ID for a TEA interrupt.
 *			\b Note: TaskIntStatus() may return 0, but this means that that
 *			taskId 0 is interrupt pending.
 */
static inline TaskId TaskIntStatus(TaskId taskId)
{
	uint32 pending;

	pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK);

	if (SDMA_INT_TEST(pending, taskId)) {
		return taskId;
	} else if (SDMA_INT_TEST(pending, DEBUG_INTR_ID)) {
		return DEBUG_INTR_ID;
	} else if (SDMA_INT_TEST(pending, TEA_INTR_ID)) {
		return TEA_INTR_ID;
	}

	return TASK_ERR_NO_INTR;
}

/*!
 * \brief	Get the interrupt pending status for a given task.
 * \param	taskId	Task handle passed back from a successful TaskSetup()
 * \returns	0 if task does not have a pending interrupt. 1 if the task
 *			has an interrupt pending.
 */
static inline int TaskIntPending(TaskId taskId)
{
	uint32 pending;

	pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK);
	if (SDMA_INT_TEST(pending, taskId)) {
		return 1;
	} else {
		return 0;
	}
}

/*!
 * \brief	Returns the task ID of an interrupting BestComm task.
 * \returns	TASK_ERR_NO_INTR (which is not really an error) for no interrupt
 *			pending or the taskId of the interrupting task.
 *
 * The user must query TaskIntStatus() to discover if this is a debug
 * or TEA interrupt. This function is designed for use by an operating
 * system interrupt handler.
 */
static inline TaskId TaskIntSource(void)
{
	uint32 pending;
	uint32 mask = 1 << (MAX_TASKS - 1);
	TaskId i;

	pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK);

	if (SDMA_INT_TEST(pending, SDMA_INT_BIT_TEA)) {
		return (TaskId)SDMA_TEA_SOURCE(SDMA_INT_PEND);
	}

	for (i = (MAX_TASKS - 1); i >= 0; --i, mask >>= 1) {
		if (pending & mask) {
			return i;
		}
	}

	return TASK_ERR_NO_INTR;
}

/*!
 * \brief	Get a count of in-use buffer descriptors.
 * \param	taskId	Task handle passed back from a successful TaskSetup()
 * \returns	Count of the current number of BDs in use by the given task.
 */
static inline uint16 TaskBDInUse(TaskId taskId)
{
	return TaskBDIdxTable[taskId].currBDInUse;
}

#endif	/* __BESTCOMM_API_H */