/* **********************************************************************
 * *                                                                    *
 * *       Open Radar Data Acquisition System Global Definitions        *
 * *                                                                    *
 * **********************************************************************
 * File: include/rda.h
 *
 *                   COPYRIGHT (c) 2001, 2002  BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#ifndef SIGMET_RDA_H
#define SIGMET_RDA_H 1

/* *****************************
 * *                           *
 * * Kernel Module Definitions *
 * *                           *
 * *****************************
 */

/* Minor numbers are allocated dynamically each time the RDA kernel
 * module is installed.  This makes it possible to express all of the
 * functions of a complex RDA backplane in a single 8-bit minor
 * number, i.e., by simply selecting the board (5-bits) and sub
 * function (3-bits).  A few special minor numbers are also assigned
 * at the high end.
 */
#define RDA_MINOR_BRD( MINOR ) (((MINOR) >> 3) & 0x1F)
#define RDA_MINOR_LUN( MINOR ) (((MINOR)     ) & 0x07)
#define RDA_MINOR( BRD, LUN ) ((((BRD) & 0x1F) << 3) | ((LUN) & 0x07))

#define RDA_MINOR_RVPPROC_W 250	/* Minor numbers for each side of the */
#define RDA_MINOR_RVPPROC_B 251	/*   signal processor I/O interface. */
#define RDA_MINOR_RVPUSER_W 252
#define RDA_MINOR_RVPUSER_B 253

/* Other parameters that span the entire RDA subsystem
 */
#define RDA_MAJOR_NUMBER     0	/* Dynamic major number by default */
#define RDA_MAX_BOARDS      14	/* Max number of RDA boards */
#define RDA_MAX_OPENS       40	/* Max opens for total set of boards */

#define RDA_DRIVER_NAME   "rda"	/* Registered name of the char driver */

#define RDA_NUM_PCI_BARS 6	/* Max number of address spaces per board */

#define RDALED_DFLT      0	/* Externally visible convention for */
#define RDALED_OFF       1	/*   assigning LED states. */
#define RDALED_ON        2

#define RTPRI_LOW       10	/* Conventions for realtime priorities */
#define RTPRI_NORM      11	/*   among all RDA user level processes. */
#define RTPRI_HIGH      12

/* PCI Configuration Space definitions for SIGMET boards
 */
#define PCI_VENDOR_ID_SIGMET  0x1172 /* We actually use Altera's ID */

#define PCI_BOARD_ID_RVP8RX   0x7805 /* RVP8/Rx IF Receiver Board */
#define PCI_BOARD_ID_RVP8TX   0x7806 /* RVP8/Rx IF Transmitter Board */
#define PCI_BOARD_ID_IO62     0x7807 /* RVP/RCP 62-pin I/O Board */

/* DMA definitions for PLDA PCI core and IOCTL calls
 */
#define RDA_DMA_SIZE (32 * 4096)
#define RDA_DMATAR_ADDR  0x48	/* Target address register (config space) */
#define RDA_DMADCR_ADDR  0x4C	/* DMA control register (config space) */
#define DMADCR_SIZE         8	/*   Starting bit of 24-bit transfer size */
#define DMADCR_CMD          4	/*   Starting bit of 4-bit command */
#define DMADCR_CONTINUE     3	/*   Continue mode (TAR incremented) */
#define DMADCR_64BIT        2	/*   64-bit data transfer */
#define DMADCR_DONE         1	/*   DMA transfer is done */
#define DMADCR_REQ          0	/*   DMA transfer request */

struct rda_dmastart {		/* Structure passed to RDAIOC_DMASTART */
  unsigned int iDWords ;	/*   Transfer length in DWords */
  unsigned int iDMAOffset ;	/*   Offset (DWords) in DMA transfer buffer */
  int lReadFromCPU ;		/*   PCI <== CPU if set, else PCI ==> CPU */
} ;

struct rda_cacheinfo {		/* Cache parameters for this CPU */
  int iL1Bytes ;		/*   Size of L1 cache in bytes */
} ;

/* Address in BAR0 space, and magic number to cause a reset on all
 * types of RDA boards.
 */
