/**
 * @file powerspan.c Source file for PowerSpan II code.
 */

/*
 * (C) Copyright 2005
 * AMIRIX Systems Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <asm/processor.h>
#include "powerspan.h"
#define tolower(x) x
#include "ap1000.h"

#ifdef INCLUDE_PCI

/** Write one byte with byte swapping.
  * @param  addr [IN] the address to write to
  * @param  val  [IN] the value to write
  */
void write1 (unsigned long addr, unsigned char val)
{
	volatile unsigned char *p = (volatile unsigned char *) addr;

#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("write1: addr=%08x val=%02x\n", addr, val);
	}
#endif
	*p = val;
	PSII_SYNC ();
}

/** Read one byte with byte swapping.
  * @param  addr  [IN] the address to read from
  * @return the value at addr
  */
unsigned char read1 (unsigned long addr)
{
	unsigned char val;
	volatile unsigned char *p = (volatile unsigned char *) addr;

	val = *p;
	PSII_SYNC ();
#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("read1: addr=%08x val=%02x\n", addr, val);
	}
#endif
	return val;
}

/** Write one 2-byte word with byte swapping.
  * @param  addr  [IN] the address to write to
  * @param  val   [IN] the value to write
  */
void write2 (unsigned long addr, unsigned short val)
{
	volatile unsigned short *p = (volatile unsigned short *) addr;

#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("write2: addr=%08x val=%04x -> *p=%04x\n", addr, val,
			((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
	}
#endif
	*p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
	PSII_SYNC ();
}

/** Read one 2-byte word with byte swapping.
  * @param  addr  [IN] the address to read from
  * @return the value at addr
  */
unsigned short read2 (unsigned long addr)
{
	unsigned short val;
	volatile unsigned short *p = (volatile unsigned short *) addr;

	val = *p;
	val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
	PSII_SYNC ();
#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("read2: addr=%08x *p=%04x -> val=%04x\n", addr, *p,
			val);
	}
#endif
	return val;
}

/** Write one 4-byte word with byte swapping.
  * @param  addr  [IN] the address to write to
  * @param  val   [IN] the value to write
  */
void write4 (unsigned long addr, unsigned long val)
{
	volatile unsigned long *p = (volatile unsigned long *) addr;

#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("write4: addr=%08x val=%08x -> *p=%08x\n", addr, val,
			((val & 0xFF000000) >> 24) |
			((val & 0x000000FF) << 24) |
			((val & 0x00FF0000) >>  8) |
			((val & 0x0000FF00) <<  8));
	}
#endif
	*p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
		((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
	PSII_SYNC ();
}

/** Read one 4-byte word with byte swapping.
  * @param  addr  [IN] the address to read from
  * @return the value at addr
  */
unsigned long read4 (unsigned long addr)
{
	unsigned long val;
	volatile unsigned long *p = (volatile unsigned long *) addr;

	val = *p;
	val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
		((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
	PSII_SYNC ();
#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("read4: addr=%08x *p=%08x -> val=%08x\n", addr, *p,
			val);
	}
#endif
	return val;
}

int PCIReadConfig (int bus, int dev, int fn, int reg, int width,
		   unsigned long *val)
{
	unsigned int conAdrVal;
	unsigned int conDataReg = REG_CONFIG_DATA;
	unsigned int status;
	int ret_val = 0;


	/* DEST bit hardcoded to 1: local pci is PCI-2 */
	/* TYPE bit is hardcoded to 1: all config cycles are local */
	conAdrVal = (1 << 24)
		| ((bus & 0xFF) << 16)
		| ((dev & 0xFF) << 11)
		| ((fn & 0x07) << 8)
		| (reg & 0xFC);

	/* clear any pending master aborts */
	write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);

	/* Load the conAdrVal value first, then read from pb_conf_data */
	write4 (REG_CONFIG_ADDRESS, conAdrVal);
	PSII_SYNC ();


	/* Note: documentation does not match the pspan library code */
	/* Note: *pData comes back as -1 if device is not present */
	switch (width) {
	case 4:
		*(unsigned int *) val = read4 (conDataReg);
		break;
	case 2:
		*(unsigned short *) val = read2 (conDataReg);
		break;
	case 1:
		*(unsigned char *) val = read1 (conDataReg);
		break;
	default:
		ret_val = ILLEGAL_REG_OFFSET;
		break;
	}
	PSII_SYNC ();

	/* clear any pending master aborts */
	status = read4 (REG_P1_CSR);
	if (status & CLEAR_MASTER_ABORT) {
		ret_val = NO_DEVICE_FOUND;
		write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
	}

	return ret_val;
}


