/**
 * @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,
	    "eeprom  - read/write/copy to/from the PowerSpan II eeprom\n",
	    "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\n");

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;
}
