/*  Copyright(c) 2009-2012 Shenzhen TP-LINK Technologies Co.Ltd.
 *
 * file		mt7620.h
 * brief		
 * details	
 *
 * author	Di Baosheng
 * version	1.0.0
 * date		16Aug12
 *
 * warning	
 *
 * history \arg 1.0.0, 16Aug12, Di Baosheng, Create the file.
 */

#ifndef	__INCLUDE_MT7620_H__
#define	__INCLUDE_MT7620_H__

#include "rt_mmap.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef CONFIG_RALINK_MT7620
#define CONFIG_RALINK_MT7620 1
#endif

#if defined(__MIPSEB__)
#define cpu_to_le32(x) __swab32((x))
#define cpu_to_le16(x) __swab16((x))
#elif defined(__MIPSEL__)
#define cpu_to_le32(x) ((UINT32)(x))
#define cpu_to_le16(x) ((UINT16)(x))
#define le32_to_cpu(x) ((UINT32)(x))
#define le16_to_cpu(x) ((UINT16)(x))
#else
#error "I don't know the endian!"
#endif

/* interrupt priority */
#define INT_PRIO_MSB				TRUE            /* interrupt priority msb highest */

/* interrupt levels */
#define INT_LVL_TIMER				SR_IBIT8        /* timer (fixed) */
#define INT_LVL_IORQ4				SR_IBIT7        /* IORQ 4 */
#define INT_LVL_IORQ3				SR_IBIT6        /* IORQ 3 */
#define INT_LVL_IORQ2				SR_IBIT5        /* IORQ 2 */
#define INT_LVL_IORQ1				SR_IBIT4        /* IORQ 1 */
#define INT_LVL_IORQ0				SR_IBIT3        /* IORQ 0 */
#define INT_LVL_SW1					SR_IBIT2        /* sw interrupt 1 (fixed) */
#define INT_LVL_SW0					SR_IBIT1        /* sw interrupt 0 (fixed) */

#define SYSMODEL					"MT7620(MIPS32)"
#define BUS							0
#define DEFAULT_SR					(SR_CU0| (SR_IMASK0 & (INT_LVL_IORQ0 | INT_LVL_IORQ2 | INT_LVL_IORQ3 | INT_LVL_IORQ4 | INT_LVL_TIMER )) | SR_IE)

/* TODO - interrupt vectors for intPrioTable */
#define INT_VEC_BASE				0x50

/*
 * The IPs. Connected to CPU (hardware IP's; the first two are software)
 */
#define IV_INT0_VEC					(INT_VEC_BASE+2)
#define IV_INT1_VEC					(INT_VEC_BASE+3)
#define IV_INT2_VEC					(INT_VEC_BASE+4)
#define IV_INT3_VEC					(INT_VEC_BASE+5)
#define IV_INT4_VEC					(INT_VEC_BASE+6)
#define IV_TIMER_VEC				(INT_VEC_BASE+7)

#define INT_NUM_PCI				IV_INT2_VEC			/* ��Ӧdatasheet��int2 */
#define INT_NUM_ETH					IV_INT3_VEC			/* hardware interrupt #3 */
#define INT_NUM_WLAN				IV_INT2_VEC

/* TODO - indirect interrupt vectors: these vectors are to handle the muxed
 * interrupts
 */
#define INT_NUM_IRQ0    			(INT_VEC_BASE+8)

#define INT_NUM_SYSCTL				(INT_NUM_IRQ0+0)	/* SYSCTL */
#define INT_NUM_TIMER0				(INT_NUM_IRQ0+1)	/* timer0 */
#define INT_NUM_WDTIMER				(INT_NUM_IRQ0+2)	/* watch dog */
#define INT_NUM_ILL_ACC				(INT_NUM_IRQ0+3)	/* illegal access */
#define INT_NUM_PCM					(INT_NUM_IRQ0+4)	/* PCM */
#define INT_NUM_UART				(INT_NUM_IRQ0+5)	/* UART */
#define INT_NUM_GPIO				(INT_NUM_IRQ0+6)	/* GPIO */
#define INT_NUM_DMA					(INT_NUM_IRQ0+7)	/* DMA */
#define INT_NUM_NAND				(INT_NUM_IRQ0+8)	/* NAND */
#define INT_NUM_PC					(INT_NUM_IRQ0+9)	/* Performance counter */
#define INT_NUM_I2S					(INT_NUM_IRQ0+10)	/* I2S */
#define INT_NUM_UART1				(INT_NUM_IRQ0+12)	/* UART Lite */
#define INT_NUM_ESW					(INT_NUM_IRQ0+17)	/* ESW */
#define INT_NUM_OTG					(INT_NUM_IRQ0+18)	/* OTG */