#define RDA_RESET_ADDR   0x00	/* Fixed reset address within BAR0 space */
#define RDA_RESET_DATA   0xB9	/* Writing this data causes a board reset */

/* The ISR Interrupt Service Register is used for interrupt control.
 * This register is located at a fixed address in BAR0, and has fixed
 * bit definitions for all boards.  Each interruptible "unit" ocupies
 * two bits in the ISR; unit #0 uses bits <1,0>, unit #1 uses bits
 * <3,2>, etc.  The Read/Write functions are overlapped to maximize
 * the number of possible units.
 *
 * Note that the ISR used to be implemented as a configuration space
 * register, but a persistent bug in the 2.4.18+ SMP kernels led to
 * instability when PCI config space was repeatedly accessed.
 */
#define RDA_ISR_ADDR     0x01	/* Fixed ISR address within BAR0 space */
#define RDA_MAX_INT_UNITS  15	/* Maximum number of interrupting units */

#define RDA_ISR_INTPEND_R   0	/* Interrupt is pending from unit #0 */
#define RDA_ISR_INTDIS_W    0	/* Interrupts enabled/disabled on unit #0 */
#define RDA_ISR_INTENA_RW   1	/*   (these are separate set/clr bits) */

#define RDA_ISR_INTREQ_R   31	/* Global interrupt being requested */
#define RDA_ISR_INTRESET_W 31	/* Reset the global interrupt request */

#define RDA_ALL_INTS_MASK 0x15555555 /* All possible interruptable devices */
#if ( RDA_MAX_INT_UNITS != 15 )
#error Please manually maintain definition of RDA_ALL_INTS_MASK
#endif

/* The PCI configuration space also holds the following information
 * within its "user" area.  These assignments are the same for all RDA
 * boards.
 */
#define RDA_SERIALNUM_ADDR  0x80 /* Board serial number */
#define RDA_BOARDREV_ADDR   0x84 /* Board revision number */
#define RDA_CODEREV_ADDR    0x88 /* FPGA code revision number */
#define RDA_PATCHBOOT_ADDR  0x8C /* Board patch level / boot module rev */

#define RDA_CHIPBITS_ADDR   0x90 /* Sampled bits from the BOOT chip */
  #define RDA_B2F_JUMP1      0	 /*   Config jumpers [2,1] */
  #define RDA_B2F_JUMP2      1
  #define RDA_B2F_PAGE0      2	 /*   Page select [2,1,0] */
  #define RDA_B2F_PAGE1      3
  #define RDA_B2F_PAGE2      4
  #define RDA_B2F_LED        5	 /*   LED State */
  #define RDA_B2F_INIT_DONE  6	 /*   Altera config signals */
  #define RDA_B2F_CONF_DONE  7
  #define RDA_B2F_NINIT_CONF 8
  #define RDA_B2F_NCONFIG    9
  #define RDA_B2F_NSTATUS   10

#define RDA_BOOTCMD_ADDR    0x94 /* Command bits sent to the BOOT chip */
  #define RDA_F2B_PAGE0    0	 /*   Page select [2,1,0] */
  #define RDA_F2B_PAGE1    1
  #define RDA_F2B_PAGE2    2
  #define RDA_F2B_LEDOFF   3	 /*   Force LED state */
  #define RDA_F2B_LEDON    4
  #define RDA_F2B_RECONFIG 5	 /*   Begin FPGA reconfiguration */

#define RDA_JTAG_ADDR       0x98 /* JTAG control lines */
  #define RDA_JTAG_TCK     0	 /*   JTAG TCK line \  These are all */
  #define RDA_JTAG_TMS     1	 /*   JTAG TMS line  >   outputs to */
  #define RDA_JTAG_TDI     2	 /*   JTAG TDI line /  external chips */
  #define RDA_JTAG_TDO     3	 /*   JTAG TDO line (input from chip) */
  #define RDA_JTAG_CHAIN0  4	 /*   Selection of which on-board JTAG */
  #define RDA_JTAG_CHAIN1  5	 /*     chain we wish to use. */
  #define RDA_JTAG_ENABLE  6	 /*   Enable PCI control of JTAG lines */
  #define RDA_JTAG_WAIT    7	 /*   Must wait for valid levels */
  #define RDA_JTAG_SLOW    8	 /*   Slow chain, must check WAIT */

