/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2010 Advanced Micro Devices, Inc.
 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
 *
 * 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; version 2 of the License.
 *
 * 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.
 */

/* This file contains functions for common utility functions */

/*
 *-----------------------------------------------------------------------------
 *		MODULES USED
 *
 *-----------------------------------------------------------------------------
 */

/*
 *-----------------------------------------------------------------------------
 *		EXPORTED FUNCTIONS
 *
 *-----------------------------------------------------------------------------
 */

static void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
{
	/* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */

	AmdMemPCIRead(loc, pValue);
	*pValue = *pValue >> lowbit;  /* Shift */

	/* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
	if ((highbit-lowbit) != 31)
		*pValue &= (((u32)1 << (highbit-lowbit+1))-1);
}

static void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
{
	u32 temp, mask;

	/* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */

	/* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
	if ((highbit-lowbit) != 31)
		mask = (((u32)1 << (highbit-lowbit+1))-1);
	else
		mask = (u32)0xFFFFFFFF;

	AmdMemPCIRead(loc, &temp);
	temp &= ~(mask << lowbit);
	temp |= (*pValue & mask) << lowbit;
	AmdMemPCIWrite(loc, &temp);
}

/*-----------------------------------------------------------------------------
 * u32 bitTestSet(u32 csMask,u32 tempD)
 *
 * Description:
 *     This routine sets a bit in a u32
 *
 * Parameters:
 *     IN        csMask = Target value in which the bit will be set
 *     IN        tempD     =  Bit that will be set
 *     OUT    value     =  Target value with the bit set
 *-----------------------------------------------------------------------------
 */
static u32 bitTestSet(u32 csMask,u32 tempD)
{
	u32 localTemp;
	/* ASSERT(tempD < 32); */
	localTemp = 1;
	csMask |= localTemp << tempD;
	return csMask;
}

/*-----------------------------------------------------------------------------
 * u32 bitTestReset(u32 csMask,u32 tempD)
 *
 * Description:
 *     This routine re-sets a bit in a u32
 *
 * Parameters:
 *     IN        csMask = Target value in which the bit will be re-set
 *     IN        tempD     =  Bit that will be re-set
 *     OUT    value     =  Target value with the bit re-set
 *-----------------------------------------------------------------------------
 */
static u32 bitTestReset(u32 csMask,u32 tempD)
{
	u32 temp, localTemp;
	/* ASSERT(tempD < 32); */
	localTemp = 1;
	temp = localTemp << tempD;
	temp = ~temp;
	csMask &= temp;
	return csMask;
}

/*-----------------------------------------------------------------------------
 *  u32 get_Bits(DCTStruct *DCTData, u8 DCT, u8 Node, u8 func, u16 offset,
 *                 u8 low, u8 high)
 *
 * Description:
 *     This routine Gets the PCT bits from the specified Node, DCT and PCI address
 *
 * Parameters:
 *   IN  OUT *DCTData - Pointer to buffer with information about each DCT
 *     IN        DCT - DCT number
 *              - 1 indicates DCT 1
 *              - 0 indicates DCT 0
 *              - 2 both DCTs
 *          Node - Node number
 *          Func - PCI Function number
 *          Offset - PCI register number
 *          Low - Low bit of the bit field
 *          High - High bit of the bit field
 *
 *     OUT    value     =  Value read from PCI space
 *-----------------------------------------------------------------------------
 */
static u32 get_Bits(sDCTStruct *pDCTData,
		u8 dct, u8 node, u8 func,
		u16 offset, u8 low, u8 high)
{
	u32 temp;
	uint32_t dword;

	/* ASSERT(node < MAX_NODES); */
	if (dct == BOTH_DCTS)
	{
		/* Registers exist on DCT0 only */
		if (is_fam15h())
		{
			/* Select DCT 0 */
			AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
			dword &= ~0x1;
			AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
		}

		AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
	}
	else
	{
		if (is_fam15h())
		{
			/* Select DCT */
			AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
			dword &= ~0x1;
			dword |= (dct & 0x1);
			AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);

			/* Read from the selected DCT */
			AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
		}
		else
		{
			if (dct == 1)
			{
				/* Read from dct 1 */
				offset += 0x100;
				AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
			}
			else
			{
				/* Read from dct 0 */
				AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
			}
		}
	}
	return temp;
}

/*-----------------------------------------------------------------------------
 *  void set_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func, u16 offset,
 *                u8 low, u8 high, u32 value)
 *
 * Description:
 *     This routine Sets the PCT bits from the specified Node, DCT and PCI address
 *
 * Parameters:
 *   IN  OUT *DCTData - Pointer to buffer with information about each DCT
 *     IN        DCT - DCT number
 *              - 1 indicates DCT 1
 *              - 0 indicates DCT 0
 *              - 2 both DCTs
 *          Node - Node number
 *          Func - PCI Function number
 *          Offset - PCI register number
 *          Low - Low bit of the bit field
 *          High - High bit of the bit field
 *
 *     OUT
 *-----------------------------------------------------------------------------
 */