/*
 * Address of RALINK_ Registers
 */
#define RALINK_SYSCTL_ADDR		RALINK_SYSCTL_BASE	/* system control */
#define RALINK_RSTCTL_ADDR		(RALINK_SYSCTL_ADDR + 0x34)
#define RALINK_REG_GPIOMODE		(RALINK_SYSCTL_ADDR + 0x60)
#define RALINK_REG_INTENA		(RALINK_INTCL_BASE + 0x34)
#define RALINK_REG_INTDIS		(RALINK_INTCL_BASE + 0x38)

#define RALINK_SYSCFG_REG			(RALINK_SYSCTL_BASE+0x10)
#define RALINK_SYSCFG1_REG			(RALINK_SYSCTL_BASE+0x14)
#define RALINK_CLKCFG1_REG			(RALINK_SYSCTL_BASE+0x30)
#define RALINK_RSTSTAT_REG			(RALINK_SYSCTL_BASE+0x38)
#define RALINK_SYSCLKCFG_REG  		(RALINK_SYSCTL_BASE+0x3c)
#define RALINK_GPIOMODE_REG			(RALINK_SYSCTL_BASE+0x60)

#define RALINK_GPIOMODE_I2C		0x01
#define RALINK_GPIOMODE_UARTF		0x1C
#define RALINK_GPIOMODE_UARTL		0x20
//#define RALINK_GPIOMODE_JTAG		0x40
#define RALINK_GPIOMODE_MDIO		0x180
#define RALINK_GPIOMODE_GE1		0x200
#define RALINK_GPIOMODE_GE2		0x400
#define RALINK_GPIOMODE_SPI		0x800
#define RALINK_GPIOMODE_SPI_REFCLK	0x1000
#define RALINK_GPIOMODE_WLED		0x2000
#define RALINK_GPIOMODE_EPHY		0x8000
#define RALINK_GPIOMODE_PERST		0x20000
#define RALINK_GPIOMODE_ND_SD		0x80000
#define RALINK_GPIOMODE_PA_G		0x100000
#define RALINK_GPIOMODE_WDT		0x400000

/* #define RALINK_GPIOMODE_SDRAM		0x100by xld, 21Oct11 */
/* #define RALINK_GPIOMODE_RGMII		0x200by xld, 21Oct11 */

/* if you would like to enable GPIO mode for other pins, please modify this value
 * !! Warning: changing this value may make other features(MDIO, PCI, etc) lose efficacy
 */
#define RALINK_GPIOMODE_DFT		(RALINK_GPIOMODE_UARTF)

#define RALINK_PRGIO_ADDR		RALINK_PIO_BASE /* Programmable I/O */
#define RALINK_REG_PIOINT		(RALINK_PRGIO_ADDR + 0)
#define RALINK_REG_PIOEDGE		(RALINK_PRGIO_ADDR + 0x04)
#define RALINK_REG_PIORENA		(RALINK_PRGIO_ADDR + 0x08)
#define RALINK_REG_PIOFENA		(RALINK_PRGIO_ADDR + 0x0C)
#define RALINK_REG_PIODATA		(RALINK_PRGIO_ADDR + 0x20)
#define RALINK_REG_PIODIR		(RALINK_PRGIO_ADDR + 0x24)
#define RALINK_REG_PIOPOL		(RALINK_PRGIO_ADDR + 0x28)
#define RALINK_REG_PIOSET		(RALINK_PRGIO_ADDR + 0x2C)
#define RALINK_REG_PIORESET		(RALINK_PRGIO_ADDR + 0x30)
#define RALINK_REG_PIOTOGGLE	(RALINK_PRGIO_ADDR + 0x34)

