
/*
 Copyright 1999 by Digi International (www.digi.com)

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the 
 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 PURPOSE.  See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Things that describe the LSI Logic RAP I L64388A2 chip.
 * (not the board, not the project, I said *chip*)
 * Things that describe the processor core don't go here, either.  They
 * live in libidt.
 *
 * $Id: rap1.h,v 1.36 2000/04/27 15:47:06 garyp Exp $
 */

#ifndef REGISTER_SECTION_INITIALIZER
#  define REGISTER_SECTION_INITIALIZER
#endif

#ifndef EXTERN
#  define EXTERN extern
#endif

#ifdef __mips
#  define REGISTER_SECTION \
	__attribute__((section("register"))) REGISTER_SECTION_INITIALIZER
#else
#  define REGISTER_SECTION
#endif


/* typedef unsigned int uint32_on_8 	__attribute__ ((aligned(8))); */
/* typedef unsigned int uint8_on_8 	__attribute__ ((aligned(8))); */

/* typedef unsigned int uint8_on_8 	__attribute__ ((aligned(1))); */

#define PROCESSOR_HZ	80000000	/* CPU oscillator */
#define BRG_HZ		18432000	/* UART oscillator */

#if TEST
typedef unsigned int 	uint32 ;
typedef unsigned short 	uint16 ;
typedef unsigned char	uint8 ;
#endif

#define NSWCS 4			/* RAP 1 always has four serial channels */

/* #define ALIGNED_8 __attribute__ ((aligned(8))) */

/* Vectored Interrupt masks */

#define VI_DEBUGUART		(1<<0)
#define VI_GPIO0		(1<<1)
#define VI_GPIO1		(1<<2)
#define VI_GPIO2		(1<<3)
#define VI_GPIO3		(1<<4)
#define VI_GPIO4		(1<<5)
#define VI_GPIO5		(1<<6)
#define VI_GPIO6		(1<<7)
#define VI_GPIO7		(1<<8)
#define INT_MBOX_I2O		(1<<9)
#define VI_WATCHDOG		(1<<10)
#define INT_TIMER0		(1<<11)
#define INT_TIMER1		(1<<12)

/* Yes, these are numbered squirreley */
#define	INT_SWC1		(1<<19)
#define	INT_SWC2		(1<<18)
#define	INT_SWC3		(1<<17)
#define	INT_SWC4		(1<<16)
#define ALL_SWC_INTS (INT_SWC1|INT_SWC2|INT_SWC3|INT_SWC4)

#define	INT_DMAC_TX		(1<<22)
#define	INT_DMAC_RX		(1<<23)
#define INT_SOURCE_COUNT	6	/* All possible interrupt sources */

typedef struct rap_cpu_regs
{
	uint32	cpu_addr_map ;
	uint32 pad1;
	uint32	_missing ;
	uint32 pad2;
	uint32	int_pending ;
	uint32 pad3;
	uint32	int_enable ;
	uint32 pad4;
	uint32	vect_int_base ;
} RAP_CPU_REGS ;

typedef struct gpio
{
        uint32 config;
	#define GPIO_RESET		(1<<10)
	#define GPIO_GENERAL_PURPOSE 	(1<<9)
	#define GPIO_LOOPBAC		(1<<8)
	#define GPIO_OUTPUT_ENABLE_7	(1<<7)
	#define GPIO_OUTPUT_ENABLE_6	(1<<6)
	#define GPIO_OUTPUT_ENABLE_5	(1<<5)
	#define GPIO_OUTPUT_ENABLE_4	(1<<4)
	#define GPIO_OUTPUT_ENABLE_3	(1<<3)
	#define GPIO_OUTPUT_ENABLE_2	(1<<2)
	#define GPIO_OUTPUT_ENABLE_1	(1<<1)
	#define GPIO_OUTPUT_ENABLE_0	(1<<0)
	#define GPIO_OUTPUT_ENABLE_MASK	(\
		GPIO_OUTPUT_ENABLE_7 | GPIO_OUTPUT_ENABLE_6 | \
		GPIO_OUTPUT_ENABLE_5 | GPIO_OUTPUT_ENABLE_4 | \
		GPIO_OUTPUT_ENABLE_3 | GPIO_OUTPUT_ENABLE_2 | \
		GPIO_OUTPUT_ENABLE_1 | GPIO_OUTPUT_ENABLE_0 ) 
	
        uint32 _pad1;
        uint32 intr_ctrl;
        uint32 _pad2;
        uint32 output_data;
	#define GPIO_OUTPUT_0		(1<<0)
	#define GPIO_OUTPUT_1		(1<<1)
	#define GPIO_OUTPUT_2		(1<<2)
	#define GPIO_OUTPUT_3		(1<<3)
	#define GPIO_OUTPUT_4		(1<<4)
	#define GPIO_OUTPUT_5		(1<<5)
	#define GPIO_OUTPUT_6		(1<<6)
	#define GPIO_OUTPUT_7		(1<<7)
	#define GPIO_OUTPUT_8		(1<<8)
	#define GPIO_OUTPUT_9		(1<<9)
	#define GPIO_OUTPUT_10		(1<<10)
	#define GPIO_OUTPUT_11		(1<<11)
	/* Technically, these are RAP Eval board and *NOT* RAP chip specific */
	#define GPIO_LED_RED		GPIO_OUTPUT_7
	#define GPIO_LED_GRN0		GPIO_OUTPUT_8
	#define GPIO_LED_GRN1		GPIO_OUTPUT_9
	#define GPIO_LED_GRN2		GPIO_OUTPUT_10
	#define GPIO_LED_GRN3		GPIO_OUTPUT_11
	#define GPIO_LED_GRN		(GPIO_LED_GRN0 | GPIO_LED_GRN1 | \
					GPIO_LED_GRN2 | GPIO_LED_GRN3)
	#define GPIO_LED_ALL		(GPIO_LED_RED | GPIO_LED_GRN)

        uint32 _pad3;
        uint32 input_data;
        uint32 _pad4;
        /* More stuff, not interesting right now */
} RAP_GPIO_REGS ;