int PCIWriteConfig (int bus, int dev, int fn, int reg, int width,
		    unsigned long val)
{
	unsigned int conAdrVal;
	unsigned int conDataReg = REG_CONFIG_DATA;
	unsigned int status;
	int ret_val = 0;


	/* DEST bit hardcoded to 1: local pci is PCI-2 */
	/* TYPE bit is hardcoded to 1: all config cycles are local */
	conAdrVal = (1 << 24)
		| ((bus & 0xFF) << 16)
		| ((dev & 0xFF) << 11)
		| ((fn & 0x07) << 8)
		| (reg & 0xFC);

	/* clear any pending master aborts */
	write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);

	/* Load the conAdrVal value first, then read from pb_conf_data */
	write4 (REG_CONFIG_ADDRESS, conAdrVal);
	PSII_SYNC ();


	/* Note: documentation does not match the pspan library code */
	/* Note: *pData comes back as -1 if device is not present */
	switch (width) {
	case 4:
		write4 (conDataReg, val);
		break;
	case 2:
		write2 (conDataReg, val);
		break;
	case 1:
		write1 (conDataReg, val);
		break;
	default:
		ret_val = ILLEGAL_REG_OFFSET;
		break;
	}
	PSII_SYNC ();

	/* clear any pending master aborts */
	status = read4 (REG_P1_CSR);
	if (status & CLEAR_MASTER_ABORT) {
		ret_val = NO_DEVICE_FOUND;
		write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
	}

	return ret_val;
}


int pci_read_config_byte (int bus, int dev, int fn, int reg,
			  unsigned char *val)
{
	unsigned long read_val;
	int ret_val;

	ret_val = PCIReadConfig (bus, dev, fn, reg, 1, &read_val);
	*val = read_val & 0xFF;

	return ret_val;
}

int pci_write_config_byte (int bus, int dev, int fn, int reg,
			   unsigned char val)
{
	return PCIWriteConfig (bus, dev, fn, reg, 1, val);
}

int pci_read_config_word (int bus, int dev, int fn, int reg,
			  unsigned short *val)
{
	unsigned long read_val;
	int ret_val;

	ret_val = PCIReadConfig (bus, dev, fn, reg, 2, &read_val);
	*val = read_val & 0xFFFF;

	return ret_val;
}

int pci_write_config_word (int bus, int dev, int fn, int reg,
			   unsigned short val)
{
	return PCIWriteConfig (bus, dev, fn, reg, 2, val);
}

int pci_read_config_dword (int bus, int dev, int fn, int reg,
			   unsigned long *val)
{
	return PCIReadConfig (bus, dev, fn, reg, 4, val);
}

int pci_write_config_dword (int bus, int dev, int fn, int reg,
			    unsigned long val)
{
	return PCIWriteConfig (bus, dev, fn, reg, 4, val);
}

#endif /* INCLUDE_PCI */

int I2CAccess (unsigned char theI2CAddress, unsigned char theDevCode,
	       unsigned char theChipSel, unsigned char *theValue, int RWFlag)
{
	int ret_val = 0;
	unsigned int reg_value;

	reg_value = PowerSpanRead (REG_I2C_CSR);

	if (reg_value & I2C_CSR_ACT) {
		printf ("Error: I2C busy\n");
		ret_val = I2C_BUSY;
	} else {
		reg_value = ((theI2CAddress & 0xFF) << 24)
			| ((theDevCode & 0x0F) << 12)
			| ((theChipSel & 0x07) << 9)
			| I2C_CSR_ERR;
		if (RWFlag == I2C_WRITE) {
			reg_value |= I2C_CSR_RW | ((*theValue & 0xFF) << 16);
		}

		PowerSpanWrite (REG_I2C_CSR, reg_value);
		udelay (1);

		do {
			reg_value = PowerSpanRead (REG_I2C_CSR);

			if ((reg_value & I2C_CSR_ACT) == 0) {
				if (reg_value & I2C_CSR_ERR) {
					ret_val = I2C_ERR;
				} else {
					*theValue =
						(reg_value & I2C_CSR_DATA) >>
						16;
				}
			}
		} while (reg_value & I2C_CSR_ACT);
	}

	return ret_val;
}