#define RALINK_REG_PIO3924INT		(RALINK_PRGIO_ADDR + 0x38)
#define RALINK_REG_PIO3924EDGE		(RALINK_PRGIO_ADDR + 0x3C)
#define RALINK_REG_PIO3924RENA		(RALINK_PRGIO_ADDR + 0x40)
#define RALINK_REG_PIO3924FENA		(RALINK_PRGIO_ADDR + 0x44)
#define RALINK_REG_PIO3924DATA		(RALINK_PRGIO_ADDR + 0x48)
#define RALINK_REG_PIO3924DIR		(RALINK_PRGIO_ADDR + 0x4C)
#define RALINK_REG_PIO3924POL		(RALINK_PRGIO_ADDR + 0x50)
#define RALINK_REG_PIO3924SET		(RALINK_PRGIO_ADDR + 0x54)
#define RALINK_REG_PIO3924RESET		(RALINK_PRGIO_ADDR + 0x58)
#define RALINK_REG_PIO3924TOGGLE	(RALINK_PRGIO_ADDR + 0x5C)

#define RALINK_REG_PIO7140INT		(RALINK_PRGIO_ADDR + 0x60)
#define RALINK_REG_PIO7140EDGE		(RALINK_PRGIO_ADDR + 0x64)
#define RALINK_REG_PIO7140RENA		(RALINK_PRGIO_ADDR + 0x68)
#define RALINK_REG_PIO7140FENA		(RALINK_PRGIO_ADDR + 0x6C)
#define RALINK_REG_PIO7140DATA		(RALINK_PRGIO_ADDR + 0x70)
#define RALINK_REG_PIO7140DIR		(RALINK_PRGIO_ADDR + 0x74)
#define RALINK_REG_PIO7140POL		(RALINK_PRGIO_ADDR + 0x78)
#define RALINK_REG_PIO7140SET		(RALINK_PRGIO_ADDR + 0x7C)
#define RALINK_REG_PIO7140RESET		(RALINK_PRGIO_ADDR + 0x80)
#define RALINK_REG_PIO7140TOGGLE	(RALINK_PRGIO_ADDR + 0x84)

#define RALINK_REG_PIO72INT			(RALINK_PRGIO_ADDR + 0x88)
#define RALINK_REG_PIO72EDGE		(RALINK_PRGIO_ADDR + 0x8c)
#define RALINK_REG_PIO72RENA		(RALINK_PRGIO_ADDR + 0x90)
#define RALINK_REG_PIO72FENA		(RALINK_PRGIO_ADDR + 0x94)
#define RALINK_REG_PIO72DATA		(RALINK_PRGIO_ADDR + 0x98)
#define RALINK_REG_PIO72DIR			(RALINK_PRGIO_ADDR + 0x9C)
#define RALINK_REG_PIO72POL			(RALINK_PRGIO_ADDR + 0xA0)
#define RALINK_REG_PIO72SET			(RALINK_PRGIO_ADDR + 0xA4)
#define RALINK_REG_PIO72RESET		(RALINK_PRGIO_ADDR + 0xA8)
#define RALINK_REG_PIO72TOGGLE		(RALINK_PRGIO_ADDR + 0xAC)

#define RALINK_GPIO_DATA_MASK	0x00FFFFFF
#define RALINK_GPIO_DATA_LEN	24

#define RALINK_GPIO(x)			(1L << x)

#define RALINK_REG_TMR0LOAD		(RALINK_TIMER_BASE + 0x10)	/* Timer0 Load Value */
#define RALINK_REG_TMR0CTL		(RALINK_TIMER_BASE + 0x18)	/* Timer0 Control */

#define sysRegRead(phys) 		(*(volatile unsigned int *)PHYS_TO_K1(phys))
#define sysRegWrite(phys, val)  ((*(volatile unsigned int *)PHYS_TO_K1(phys)) = (val))