struct rda_boardinfo {
  int iSerialNum, iBoardRev ;	/* Info read back from "user" area */
  int iCodeRev  , iPatchLev  ;	/*   of PCI config space. */
  int iBootMod  , iChipBits ;
  int iOpenCount ;		/* Number of opens currently on this board */
  int iBoardID ;		/* Board identifier PCI_BOARD_ID... */
  char sName[20] ;		/* Name+Unit of this board, e.g., "rvp8rx-0" */
  int iUnit ;			/* Unit number of this type of board */
} ;
#define RDA_REV_LETTER( REV ) ( "?ABCDEFGHIJ?"[ MAX(0, MIN(11, (REV)) ) ] )

/* Entries created in the /proc and /dev filesystems
 */
#define RDA_PROC_TOPDIR       "driver/" RDA_DRIVER_NAME
#define RDA_PROC_TOPPATH      "/proc/" RDA_PROC_TOPDIR
#define RDA_PROC_NODEINFO     "nodeinfo"
#define RDA_PROC_CONFIGSPACE  "configspace"
#define RDA_PROC_BOARDLOG     "boardlog"
#define RDA_PROC_RECONFIG     "reconfig"
#define RDA_PROC_VERSION      "version"

#define RDA_DEV_TOPPATH       "/dev/" RDA_DRIVER_NAME
#define RDA_DEV_RVPPROC_W     "rvp-proc"
#define RDA_DEV_RVPPROC_B     "rvp-proc-byte"
#define RDA_DEV_RVPUSER_W     "rvp-user"
#define RDA_DEV_RVPUSER_B     "rvp-user-byte"

#define RDA_VERSION_FORMAT "SIGMET RDA kernel module V%d.%d"

/* RVP I/O kernel module definitions.  These parameters are used by
 * the FIFO interfaces between the processor code and the user code.
 */
#define RVPIO_TIMEOUTMS      4000 /* Default read timeout (miliseconds) */
#define RVPIO_TIMEOUTMS_MAX 20000 /* Maximum selectable value */

#define RVPIO_P2U_SIZE  16000	/* Proc->User buffer size (bytes) */
#define RVPIO_U2P_SIZE   4000	/* User->Proc buffer size (bytes) */

struct rvpio_ffinfo {		/* State of the Proc<->User FIFOs */
  int iSize ;			/*   Size of the FIFO */
  int iUsed, iFree ;		/*   Used and Free counts */
  int wrCount, rdCount ;	/*   Read and write I/O counters */
  unsigned long iTimeoutMS ;	/*   Read TimeOut in milliseconds */
} ;
struct rvpio_status {		/* Status of the Proc<->User interface */
  int iLocalOpens ;		/*   Number of opens that are active on */
  int iRemoteOpens ;		/*     the local and remote sides. */
  struct rvpio_ffinfo wrFIFO ;	/*  Condition of our write FIFO */
  struct rvpio_ffinfo rdFIFO ;	/*  Condition of our read FIFO */
} ;

/* Kernel implementation of generic serial encoder/decoder
 */
struct intActionArgsTTY {	/* Interrupt action arguments for TTY handler */
  int lEnabled ;		/*   Interface is enabled */
  int iCSR, iData ;		/*   CSR/Data addresses for ioserial controller */
  int iIntUnit ;		/*   Interrupt bit within board's ISR */
  int iBaud ;			/*   Baud rate of the interface */
  int iParity ;			/*   One of TTYPARITY_XXX */
  int iProtocol ;		/*   Serial protocol, one of TTYPROTO_XXX */
  int lWriteOnly ;		/*   Do not implement serial Rx functions */
  int iChunkIO ;		/*   Number of Tx/Rx octets per interrupt */
  int iRxFlush ;		/*   Flush this many Rx words on startup */
} ;
#define IOSERR_PARITY   0x8000	/* Rx parity error */
#define IOSERR_FRAME    0x4000	/* Rx framing error */

/* IOCTL opcode/arg definitions for the entire RDA kernel module.
 * Each device will only respond to a subset of this full list of
 * commands.
 */