int EEPROMRead (unsigned char theI2CAddress, unsigned char *theValue)
{
	return I2CAccess (theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL,
			  theValue, I2C_READ);
}

int EEPROMWrite (unsigned char theI2CAddress, unsigned char theValue)
{
	return I2CAccess (theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL,
			  &theValue, I2C_WRITE);
}

int do_eeprom (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	char cmd;
	int ret_val = 0;
	unsigned int address = 0;
	unsigned char value = 1;
	unsigned char read_value;
	int ii;
	int error = 0;
	unsigned char *mem_ptr;
	unsigned char default_eeprom[] = EEPROM_DEFAULT;

	if (argc < 2) {
		goto usage;
	}

	cmd = argv[1][0];
	if (argc > 2) {
		address = simple_strtoul (argv[2], NULL, 16);
		if (argc > 3) {
			value = simple_strtoul (argv[3], NULL, 16) & 0xFF;
		}
	}

	switch (cmd) {
	case 'r':
		if (address > 256) {
			printf ("Illegal Address\n");
			goto usage;
		}
		printf ("@0x%x: ", address);
		for (ii = 0; ii < value; ii++) {
			if (EEPROMRead (address + ii, &read_value) !=
			    0) {
				printf ("Read Error\n");
			} else {
				printf ("0x%02x ", read_value);
			}

			if (((ii + 1) % 16) == 0) {
				printf ("\n");
			}
		}
		printf ("\n");
		break;
	case 'w':
		if (address > 256) {
			printf ("Illegal Address\n");
			goto usage;
		}
		if (argc < 4) {
			goto usage;
		}
		if (EEPROMWrite (address, value) != 0) {
			printf ("Write Error\n");
		}
		break;
	case 'g':
		if (argc != 3) {
			goto usage;
		}
		mem_ptr = (unsigned char *) address;
		for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
		     ii++) {
			if (EEPROMRead (ii, &read_value) != 0) {
				printf ("Read Error\n");
				error = 1;
			} else {
				*mem_ptr = read_value;
				mem_ptr++;
			}
		}
		break;
	case 'p':
		if (argc != 3) {
			goto usage;
		}
		mem_ptr = (unsigned char *) address;
		for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
		     ii++) {
			if (EEPROMWrite (ii, *mem_ptr) != 0) {
				printf ("Write Error\n");
				error = 1;
			}

			mem_ptr++;
		}
		break;
	case 'd':
		if (argc != 2) {
			goto usage;
		}
		for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
		     ii++) {
			if (EEPROMWrite (ii, default_eeprom[ii]) != 0) {
				printf ("Write Error\n");
				error = 1;
			}
		}
		break;
	default:
		goto usage;
	}

	goto done;
      usage:
	printf ("Usage:\n%s\n", cmdtp->help);

      done:
	return ret_val;

}

U_BOOT_CMD (eeprom, 4, 0, do_eeprom,
	    "read/write/copy to/from the PowerSpan II eeprom",
	    "eeprom r OFF [NUM]\n"
	    "    - read NUM words starting at OFF\n"
	    "eeprom w OFF VAL\n"
	    "    - write word VAL at offset OFF\n"
	    "eeprom g ADD\n"
	    "    - store contents of eeprom at address ADD\n"
	    "eeprom p ADD\n"
	    "    - put data stored at address ADD into the eeprom\n"
	    "eeprom d\n" "    - return eeprom to default contents");

unsigned int PowerSpanRead (unsigned int theOffset)
{
	volatile unsigned int *ptr =
		(volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
	unsigned int ret_val;

#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("PowerSpanRead: offset=%08x ", theOffset);
	}
#endif
	ret_val = *ptr;
	PSII_SYNC ();

#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("value=%08x\n", ret_val);
	}
#endif

	return ret_val;
}