/* FIXME: Right now, include these defines from LSI Logic until 
   we can get more civilized ones in place. */

#define SDRAM_LP_MODE_OFF               0x00000000

#define SDRAM_CAS_LATENCY               0x00300000

#define SDRAM_RC_1MHZ                   0x00002000
#define SDRAM_RC_40MHZ                  0x00007000
#define SDRAM_RC_80MHZ                  0x0000A000

#define SDRAM_DP2                       0x00000000

#define SDRAM_RBS                       0x00000100

#define REFRESH_RATE_FOR_1MHZ           0x00000010

#define REFRESH_RATE_FOR_40MHZ          0x00000271

#define REFRESH_RATE_FOR_80MHZ          0x000004E2


typedef volatile struct local_mem_regs
{
	uint32	dram_refresh ;
	uint32	delay_config ;	/* Not a mistake.  Added in  Production run */
	uint32	sdram_control ;
	uint32	pad2;
	uint32	manual_precharge ;
	uint32	pad3;
	uint32	mode_register ;
	uint32	pad4;
	uint32	refresh_command ;
	uint32	pad5;
	uint32	eprom_control ;
	uint32	pad6;
	uint32	phy_control ;
} RAP_LOCAL_MEM_REGS ;


typedef struct pci_bmd
{
	#define RAP_DMA_PCI2LCL 	(0) 	/* Pseudo OP */
	#define	PCIBMD_VALID		(1 << 0)
	#define RAP_DMA_LCL2PCI		(1 << 1)
	#define PCIBMD_COMPLETE		(1 << 2)
	
        uint16          	count ;
        uint16          	flags ;
        uint32          	pci_addr;
        uint32          	local_addr;
        struct pci_bmd *	next_bmd;
} RAP_PCI_BMD ;

typedef struct mc_bmd
{
		#define BMD_DMAC_OWNS		(1 << 0)
		#define BMD_EOF			(1 << 1)
		#define BMD_START		(1 << 2)
		#define FRAME_ORUN		(1 << 3)
		/* reserved */
		#define ERR_ABORT		(1 << 8)
		#define ERR_FRAME		(1 << 9)
		#define ERR_CRC			(1 << 10)
		/* reserved */
		#define BMD_BURST_1		(0 << 16)
		#define BMD_BURST_2		(1 << 16)
		#define BMD_BURST_4		(2 << 16)
		#define BMD_BURST_8		(3 << 16)

		#define BMD_INT_ON_BUF_DONE	(1 << 18)
	uint32			flags ;
	uint16			byte_count;
	uint16			rx_frame_count;
	void *			buf;
	struct mc_bmd *		next_bmd;
} RAP_MC_BMD ;

/* 
 * This definition is gross becuase of the silly alignment constraints, 
 * but at least the calling site and the generated
 * code isn't horrible.
 */