static void set_Bits(sDCTStruct *pDCTData,
		u8 dct, u8 node, u8 func,
		u16 offset, u8 low, u8 high, u32 value)
{
	u32 temp;
	uint32_t dword;

	temp = value;

	if (dct == BOTH_DCTS)
	{
		/* Registers exist on DCT0 only */
		if (is_fam15h())
		{
			/* Select DCT 0 */
			AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
			dword &= ~0x1;
			AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
		}

		AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
	}
	else
	{
		if (is_fam15h())
		{
			/* Select DCT */
			AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
			dword &= ~0x1;
			dword |= (dct & 0x1);
			AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);

			/* Write to the selected DCT */
			AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
		}
		else
		{
			if (dct == 1)
			{
				/* Write to dct 1 */
				offset += 0x100;
				AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
			}
			else
			{
				/* Write to dct 0 */
				AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
			}
		}
	}
}

/*-------------------------------------------------
 *  u32 get_ADD_DCT_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func,
 *                         u16 offset,u8 low, u8 high)
 *
 * Description:
 *     This routine gets the Additional PCT register from Function 2 by specified
 *   Node, DCT and PCI address
 *
 * Parameters:
 *   IN  OUT *DCTData - Pointer to buffer with information about each DCT
 *     IN        DCT - DCT number
 *              - 1 indicates DCT 1
 *              - 0 indicates DCT 0
 *              - 2 both DCTs
 *          Node - Node number
 *          Func - PCI Function number
 *          Offset - Additional PCI register number
 *          Low - Low bit of the bit field
 *          High - High bit of the bit field
 *
 *     OUT
 *-------------------------------------------------
 */
static u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData,
		u8 dct, u8 node, u8 func,
		u16 offset, u8 low, u8 high)
{
	u32 tempD;
	tempD = offset;
	tempD = bitTestReset(tempD,DctAccessWrite);
	set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
		PCI_MIN_LOW, PCI_MAX_HIGH, offset);
	while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
			DctAccessDone, DctAccessDone)) == 0);
	return (get_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
			low, high));
}

/*-------------------------------------------------
 *  void set_DCT_ADDR_Bits(DCTStruct *DCTData, u8 DCT,u8 Node,u8 func,
 *                         u16 offset,u8 low, u8 high, u32 value)
 *
 * Description:
 *     This routine sets the Additional PCT register from Function 2 by specified
 *   Node, DCT and PCI address
 *
 * Parameters:
 *   IN  OUT *DCTData - Pointer to buffer with information about each DCT
 *     IN        DCT - DCT number
 *              - 1 indicates DCT 1
 *              - 0 indicates DCT 0
 *              - 2 both DCTs
 *          Node - Node number
 *          Func - PCI Function number
 *          Offset - Additional PCI register number
 *          Low - Low bit of the bit field
 *          High - High bit of the bit field
 *
 *     OUT
 *-------------------------------------------------
 */
static void set_DCT_ADDR_Bits(sDCTStruct *pDCTData,
		u8 dct, u8 node, u8 func,
		u16 offset, u8 low, u8 high, u32 value)
{
	u32 tempD;

	set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
		PCI_MIN_LOW, PCI_MAX_HIGH, offset);
	while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
			DctAccessDone, DctAccessDone)) == 0);

	set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
		low, high, value);
	tempD = offset;
	tempD = bitTestSet(tempD,DctAccessWrite);
	set_Bits(pDCTData, dct, node, FUN_DCT,DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
		PCI_MIN_LOW, PCI_MAX_HIGH, tempD);
	while ((get_Bits(pDCTData,dct, pDCTData->NodeId, FUN_DCT,
			DRAM_CONTROLLER_ADD_DATA_OFFSET_REG, DctAccessDone,
			DctAccessDone)) == 0);
}

/*-------------------------------------------------
 * BOOL bitTest(u32 value, u8 bitLoc)
 *
 * Description:
 *     This routine tests the value to determine if the bitLoc is set
 *
 * Parameters:
 *     IN        Value - value to be tested
 *          bitLoc - bit location to be tested
 *     OUT    TRUE - bit is set
 *          FALSE - bit is clear
 *-------------------------------------------------
 */
static BOOL bitTest(u32 value, u8 bitLoc)
{
	u32 tempD, compD;
	tempD = value;
	compD = 0;
	compD = bitTestSet(compD,bitLoc);
	tempD &= compD;
	if (compD == tempD)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