void PowerSpanWrite (unsigned int theOffset, unsigned int theValue)
{
	volatile unsigned int *ptr =
		(volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("PowerSpanWrite: offset=%08x val=%02x\n", theOffset,
			theValue);
	}
#endif
	*ptr = theValue;
	PSII_SYNC ();
}

/**
 * Sets the indicated bits in the indicated register.
 * @param theOffset [IN] the register to access.
 * @param theMask   [IN] bits set in theMask will be set in the register.
 */
void PowerSpanSetBits (unsigned int theOffset, unsigned int theMask)
{
	volatile unsigned int *ptr =
		(volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
	unsigned int register_value;

#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("PowerSpanSetBits: offset=%08x mask=%02x\n",
			theOffset, theMask);
	}
#endif
	register_value = *ptr;
	PSII_SYNC ();

	register_value |= theMask;
	*ptr = register_value;
	PSII_SYNC ();
}

/**
 * Clears the indicated bits in the indicated register.
 * @param theOffset [IN] the register to access.
 * @param theMask   [IN] bits set in theMask will be cleared in the register.
 */
void PowerSpanClearBits (unsigned int theOffset, unsigned int theMask)
{
	volatile unsigned int *ptr =
		(volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
	unsigned int register_value;

#ifdef VERBOSITY
	if (gVerbosityLevel > 1) {
		printf ("PowerSpanClearBits: offset=%08x mask=%02x\n",
			theOffset, theMask);
	}
#endif
	register_value = *ptr;
	PSII_SYNC ();

	register_value &= ~theMask;
	*ptr = register_value;
	PSII_SYNC ();
}

/**
 * Configures a slave image on the local bus, based on the parameters and some hardcoded system values.
 * Slave Images are images that cause the PowerSpan II to be a master on the PCI bus.  Thus, they
 *  are outgoing from the standpoint of the local bus.
 * @param theImageIndex    [IN] the PowerSpan II image to set (assumed to be 0-7).
 * @param theBlockSize     [IN] the block size of the image (as used by PowerSpan II: PB_SIx_CTL[BS]).
 * @param theMemIOFlag     [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
 * @param theEndianness    [IN] the endian bits for the image (already shifted, use defines).
 * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
 * @param thePCIBaseAddr   [IN] the PCI address for the image (assumed to be valid with provided block size).
 */
int SetSlaveImage (int theImageIndex, unsigned int theBlockSize,
		   int theMemIOFlag, int theEndianness,
		   unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr)
{
	unsigned int reg_offset = theImageIndex * PB_SLAVE_IMAGE_OFF;
	unsigned int reg_value = 0;

	/* Make sure that the Slave Image is disabled */
	PowerSpanClearBits ((REGS_PB_SLAVE_CSR + reg_offset),
			    PB_SLAVE_CSR_IMG_EN);

	/* Setup the mask required for requested PB Slave Image configuration */
	reg_value = PB_SLAVE_CSR_TA_EN | theEndianness | (theBlockSize << 24);
	if (theMemIOFlag == PB_SLAVE_USE_MEM_IO) {
		reg_value |= PB_SLAVE_CSR_MEM_IO;
	}

	/* hardcoding the following:
	   TA_EN = 1
	   MD_EN = 0
	   MODE  = 0
	   PRKEEP = 0
	   RD_AMT = 0
	 */
	PowerSpanWrite ((REGS_PB_SLAVE_CSR + reg_offset), reg_value);

	/* these values are not checked by software */
	PowerSpanWrite ((REGS_PB_SLAVE_BADDR + reg_offset), theLocalBaseAddr);
	PowerSpanWrite ((REGS_PB_SLAVE_TADDR + reg_offset), thePCIBaseAddr);

	/* Enable the Slave Image */
	PowerSpanSetBits ((REGS_PB_SLAVE_CSR + reg_offset),
			  PB_SLAVE_CSR_IMG_EN);

	return 0;
}

/**
 * Configures a target image on the local bus, based on the parameters and some hardcoded system values.
 * Target Images are used when the PowerSpan II is acting as a target for an access.  Thus, they
 *  are incoming from the standpoint of the local bus.
 * In order to behave better on the host PCI bus, if thePCIBaseAddr is NULL (0x00000000), then the PCI
 *  base address will not be updated; makes sense given that the hosts own memory should be mapped to
 *  PCI address 0x00000000.
 * @param theImageIndex    [IN] the PowerSpan II image to set.
 * @param theBlockSize     [IN] the block size of the image (as used by PowerSpan II: Px_TIx_CTL[BS]).
 * @param theMemIOFlag     [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
 * @param theEndianness    [IN] the endian bits for the image (already shifted, use defines).
 * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
 * @param thePCIBaseAddr   [IN] the PCI address for the image (assumed to be valid with provided block size).
 */
int SetTargetImage (int theImageIndex, unsigned int theBlockSize,
		    int theMemIOFlag, int theEndianness,
		    unsigned int theLocalBaseAddr,
		    unsigned int thePCIBaseAddr)
{
	unsigned int csr_reg_offset = theImageIndex * P1_TGT_IMAGE_OFF;
	unsigned int pci_reg_offset = theImageIndex * P1_BST_OFF;
	unsigned int reg_value = 0;

	/* Make sure that the Slave Image is disabled */
	PowerSpanClearBits ((REGS_P1_TGT_CSR + csr_reg_offset),
			    PB_SLAVE_CSR_IMG_EN);

	/* Setup the mask required for requested PB Slave Image configuration */
	reg_value =
		PX_TGT_CSR_TA_EN | PX_TGT_CSR_BAR_EN | (theBlockSize << 24) |
		PX_TGT_CSR_RTT_READ | PX_TGT_CSR_WTT_WFLUSH | theEndianness;
	if (theMemIOFlag == PX_TGT_USE_MEM_IO) {
		reg_value |= PX_TGT_MEM_IO;
	}

	/* hardcoding the following:
	   TA_EN = 1
	   BAR_EN = 1
	   MD_EN = 0
	   MODE  = 0
	   DEST  = 0
	   RTT = 01010
	   GBL = 0
	   CI = 0
	   WTT = 00010
	   PRKEEP = 0
	   MRA = 0
	   RD_AMT = 0
	 */
	PowerSpanWrite ((REGS_P1_TGT_CSR + csr_reg_offset), reg_value);

	PowerSpanWrite ((REGS_P1_TGT_TADDR + csr_reg_offset),
			theLocalBaseAddr);

	if (thePCIBaseAddr != (unsigned int) NULL) {
		PowerSpanWrite ((REGS_P1_BST + pci_reg_offset),
				thePCIBaseAddr);
	}

	/* Enable the Slave Image */
	PowerSpanSetBits ((REGS_P1_TGT_CSR + csr_reg_offset),
			  PB_SLAVE_CSR_IMG_EN);

	return 0;
}

int do_bridge (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	char cmd;
	int ret_val = 1;
	unsigned int image_index;
	unsigned int block_size;
	unsigned int mem_io;
	unsigned int local_addr;
	unsigned int pci_addr;
	int endianness;

	if (argc != 8) {
		goto usage;
	}

	cmd = argv[1][0];
	image_index = simple_strtoul (argv[2], NULL, 16);
	block_size = simple_strtoul (argv[3], NULL, 16);
	mem_io = simple_strtoul (argv[4], NULL, 16);
	endianness = argv[5][0];
	local_addr = simple_strtoul (argv[6], NULL, 16);
	pci_addr = simple_strtoul (argv[7], NULL, 16);


	switch (cmd) {
	case 'i':
		if (tolower (endianness) == 'b') {
			endianness = PX_TGT_CSR_BIG_END;
		} else if (tolower (endianness) == 'l') {
			endianness = PX_TGT_CSR_TRUE_LEND;
		} else {
			goto usage;
		}
		SetTargetImage (image_index, block_size, mem_io,
				endianness, local_addr, pci_addr);
		break;
	case 'o':
		if (tolower (endianness) == 'b') {
			endianness = PB_SLAVE_CSR_BIG_END;
		} else if (tolower (endianness) == 'l') {
			endianness = PB_SLAVE_CSR_TRUE_LEND;
		} else {
			goto usage;
		}
		SetSlaveImage (image_index, block_size, mem_io,
			       endianness, local_addr, pci_addr);
		break;
	default:
		goto usage;
	}

	goto done;
usage:
	printf ("Usage:\n%s\n", cmdtp->help);

done:
	return ret_val;
}