typedef volatile struct rap_timer_regs
{
	struct timer
	{
		uint32	current_count;
		uint32 	padding1;
		uint32	init_count;
		uint32 	padding3;
	} timer[4] ;
	
	uint16 watchdog_timer;
	uint16 padding4;
	uint32 padding;

	struct config
	{
		#define TIMER_PERIODIC		(1<<5)
		#define TIMER_RESET		(1<<4)
		#define TIMER_ENABLE		(1<<3)
		#define	TIMER_SRC_SYSCLK	(0<<1)
		#define	TIMER_SRC_RTCCLK	(1<<1)
		#define	TIMER_SRC_1KHZ  	(2<<1)
		#define	TIMER_SRC_1HZ		(3<<1)
		#define TIMER_SRC_EXTERNAL	(1<<0)
		uint32	configuration;
		uint32	padding1;
	} config[5] ;

	struct timer_status
	{
		uint32	status;
		uint32	padding1;
	} status[5] ;

	

	
} RAP_TIMER_REGS ;

typedef volatile struct rap_pci_dmac_regs
{
	#define RAP_PCI_DMAC_LOCKOUT		(1<<0)
	#define RAP_PCI_DMAC_LREADY		(1<<1)
	#define RAP_PCI_DMAC_DMA_POLL		(1<<2)
	#define PCIDMAC_ENABLE			(1<<3)
	#define RAP_PCI_DMAC_RESET		(1<<4)
	uint32		dmac_control ;
	uint32		pad1;

	#define RAP_PCI_DMAC_BMD_INT_CLR	(1<<18)
	#define PCIDMAC_INT_LIST_CLR		(1<<17)
	#define RAP_PCI_DMAC_BMD_INT_PENDING	(1<<10)
	#define PCIDMAC_INT_LIST		(1<<9)
	#define RAP_PCI_DMAC_BMD_INT_ENABLE	(1<<2)
	#define PCIDMAC_INT_LIST_EN 		(1<<1)
	uint32		interrupt ;
	uint32		pad2;
	uint32		poll_timer ;
	uint32		pad3;
	volatile RAP_PCI_BMD *	bmd_pointer ;
}  RAP_PCI_DMAC_REGS ;


typedef volatile struct rap_reset_ctrl_regs
{
	uint32	cpu_reset_control ;
	uint32	pad1;
	uint32	sys_reset_control ;
	uint32	pad2;
	uint32	reg_access_enable ;
	uint32	pad3;

	#define LM_SIZE_1M		(0x1f)
	#define LM_SIZE_2M		(0x1e)
	#define LM_SIZE_4M		(0x1c)
	#define LM_SIZE_8M		(0x18)
	#define LM_SIZE_16M		(0x10)
	#define LM_SIZE_64M		(0x00)
	uint32	local_mem_size ;	
	uint32	pad4;

	#define	CPU_CMD_ERROR		(1<<0)
	#define	DMA_MEM_BERROR		(1<<1)
	#define	PCI_MEM_BERROR		(1<<2)
	#define	PCI_REG_BERROR		(1<<3)
	#define	PARITY_ERROR		(1<<4)
	#define	MST_FATAL		(1<<5)
	#define	ILL_ACCESS		(1<<6)
	#define	DMA_ERROR		(1<<7)
	#define	CPU_ERROR		(1<<8)

	uint32	rap_interrupt ;
	uint32	pad5;
	uint32	rap_pci_cmd ;
	uint32	pad6;
	uint32	rap_pci_addr ;
	uint32	pad7;
	uint32	rap_local_memory_addr ;
} RAP_RESET_CTRL_REGS ;

typedef volatile struct rap_dmac_regs
{
	uint32	_missing;
	uint32	pad1;
	uint32	rx_ch_enable ;
	uint32	pad2;
	uint32	tx_ch_enable ;
	uint32	pad3;

		#define MC_INT_RXEOF		(1<<4)
		#define MC_INT_LIST_COMPLETE	(1<<3)
		#define MC_INT_BUSERROR		(1<<2)
		#define MC_INT_BMD_NOTREADY	(1<<1)
		#define MC_INT_BMD_COMPLETE	(1<<0)
	uint32	rx_int_enable ;
	uint32	pad4;
		#define MC_INT_LIST_COMPLETE	(1<<3)
		#define MC_INT_BUSERROR		(1<<2)
		#define MC_INT_BMD_NOTREADY	(1<<1)
		#define MC_INT_BMD_COMPLETE	(1<<0)
	uint32	tx_int_enable ;
	uint32	pad5;
		#define SWC0_PENDING	(1<<1)
	uint32	rx_int_pending ;
	uint32	pad6;
	uint32	tx_int_pending ;
	uint32	pad7;
	uint32	rx_transparent ;
	uint32	pad8;

	struct tx_bmd
	{
		RAP_MC_BMD * 	reg;
		uint32 		pad;
	} tx_bmd[8] __attribute__ ((aligned(0x100)));

	struct rx_bmd
	{
		RAP_MC_BMD * 	reg;
		uint32 		pad;
	} rx_bmd[8] __attribute__ ((aligned(0x100)));

	#define MC_INT_BMD_ENABLE (1<<31)
	struct tx_int_status
	{
		uint32		reg;
		uint32 		pad;
	} tx_int_status[8] __attribute__ ((aligned(0x100)));

	struct rx_int_status
	{
		uint32		reg;
		uint32 		pad;
	} rx_int_status[8] __attribute__ ((aligned(0x100)));

	struct tx_bmd_next
	{
		uint32		reg;
		uint32 		pad;
	} tx_bmd_next[8] __attribute__ ((aligned(0x100)));

	struct rx_bmd_next
	{
		uint32		reg;
		uint32 		pad;
	} rx_bmd_next[8] __attribute__ ((aligned(0x100)));
} RAP_DMAC_REGS ;