/*
 * Address of RALINK_ Registers from rt_mmap.h
 */
#define RALINK_SYSCTL_BASE		0xB0000000
#define RALINK_TIMER_BASE		0xB0000100
#define RALINK_INTCL_BASE		0xB0000200
#define RALINK_MEMCTRL_BASE		0xB0000300
#define RALINK_RBUS_MATRIXCTL_BASE	0xB0000400
#define RALINK_UART_BASE		0x10000500
#define RALINK_PIO_BASE			0xB0000600
#define RALINK_NAND_CTRL_BASE		0xB0000810
#define RALINK_I2C_BASE			0xB0000900
#define RALINK_I2S_BASE			0xB0000A00
#define RALINK_SPI_BASE			0xB0000B00
#define RALINK_UART_LITE_BASE		0x10000C00
#define RALINK_MIPS_CNT_BASE		0x10000D00
#define RALINK_PCM_BASE			0xB0002000
#define RALINK_GDMA_BASE		0xB0002800
#define RALINK_CRYPTO_ENGINE_BASE	0xB0004000
#define RALINK_FRAME_ENGINE_BASE	0xB0100000
#define RALINK_PPE_BASE			0xB0100C00
#define RALINK_ETH_SW_BASE		0xB0110000
#define RALINK_USB_DEV_BASE		0x10120000
#define RALINK_MSDC_BASE		0xB0130000
#define RALINK_PCI_BASE                 0xB0140000
#define RALINK_11N_MAC_BASE		0xB0180000
#define RALINK_USB_HOST_BASE		0x101C0000

#define RALINK_MCNT_CFG			0xB0000D00
#define RALINK_COMPARE			0xB0000D04
#define RALINK_COUNT			0xB0000D08

#define RALINK_CPLLCFG0_REG		(RALINK_SYSCTL_BASE+0x54)
#define RALINK_CPLLCFG1_REG		(RALINK_SYSCTL_BASE+0x58)

#define RALINK_GLOBAL_FLOW_CTL	(RALINK_ETH_SW_BASE + 0x1FE0)
#define RALINK_FC_EN			(1<<31)

/*Interrupt Controller */
#define RALINK_INTCTL_SYSCTL		(1<<0)
#define RALINK_INTCTL_TIMER0		(1<<1)
#define RALINK_INTCTL_WDTIMER		(1<<2)
#define RALINK_INTCTL_ILL_ACCESS	(1<<3)
#define RALINK_INTCTL_PCM		(1<<4)
#define RALINK_INTCTL_UART		(1<<5)
#define RALINK_INTCTL_PIO		(1<<6)
#define RALINK_INTCTL_DMA		(1<<7)
#define RALINK_INTCTL_PC		(1<<9)
#define RALINK_INTCTL_I2S		(1<<10)
#define RALINK_INTCTL_SPI		(1<<11)
#define RALINK_INTCTL_UARTLITE		(1<<12)
#define RALINK_INTCTL_CRYPTO		(1<<13)
#define RALINK_INTCTL_ESW		(1<<17)
#define RALINK_INTCTL_UHST		(1<<18)
#define RALINK_INTCTL_UDEV		(1<<19)
#define RALINK_INTCTL_GLOBAL		(1<<31)

//Reset Control Register
#define RALINK_SYS_RST			(1<<0)
#define RALINK_TIMER_RST		(1<<8)
#define RALINK_INTC_RST			(1<<9)
#define RALINK_MC_RST			(1<<10)
#define RALINK_PCM_RST			(1<<11)
#define RALINK_UART_RST			(1<<12)
#define RALINK_PIO_RST			(1<<13)
#define RALINK_DMA_RST			(1<<14)
#define RALINK_I2C_RST			(1<<16)
#define RALINK_I2S_RST			(1<<17)
#define RALINK_SPI_RST			(1<<18)
#define RALINK_UARTL_RST		(1<<19)
#define RALINK_FE_RST			(1<<21)
#define RALINK_UHST_RST			(1<<22)
#define RALINK_ESW_RST			(1<<23)
#define RALINK_EPHY_RST			(1<<24)
#define RALINK_UDEV_RST			(1<<25)
#define RALINK_PCIE0_RST		(1<<26)
#define RALINK_PCIE1_RST		(1<<27)
#define RALINK_MIPS_CNT_RST		(1<<28)
#define RALINK_CRYPTO_RST		(1<<29)