#define RDA_IOC_MAGIC 'R'	/* IOCTL magic number */

#define RVPIOC_STATUS      _IOR( RDA_IOC_MAGIC,  0, struct rvpio_status )
#define RVPIOC_WRFLUSH	    _IO( RDA_IOC_MAGIC,  1 ) /* Flush our write FIFO */
#define RVPIOC_RDFLUSH	    _IO( RDA_IOC_MAGIC,  2 ) /* Flush our read FIFO */
#define RVPIOC_SETIMEOUT    _IO( RDA_IOC_MAGIC,  3 ) /* Set read timeout */
#define RVPIOC_ZAPCOUNTS    _IO( RDA_IOC_MAGIC,  4 ) /* Zero WR/RD counters */

#define RDAIOC_RECFGBOARD   _IO( RDA_IOC_MAGIC,  5 ) /* Reconfigure our board */
#define RDAIOC_RECFGSYSTEM  _IO( RDA_IOC_MAGIC,  6 ) /* Reconfigure all boards */
#define RDAIOC_WAITFORINT   _IO( RDA_IOC_MAGIC,  7 ) /* Wait for interrupt */

#define RDAIOC_DMASTART    _IOW( RDA_IOC_MAGIC,  8, struct rda_dmastart )
#define RDAIOC_DMABUSY     _IOR( RDA_IOC_MAGIC,  9, int )
#define RDAIOC_CACHEINFO   _IOR( RDA_IOC_MAGIC, 10, struct rda_cacheinfo )
#define RDAIOC_BOARDINFO   _IOR( RDA_IOC_MAGIC, 11, struct rda_boardinfo )

#define RDAIOC_BOOTPAGE     _IO( RDA_IOC_MAGIC, 12 ) /* Reboot FPGA(s) from ROM */
#define RDAIOC_BOOTLED      _IO( RDA_IOC_MAGIC, 13 ) /* Control Boot/JTAG LED */

#define RDAIOC_JTAGGET      _IO( RDA_IOC_MAGIC, 14 ) /* GET/SET return the TDO line, */
#define RDAIOC_JTAGSET      _IO( RDA_IOC_MAGIC, 15 ) /*   SET sets output lines first. */
#define RDAIOC_JTAGCYCLE    _IO( RDA_IOC_MAGIC, 16 ) /* Perform a complete clock cycle */

#define RDAIOC_IOSERIAL    _IOW( RDA_IOC_MAGIC, 17, struct intActionArgsTTY )
#define RDAIOC_IOSWRITE     _IO( RDA_IOC_MAGIC, 18 ) /* Write serial Tx character */
#define RDAIOC_IOSREAD      _IO( RDA_IOC_MAGIC, 19 ) /* Read serial Rx character */
#define RDAIOC_IOSQUEUED    _IO( RDA_IOC_MAGIC, 20 ) /* Return number of Tx/Rx in FIFOs */
  #define IOSQUEUED_TX  0
  #define IOSQUEUED_RX  1

#define RDA_IOC_COUNT  21	/* Total number of opcodes */

/* NOTE: There is only one interrupt per board, and only one IOCTL for
 * waiting on it.  This makes it possible to write a generic kernel
 * handler that needs to know virtually nothing about the board
 * details.  INTUNITS is a mask of interruptible functions on the PCI
 * card that we want to wait for.  We will wakeup as soon as any of
 * the conditions are met.
 */
#define RDA_WAIT_FOR_INTERRUPT( FD, INTUNIT ) \
  do { \
    if( ioctl( (FD), RDAIOC_WAITFORINT, (INTUNIT) ) < 0 ) \
      sig_signal( errno_to_message_va( errno, 1, "WaitForInt()" ) ) ; \
  } while(0)

/* The maximum realtime delay from the posting of an interrupt to the
 * execution of the first line of code in a high priority thread that
 * was waiting for that interrupt.  This is largely determined by the
 * worst case kernel preemptions due to disk I/O, network I/O, etc.
 */
#define RDA_MAX_INT_LATENCY_MS  25 /* Rough empirical guess (miliseconds) */

#endif /* #ifndef SIGMET_RDA_H */