typedef volatile struct rap_swc_regs
{
		#define TX_CLK_IS_RX_CLK_INPUT	(0x00 << 6)
		#define TX_CLK_IS_BRG_DIV_16	(0x01 << 6)
		#define TX_CLK_IS_TX_CLK_INPUT	(0x02 << 6)
		#define TX_CLK_IS_DISABLED    	(0x03 << 6)
		#define TX_CLK_MASK 		(0x03 << 6)

		#define RX_CLK_IS_RX_CLK_INPUT	(0x00 << 4)
		#define RX_CLK_IS_BRG_DIV_16	(0x01 << 4)
		#define RX_CLK_IS_DPLL		(0x02 << 4)
		#define RX_CLK_IS_DISABLED    	(0x03 << 4)
		#define RX_CLK_MASK 		(0x03 << 4)

		#define BRG_IS_SYSTEM_CLK	(1 << 3)

		#define SWC_LOOPBACK		(1 << 1)

	uint32	swc_config;
	uint32	unused1;

		#define BRG_PRESCALE		(1 << 20)
		#define BRG_COUNT_MASK		0xfffff
	uint32	brg_count;
	uint32	unused2;

		#define SWC_RESET 		(1 << 0)
		#define SWC_RX_HALT		(1 << 1)
		#define SWC_TX_HALT		(1 << 2)
	uint32	reset;
	uint32	unused3;

		#define	SWCINT_CTL_RTS		(1<<12)
		#define	SWCINT_CTL_DTR		(1<<11)

		#define SWC_INT_DSR_EN		(1<<22)
		#define SWC_INT_CTS_EN		(1<<21)
		#define SWC_INT_DCD_EN		(1<<20)

		#define SWC_INT_DSR_STATE	(1<<18)
	
		#define SWC_INT_DSR_CLR		(1<<6)

	uint32	int_control;
	uint32	unused4;
	uint32	sync_character;
	uint32	unused5;
	uint32	idle_character;
	uint32	unused6;
	uint32	interval_timer;
	uint32	unused7;
	uint32	rx_idle_count;
	uint32 	unused8;

		/* Note: Not all possible values are filled in here */
		#define CRC_MEM			(1 << 18)
		#define IGNORE_CTS		(1 << 7)
		#define IGNORE_DSR		(1 << 6)
		#define IGNORE_DCD		(1 << 5)

		#define FRAME_ASYNC		(1 << 4)
		#define ASYNC_DATABITS_8	(1 << 1)
		#define ASYNC_STOPBITS_1	(1 << 0)
		

	uint32	chan_config;
	uint32	unused9;
	uint32	tx_idle_count;
	uint32	unused10;
	uint32	rx_rate;
	uint32	unused11;
	uint32	abrd_min_sample;
	uint32	unused[0] __attribute__ ((aligned(0x200)));
	
} RAP_SWC_REGS ;

typedef volatile struct rap_mbox_regs
{
	uint32	tx_fifo;
	uint32	unused1;
	uint32	rx_fifo;
	uint32	unused2;
	# define MBOX_RX_EMPTY			(1<<3)
	# define MBOX_ENABLE_INT_TO_HOST	(1<<12)
	uint32	xpci_ctrl;
	uint32	unused_1[0] __attribute__ ((aligned(0x20)));
	uint32	unused_2;
	uint32	unused_3[0] __attribute__ ((aligned(0x10)));
	# define MBOX_ENABLE	0x01
	uint32	mbox_address;
	uint32	unused3;
	# define MBOX_256_WORDS	0x80
	# define MBOX_128_WORDS	0x40
	# define MBOX_64_WORDS	0x20
	# define MBOX_32_WORDS	0x10
	uint32	mbox_size;
	uint32	unused4;
	uint32	mbox_threshold;
	uint32	unused5;
} RAP_MBOX_REGS ;


