/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2011 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "AGESA.h"
#include "amdlib.h"
#include "Ids.h"
#include "heapManager.h"
#include "PlatformGnbPcieComplex.h"
#include "Filecode.h"

#define FILECODE PROC_RECOVERY_MEM_NB_ON_MRNON_FILECODE

/*---------------------------------------------------------------------------------------*/
/**
 *	OemCustomizeInitEarly
 *
 *	Description:
 *	This stub function will call the host environment through the binary block
 *	interface (call-out port) to provide a user hook opportunity
 *
 *	Parameters:
 *	@param[in]		**PeiServices
 *	@param[in]		*InitEarly
 *
 *	@retval		 VOID
 *
 **/
/*---------------------------------------------------------------------------------------*/
VOID
OemCustomizeInitEarly (
		IN	OUT AMD_EARLY_PARAMS	*InitEarly
		)
{
	AGESA_STATUS		 Status;
	VOID				 *BrazosPcieComplexListPtr;
	VOID				 *BrazosPciePortPtr;
	VOID				 *BrazosPcieDdiPtr;

	ALLOCATE_HEAP_PARAMS AllocHeapParams;

	PCIe_PORT_DESCRIPTOR PortList [] = {
		// Initialize Port descriptor (PCIe port, Lanes 4, PCI Device Number 4, ...) MXM
		{
			0, //Descriptor flags  !!!IMPORTANT!!! Terminate last element of array
			PCIE_ENGINE_DATA_INITIALIZER (PciePortEngine, 4, 5),
			PCIE_PORT_DATA_INITIALIZER (GNB_GPP_PORT4_PORT_PRESENT, GNB_GPP_PORT4_CHANNEL_TYPE, 4, GNB_GPP_PORT4_HOTPLUG_SUPPORT, GNB_GPP_PORT4_SPEED_MODE, GNB_GPP_PORT4_SPEED_MODE, GNB_GPP_PORT4_LINK_ASPM, 4)
		},
		// Initialize Port descriptor (PCIe port, Lanes 6, PCI Device Number 6, ...) PCIE LAN
		{
			0, //Descriptor flags  !!!IMPORTANT!!! Terminate last element of array
			PCIE_ENGINE_DATA_INITIALIZER (PciePortEngine, 6, 6),
			PCIE_PORT_DATA_INITIALIZER (GNB_GPP_PORT6_PORT_PRESENT, GNB_GPP_PORT6_CHANNEL_TYPE, 6, GNB_GPP_PORT6_HOTPLUG_SUPPORT, GNB_GPP_PORT6_SPEED_MODE, GNB_GPP_PORT6_SPEED_MODE, GNB_GPP_PORT6_LINK_ASPM, 6)
		},
		// Initialize Port descriptor (PCIe port, Lanes 7, PCI Device Number 7, ...) MINIPCIE SLOT1
		{
			0,
			PCIE_ENGINE_DATA_INITIALIZER (PciePortEngine, 7, 7),
			PCIE_PORT_DATA_INITIALIZER (GNB_GPP_PORT7_PORT_PRESENT, GNB_GPP_PORT7_CHANNEL_TYPE, 7, GNB_GPP_PORT7_HOTPLUG_SUPPORT, GNB_GPP_PORT7_SPEED_MODE, GNB_GPP_PORT7_SPEED_MODE, GNB_GPP_PORT7_LINK_ASPM, 7)
		},
		// Initialize Port descriptor (PCIe port, Lanes 8, PCI Device Number 8, ...)
		{
			DESCRIPTOR_TERMINATE_LIST, //Descriptor flags  !!!IMPORTANT!!! Terminate last element of array
			PCIE_ENGINE_DATA_INITIALIZER (PciePortEngine, 0, 3),
			PCIE_PORT_DATA_INITIALIZER (GNB_GPP_PORT8_PORT_PRESENT, GNB_GPP_PORT8_CHANNEL_TYPE, 8, GNB_GPP_PORT8_HOTPLUG_SUPPORT, GNB_GPP_PORT8_SPEED_MODE, GNB_GPP_PORT8_SPEED_MODE, GNB_GPP_PORT8_LINK_ASPM, 0)
		}
	};

	PCIe_DDI_DESCRIPTOR DdiList [] = {
		// Initialize Ddi descriptor (DDI interface Lanes 8:11, DdA, ...) DP0 to LVDS
		{
			0,   //Descriptor flags
			PCIE_ENGINE_DATA_INITIALIZER (PcieDdiEngine, 8, 11),
			PCIE_DDI_DATA_INITIALIZER (ConnectorTypeLvds, Aux1, Hdp1)
		},
		// Initialize Ddi descriptor (DDI interface Lanes 12:15, DdB, ...) DP1 to VGA
		{
			DESCRIPTOR_TERMINATE_LIST, //Descriptor flags  !!!IMPORTANT!!! Terminate last element of array
			PCIE_ENGINE_DATA_INITIALIZER (PcieDdiEngine, 12, 15),
			PCIE_DDI_DATA_INITIALIZER (ConnectorTypeAutoDetect, Aux2, Hdp2)
		}
	};

	PCIe_COMPLEX_DESCRIPTOR Brazos = {
		DESCRIPTOR_TERMINATE_LIST,
		0,
		&PortList[0],
		&DdiList[0]
	};

	// GNB PCIe topology Porting

	//
	// Allocate buffer for PCIe_COMPLEX_DESCRIPTOR , PCIe_PORT_DESCRIPTOR and PCIe_DDI_DESCRIPTOR
	//
	AllocHeapParams.RequestedBufferSize = (sizeof (PCIe_COMPLEX_DESCRIPTOR)  +
			sizeof (PCIe_PORT_DESCRIPTOR) * 5 +
			sizeof (PCIe_DDI_DESCRIPTOR)) * 2;

	AllocHeapParams.BufferHandle = AMD_MEM_MISC_HANDLES_START;
	AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
	Status = HeapAllocateBuffer (&AllocHeapParams, &InitEarly->StdHeader);
	if ( Status!= AGESA_SUCCESS) {
		// Could not allocate buffer for PCIe_COMPLEX_DESCRIPTOR , PCIe_PORT_DESCRIPTOR and PCIe_DDI_DESCRIPTOR
		ASSERT(FALSE);
		return;
	}

	BrazosPcieComplexListPtr  =  (PCIe_COMPLEX_DESCRIPTOR *) AllocHeapParams.BufferPtr;

	AllocHeapParams.BufferPtr += sizeof (PCIe_COMPLEX_DESCRIPTOR);
	BrazosPciePortPtr         =  (PCIe_PORT_DESCRIPTOR *)AllocHeapParams.BufferPtr;

	AllocHeapParams.BufferPtr += sizeof (PCIe_PORT_DESCRIPTOR) * 5;
	BrazosPcieDdiPtr          =  (PCIe_DDI_DESCRIPTOR *) AllocHeapParams.BufferPtr;

	LibAmdMemFill (BrazosPcieComplexListPtr,
			0,
			sizeof (PCIe_COMPLEX_DESCRIPTOR),
			&InitEarly->StdHeader);

	LibAmdMemFill (BrazosPciePortPtr,
			0,
			sizeof (PCIe_PORT_DESCRIPTOR) * 5,
			&InitEarly->StdHeader);

	LibAmdMemFill (BrazosPcieDdiPtr,
			0,
			sizeof (PCIe_DDI_DESCRIPTOR) * 2,
			&InitEarly->StdHeader);

	LibAmdMemCopy  (BrazosPcieComplexListPtr, &Brazos, sizeof (PCIe_COMPLEX_DESCRIPTOR), &InitEarly->StdHeader);
	LibAmdMemCopy  (BrazosPciePortPtr, &PortList[0], sizeof (PCIe_PORT_DESCRIPTOR) * 5, &InitEarly->StdHeader);
	LibAmdMemCopy  (BrazosPcieDdiPtr, &DdiList[0], sizeof (PCIe_DDI_DESCRIPTOR) *2, &InitEarly->StdHeader);


	((PCIe_COMPLEX_DESCRIPTOR*)BrazosPcieComplexListPtr)->PciePortList =  (PCIe_PORT_DESCRIPTOR*)BrazosPciePortPtr;
	((PCIe_COMPLEX_DESCRIPTOR*)BrazosPcieComplexListPtr)->DdiLinkList  =  (PCIe_DDI_DESCRIPTOR*)BrazosPcieDdiPtr;

	InitEarly->GnbConfig.PcieComplexList = BrazosPcieComplexListPtr;
	InitEarly->GnbConfig.PsppPolicy      = 0;
}