//Clock Conf Register
#define RALINK_UPHY0_CLK_EN		(1<<25)
#define RALINK_UPHY1_CLK_EN		(1<<22)
#define RALINK_PCIE0_CLK_EN		(1<<26)
#define RALINK_PCIE1_CLK_EN		(1<<27)

//CPU PLL CFG Register
#define CPLL_SW_CONFIG                  (0x1UL << 31)
#define CPLL_MULT_RATIO_SHIFT           16
#define CPLL_MULT_RATIO                 (0x7UL << CPLL_MULT_RATIO_SHIFT)
#define CPLL_DIV_RATIO_SHIFT            10
#define CPLL_DIV_RATIO                  (0x3UL << CPLL_DIV_RATIO_SHIFT)
#define BASE_CLOCK                      40      /* Mhz */

/***** from rt_mmap.h end *****/
#define RALINK_REG(x)		(*((volatile unsigned int *)(x)))	

/*==================================================PCIE from linux===============================*/
#define RALINK_PCI_MM_MAP_BASE	0x20000000
#define RALINK_PCI_IO_MAP_BASE	0x10160000

#define RALINK_PCI_PCICFG_ADDR 		*(volatile UINT32 *)(RALINK_PCI_BASE + 0x0000)
#define RALINK_PCI_PCIRAW_ADDR 		*(volatile UINT32 *)(RALINK_PCI_BASE + 0x0004)
#define RALINK_PCI_PCIINT_ADDR 		*(volatile UINT32 *)(RALINK_PCI_BASE + 0x0008)
#define RALINK_PCI_PCIMSK_ADDR 		*(volatile UINT32 *)(RALINK_PCI_BASE + 0x000C)
#define RALINK_PCI_IMBASEBAR1_ADDR 	*(volatile UINT32 *)(RALINK_PCI_BASE + 0x001C)
#define RALINK_PCI_MEMBASE 		*(volatile UINT32 *)(RALINK_PCI_BASE + 0x0028)
#define RALINK_PCI_IOBASE 		*(volatile UINT32 *)(RALINK_PCI_BASE + 0x002C)
#define RALINK_PCI_ARBCTL 		*(volatile UINT32 *)(RALINK_PCI_BASE + 0x0080)

/*
PCI0 --> PCIe 0
PCI1 --> PCIe 1
*/
#define RT6855_PCIE0_OFFSET	0x2000
#define RT6855_PCIE1_OFFSET	0x3000

#define RALINK_PCI0_BAR0SETUP_ADDR 	*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010)
#define RALINK_PCI0_IMBASEBAR0_ADDR 	*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018)
#define RALINK_PCI0_ID 			*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030)
#define RALINK_PCI0_CLASS 		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034)
#define RALINK_PCI0_SUBID 		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038)
#define RALINK_PCI0_STATUS		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050)
#define RALINK_PCI0_DERR		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060)
#define RALINK_PCI0_ECRC		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064)

#define RALINK_PCI1_BAR0SETUP_ADDR 	*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010)
#define RALINK_PCI1_IMBASEBAR0_ADDR 	*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018)
#define RALINK_PCI1_ID 			*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030)
#define RALINK_PCI1_CLASS 		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034)
#define RALINK_PCI1_SUBID 		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038)
#define RALINK_PCI1_STATUS		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050)
#define RALINK_PCI1_DERR		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060)
#define RALINK_PCI1_ECRC		*(volatile UINT32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064)

#define RALINK_PCIEPHY_P0_CTL_OFFSET	(RALINK_PCI_BASE + 0x9000)


#ifdef __cplusplus
}
#endif
#endif	/* __INCLUDE_MT7620_H__ */