typedef volatile struct rap_wan_ctrl_regs
{
	uint32	port_config;
	/* There's a bunch of crazy bitmapped options arranged incredibly
	 * inconveniently.  We'll weenie out and define the only one that
	 * I think makes sense for us. 
	 */
	#define ALL_PORTS_USE_RI 0xff
} RAP_WAN_CTRL_REGS ;


/*
 *	Below, the __attribute__((section("register"))), produced
 *	by the REGISTER_SECTION macro when compiled for a MIPS
 *	architecture, is enough to force non-GP-relative code
 *	to be emitted for accesses.
 *	There is much preprocessor abuse happening here.  When
 *	this file is included 
 */
EXTERN RAP_CPU_REGS 		rap_cpu_regs 		REGISTER_SECTION;
EXTERN RAP_PCI_DMAC_REGS 	rap_pci_dmac_regs 	REGISTER_SECTION;
EXTERN RAP_TIMER_REGS 		rap_timer_regs 		REGISTER_SECTION;
EXTERN RAP_SWC_REGS 		rap_swc_regs[NSWCS] 	REGISTER_SECTION;
EXTERN RAP_DMAC_REGS 		rap_dmac_regs 		REGISTER_SECTION;
EXTERN RAP_MBOX_REGS 		rap_mbox_regs 		REGISTER_SECTION;
EXTERN RAP_WAN_CTRL_REGS 	rap_wan_ctrl_regs 	REGISTER_SECTION;
EXTERN RAP_RESET_CTRL_REGS 	rap_ctrl_regs 		REGISTER_SECTION;
EXTERN RAP_GPIO_REGS 		rap_gpio_regs 		REGISTER_SECTION;

#undef	REGISTER_SECTION

#define RAP char

#define V_OFF(a,b) offsetof(struct a, b)
#define assert_rap_offsets()						\
									\
{									\
	assert( 0x00 == V_OFF(rap_cpu_regs, cpu_addr_map));		\
	assert( 0x10 == V_OFF(rap_cpu_regs, int_pending));		\
	assert( 0x18 == V_OFF(rap_cpu_regs, int_enable));		\
									\
	assert( 0x20 == V_OFF(rap_cpu_regs, vect_int_base));		\
									\
	assert( 0x00 == V_OFF(local_mem_regs, dram_refresh));		\
	assert( 0x30 == V_OFF(local_mem_regs, phy_control));		\
									\
	assert( 0x08 == V_OFF(rap_pci_dmac_regs, interrupt));		\
	assert( 0x18 == V_OFF(rap_pci_dmac_regs, bmd_pointer));		\
									\
	assert( 0x00 == V_OFF(rap_reset_ctrl_regs, cpu_reset_control));	\
	assert( 0x18 == V_OFF(rap_reset_ctrl_regs, local_mem_size));	\
	assert( 0x38 == V_OFF(rap_reset_ctrl_regs, rap_local_memory_addr));	\
									\
	assert( 0x08 == V_OFF(rap_dmac_regs, rx_ch_enable));		\
	assert( 0x38 == V_OFF(rap_dmac_regs, rx_transparent));		\
									\
	assert( 0x100 == V_OFF(rap_dmac_regs, tx_bmd[0].reg));		\
	assert( 0x108 == V_OFF(rap_dmac_regs, tx_bmd[1].reg));		\
									\
	assert( 0x200 == V_OFF(rap_dmac_regs, rx_bmd[0].reg));		\
	assert( 0x208 == V_OFF(rap_dmac_regs, rx_bmd[1].reg));		\
									\
	assert( 0x300 == V_OFF(rap_dmac_regs, tx_int_status[0].reg)); 	\
	assert( 0x308 == V_OFF(rap_dmac_regs, tx_int_status[1].reg)); 	\
									\
	assert( 0x400 == V_OFF(rap_dmac_regs, rx_int_status[0].reg)); 	\
	assert( 0x408 == V_OFF(rap_dmac_regs, rx_int_status[1].reg)); 	\
									\
	assert( 16 == sizeof(struct pci_bmd)); 				\
									\
	assert( 16 == sizeof(struct mc_bmd)); 				\
									\
	assert( 0x58 == V_OFF(rap_swc_regs, abrd_min_sample));		\
	assert( 0x200 == sizeof(struct rap_swc_regs));			\
									\
	assert( 0x30 == V_OFF(rap_mbox_regs, mbox_address));		\
}

#if TEST
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
int 
main()
{
	assert_rap_offsets();
}
#endif

