#ifndef REGACCESS_H
#define REGACCESS_H

/* All regs are accessed in KSEG1 */
#define PNX833X_BASE		(0xa0000000ul + 0x17E00000ul)

#define PNX833X_REG(offs)	*((volatile unsigned long *)(PNX833X_BASE + offs))


/* Use PNX833X_FIELD to extract a field from val */

#define PNX_FIELD(cpu, val, reg, field) \
		(((val) & PNX##cpu##_##reg##_##field##_MASK) >> \
			PNX##cpu##_##reg##_##field##_SHIFT)
#define PNX833X_FIELD(val, reg, field)	PNX_FIELD(833X, val, reg, field)
#define PNX8330_FIELD(val, reg, field)	PNX_FIELD(8330, val, reg, field)
#define PNX8335_FIELD(val, reg, field)	PNX_FIELD(8335, val, reg, field)

/* Use PNX833X_REGFIELD to extract a field from a register */
#define PNX833X_REGFIELD(reg, field)	PNX833X_FIELD(PNX833X_##reg, reg, field)
#define PNX8330_REGFIELD(reg, field)	PNX8330_FIELD(PNX8330_##reg, reg, field)
#define PNX8335_REGFIELD(reg, field)	PNX8335_FIELD(PNX8335_##reg, reg, field)


#define PNX_WRITEFIELD(cpu, val, reg, field) \
   PNX833X_##reg = (PNX##cpu##_##reg & ~(PNX##cpu##_##reg##_##field##_MASK)) | \
                  ((val) << PNX##cpu##_##reg##_##field##_SHIFT)
#define PNX833X_WRITEFIELD(val, reg, field) \
					PNX_WRITEFIELD(833X, val, reg, field)
#define PNX8330_WRITEFIELD(val, reg, field) \
					PNX_WRITEFIELD(8330, val, reg, field)
#define PNX8335_WRITEFIELD(val, reg, field) \
					PNX_WRITEFIELD(8335, val, reg, field)

/* reset_control */
#define PNX833X_RESET_CONTROL			PNX833X_REG(0x8004)
#define PNX833X_RESET_CONTROL_UART_RESET_CTRL	0x00000400

#define PNX833X_RESET_CONTROL_2 		PNX833X_REG(0x8014)

/* config regs */
#define PNX8330_CONFIG_POLYFUSE_7		PNX833X_REG(0x7040)
#define PNX8335_CONFIG_POLYFUSE_9		PNX833X_REG(0x7074)
#define PNX8335_CONFIG_NAND_CS_EN		PNX833X_REG(0x7080)
#define PNX833X_CONFIG_MODULE_ID		PNX833X_REG(0x7FFC)

/* config regs - bit defs */
#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_SHIFT	(19)
#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_MASK	(0x03 << PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_SHIFT)

#define PNX8335_CONFIG_POLYFUSE_9_FLASH_CONFIG_SHIFT	(7)
#define PNX8335_CONFIG_POLYFUSE_9_FLASH_CONFIG_MASK	(0x07 << PNX8335_CONFIG_POLYFUSE_9_FLASH_CONFIG_SHIFT)
#define PNX8335_CONFIG_POLYFUSE_9_FLASH_TIMING_SHIFT	(1)
#define PNX8335_CONFIG_POLYFUSE_9_FLASH_TIMING_MASK	(0x3F << PNX8335_CONFIG_POLYFUSE_9_FLASH_TIMING_SHIFT)
#define PNX8335_CONFIG_POLYFUSE_9_SIGNATURE_CHECK_SHIFT	(0)
#define PNX8335_CONFIG_POLYFUSE_9_SIGNATURE_CHECK_MASK	(0x01 << PNX8335_CONFIG_POLYFUSE_9_SIGNATURE_CHECK_SHIFT)

#define PNX833X_CONFIG_MODULE_ID_MAJREV_SHIFT		(12)
#define PNX833X_CONFIG_MODULE_ID_MAJREV_MASK		(0x0F << PNX833X_CONFIG_MODULE_ID_MAJREV_SHIFT)
#define PNX8330_CONFIG_MODULE_MAJREV			(4)
#define PNX8335_M0_CONFIG_MODULE_MAJREV 		(5)
#define PNX8335_M1_CONFIG_MODULE_MAJREV 		(6)

/* config regs - helper macros */
#define PNX8335_CONFIG_NAND_CS_TOGGLE	(((PNX8335_CONFIG_POLYFUSE_9 & PNX8335_CONFIG_POLYFUSE_9_FLASH_TIMING_MASK) >> PNX8335_CONFIG_POLYFUSE_9_FLASH_TIMING_SHIFT) & 1)
#define PNX8335_CONFIG_SECURE_BOOT	(((PNX8335_CONFIG_POLYFUSE_9 & PNX8335_CONFIG_POLYFUSE_9_SIGNATURE_CHECK_MASK) == 0) ? 0 : 1)
#define CPU_IS_PNX8330			(PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == PNX8330_CONFIG_MODULE_MAJREV)
#define CPU_IS_PNX8335_M0		(PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == PNX8335_M0_CONFIG_MODULE_MAJREV)
#define CPU_IS_PNX8335_M1		(PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == PNX8335_M1_CONFIG_MODULE_MAJREV)

#if 0
/* pio (direct register access shouldn't be needed anymore... use GPIO driver instead) */
#define PNX833X_PIO_SEL		PNX833X_REG(0xF014)
#define PNX833X_PIO_DIR		PNX833X_REG(0xF008)
#define PNX833X_PIO_IN		PNX833X_REG(0xF000)
#define PNX833X_PIO_OUT		PNX833X_REG(0xF004)
#endif

/* serial */
#ifdef PNX833X_UART0
#define PNX833X_UART_LCR_FCR	PNX833X_REG(0xB000)
#define PNX833X_UART_BAUDRATE	PNX833X_REG(0xB008)
#define PNX833X_UART_RBR_THR	PNX833X_REG(0xB028)
#define PNX833X_UART_INT_ENABLE PNX833X_REG(0xBFE4)
#define PNX833X_UART_INT_CLEAR  PNX833X_REG(0xBFE8)
#endif

#ifdef PNX833X_UART1
#define PNX833X_UART_LCR_FCR	PNX833X_REG(0xC000)
#define PNX833X_UART_BAUDRATE	PNX833X_REG(0xC008)
#define PNX833X_UART_RBR_THR	PNX833X_REG(0xC028)
#define PNX833X_UART_INT_ENABLE PNX833X_REG(0xCFE4)
#define PNX833X_UART_INT_CLEAR  PNX833X_REG(0xCFE8)
#endif

#define PNX833X_UART_LCR_FCR_BIT_8		0x01000000	/* bit 24 */
#define PNX833X_UART_LCR_FCR_TX_FIFO_RST	0x00040000	/* bit 18 */
#define PNX833X_UART_LCR_FCR_RX_FIFO_RST	0x00020000	/* bit 17 */
#define PNX833X_UART_LCR_FCR_RX_FIFO_PT_ADV	0x00010000	/* bit 16 */
#define PNX833X_UART_RBR_THR_TXFIFO_STA_MASK	0x001F0000	/* bits 20:16 */
#define PNX833X_UART_RBR_THR_TXFIFO_STA_SHIFT	16
#define PNX833X_UART_RBR_THR_RXFIFO_STA_MASK	0x00001F00	/* bits 12:8 */
#define PNX833X_UART_RBR_THR_RXFIFO_STA_SHIFT	8

/* miu */
#define PNX833X_MIU_SEL0	PNX833X_REG(0x2004)
#define PNX833X_MIU_SEL0_TIMING	PNX833X_REG(0x2008)
#define PNX833X_MIU_SEL1	PNX833X_REG(0x200C)
#define PNX833X_MIU_SEL1_TIMING	PNX833X_REG(0x2010)
#define PNX833X_MIU_SEL2	PNX833X_REG(0x2014)
#define PNX833X_MIU_SEL2_TIMING	PNX833X_REG(0x2018)
#define PNX833X_MIU_SEL3	PNX833X_REG(0x201C)
#define PNX833X_MIU_SEL3_TIMING	PNX833X_REG(0x2020)

#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_MASK	(1 << 14)
#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_SHIFT	14

#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_MASK	(1 << 7)
#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_SHIFT	7

#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_MASK	(0xF << 9)
#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_SHIFT	9

#define PNX833X_MIU_CONFIG	PNX833X_REG(0x2000)

#define PNX833X_MIU_CONFIG_SPI_OPCODE_MASK	(0xFF << 3)
#define PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT	3

#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_MASK	(1 << 2)
#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT	2

#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_MASK	(1 << 1)
#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT	1

#define PNX833X_MIU_CONFIG_SPI_SYNC_MASK	(1 << 0)
#define PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT	0

#define PNX833X_WRITE_SPI_CONFIG(opcode, data_enable, addr_enable, sync) \
   PNX833X_MIU_CONFIG = \
   ((opcode) << PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT) | \
   ((data_enable) << PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT) | \
   ((addr_enable) << PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT) | \
   ((sync) << PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT)

#endif
