/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
 * Copyright (C) 2007-2008 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.
 */

#include <cpu/x86/msr.h>
#include <console/console.h>
#include <northbridge/amd/amdfam10/amdfam10.h>

#include "ht_wrapper.h"

/*----------------------------------------------------------------------------
 *			TYPEDEFS, DEFINITIONS AND MACROS
 *
 *----------------------------------------------------------------------------
 */

/* Single CPU system? */
#if (CONFIG_MAX_PHYSICAL_CPUS == 1)
	/* FIXME
         * This #define is used by other #included .c files
	 * When set, multiprocessor support is completely disabled
         */
	#define HT_BUILD_NC_ONLY 1
#endif

/* Debugging Options */
#define AMD_DEBUG 1
//#define AMD_DEBUG_ERROR_STOP 1

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

#undef FILECODE
#define FILECODE 0xFF01
#include "comlib.h"
#include "h3gtopo.h"
#include "h3finit.h"

/* include the main HT source file */
#include "h3finit.c"


/*----------------------------------------------------------------------------
 *			LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

/* FIXME: Find a better place for these pre-ram functions. */
#define NODE_HT(x) NODE_PCI(x,0)
#define NODE_MP(x) NODE_PCI(x,1)
#define NODE_MC(x) NODE_PCI(x,3)
#define NODE_LC(x) NODE_PCI(x,4)

static  u32 get_nodes(void)
{
	device_t dev;
	u32 nodes;

	dev = PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0);
	nodes = ((pci_read_config32(dev, 0x60)>>4) & 7) ;
#if CONFIG_MAX_PHYSICAL_CPUS > 8
	nodes += (((pci_read_config32(dev, 0x160)>>4) & 7)<<3);
#endif
	nodes++;

	return nodes;
}

static const char * event_class_string_decodes[] = {
	[HT_EVENT_CLASS_CRITICAL] = "CRITICAL",
	[HT_EVENT_CLASS_ERROR] = "ERROR",
	[HT_EVENT_CLASS_HW_FAULT] = "HARDWARE FAULT",
	[HT_EVENT_CLASS_WARNING] = "WARNING",
	[HT_EVENT_CLASS_INFO] = "INFO"
};

typedef struct {
	uint32_t code;
	const char * string;
} event_string_decode_t;

static const event_string_decode_t event_string_decodes[] = {
	{ HT_EVENT_COH_EVENTS, "HT_EVENT_COH_EVENTS" },
	{ HT_EVENT_COH_NO_TOPOLOGY, "HT_EVENT_COH_NO_TOPOLOGY" },
	{ HT_EVENT_COH_LINK_EXCEED, "HT_EVENT_COH_LINK_EXCEED" },
	{ HT_EVENT_COH_FAMILY_FEUD, "HT_EVENT_COH_FAMILY_FEUD" },
	{ HT_EVENT_COH_NODE_DISCOVERED, "HT_EVENT_COH_NODE_DISCOVERED" },
	{ HT_EVENT_COH_MPCAP_MISMATCH, "HT_EVENT_COH_MPCAP_MISMATCH" },
	{ HT_EVENT_NCOH_EVENTS, "HT_EVENT_NCOH_EVENTS" },
	{ HT_EVENT_NCOH_BUID_EXCEED, "HT_EVENT_NCOH_BUID_EXCEED" },
	{ HT_EVENT_NCOH_LINK_EXCEED, "HT_EVENT_NCOH_LINK_EXCEED" },
	{ HT_EVENT_NCOH_BUS_MAX_EXCEED, "HT_EVENT_NCOH_BUS_MAX_EXCEED" },
	{ HT_EVENT_NCOH_CFG_MAP_EXCEED, "HT_EVENT_NCOH_CFG_MAP_EXCEED" },
	{ HT_EVENT_NCOH_DEVICE_FAILED, "HT_EVENT_NCOH_DEVICE_FAILED" },
	{ HT_EVENT_NCOH_AUTO_DEPTH, "HT_EVENT_NCOH_AUTO_DEPTH" },
	{ HT_EVENT_OPT_EVENTS, "HT_EVENT_OPT_EVENTS" },
	{ HT_EVENT_OPT_REQUIRED_CAP_RETRY, "HT_EVENT_OPT_REQUIRED_CAP_RETRY" },
	{ HT_EVENT_OPT_REQUIRED_CAP_GEN3, "HT_EVENT_OPT_REQUIRED_CAP_GEN3" },
	{ HT_EVENT_HW_EVENTS, "HT_EVENT_HW_EVENTS" },
	{ HT_EVENT_HW_SYNCHFLOOD, "HT_EVENT_HW_SYNCHFLOOD" },
	{ HT_EVENT_HW_HTCRC, "HT_EVENT_HW_HTCRC" }
};

static const char * event_string_decode(uint32_t event) {
	uint32_t i;
	for (i = 0; i < ARRAY_SIZE(event_string_decodes); i++)
		if (event_string_decodes[i].code == event)
			break;
	if (i == ARRAY_SIZE(event_string_decodes))
		return "ERROR: Unmatched event code! "
			"Did you forget to update event_string_decodes[]?";
	return event_string_decodes[i].string;
}

/**
 * void AMD_CB_EventNotify (u8 evtClass, u16 event, const u8 *pEventData0)
 */
static void AMD_CB_EventNotify (u8 evtClass, u16 event, const u8 *pEventData0)
{
	uint8_t i;
	uint8_t log_level;
	uint8_t dump_event_detail;

	printk(BIOS_DEBUG, "AMD_CB_EventNotify(): ");

	/* Decode event */
	dump_event_detail = 1;
	switch (evtClass) {
		case HT_EVENT_CLASS_CRITICAL:
		case HT_EVENT_CLASS_ERROR:
		case HT_EVENT_CLASS_HW_FAULT:
		case HT_EVENT_CLASS_WARNING:
		case HT_EVENT_CLASS_INFO:
			log_level = BIOS_DEBUG;
			printk(log_level, event_class_string_decodes[evtClass]);
			break;
		default:
			log_level = BIOS_DEBUG;
			printk(log_level, "UNKNOWN");
			break;
	}
	printk(log_level, ": ");

	switch(event) {
		case HT_EVENT_COH_EVENTS:
		case HT_EVENT_COH_NO_TOPOLOGY:
		case HT_EVENT_COH_LINK_EXCEED:
		case HT_EVENT_COH_FAMILY_FEUD:
			printk(log_level, event_string_decode(event));
			break;
		case HT_EVENT_COH_NODE_DISCOVERED:
			{
				printk(log_level, "HT_EVENT_COH_NODE_DISCOVERED");
				sHtEventCohNodeDiscovered *evt = (sHtEventCohNodeDiscovered*)pEventData0;
				printk(log_level, ": node %d link %d new node: %d",
					evt->node, evt->link, evt->newNode);
				dump_event_detail = 0;
				break;
			}
		case HT_EVENT_COH_MPCAP_MISMATCH:
		case HT_EVENT_NCOH_EVENTS:
		case HT_EVENT_NCOH_BUID_EXCEED:
		case HT_EVENT_NCOH_LINK_EXCEED:
		case HT_EVENT_NCOH_BUS_MAX_EXCEED:
		case HT_EVENT_NCOH_CFG_MAP_EXCEED:
			printk(log_level, event_string_decode(event));
			break;
		case HT_EVENT_NCOH_DEVICE_FAILED:
			{
				printk(log_level, event_string_decode(event));
				sHtEventNcohDeviceFailed *evt = (sHtEventNcohDeviceFailed*)pEventData0;
				printk(log_level, ": node %d link %d depth: %d attemptedBUID: %d",
					evt->node, evt->link, evt->depth, evt->attemptedBUID);
				dump_event_detail = 0;
				break;
			}
		case HT_EVENT_NCOH_AUTO_DEPTH:
			{
				printk(log_level, event_string_decode(event));
				sHtEventNcohAutoDepth *evt = (sHtEventNcohAutoDepth*)pEventData0;
				printk(log_level, ": node %d link %d depth: %d",
					evt->node, evt->link, evt->depth);
				dump_event_detail = 0;
				break;
			}
		case HT_EVENT_OPT_EVENTS:
		case HT_EVENT_OPT_REQUIRED_CAP_RETRY:
		case HT_EVENT_OPT_REQUIRED_CAP_GEN3:
		case HT_EVENT_HW_EVENTS:
		case HT_EVENT_HW_SYNCHFLOOD:
		case HT_EVENT_HW_HTCRC:
			printk(log_level, event_string_decode(event));
			break;
		default:
			printk(log_level, "HT_EVENT_UNKNOWN");
			break;
	}
	printk(log_level, "\n");

	if (dump_event_detail) {
		printk(BIOS_DEBUG, " event class: %02x\n event: %04x\n data: ", evtClass, event);

		for (i = 0; i < *pEventData0; i++) {
			printk(BIOS_DEBUG, " %02x ", *(pEventData0 + i));
		}
		printk(BIOS_DEBUG, "\n");
	}
}

/**
 * void getAmdTopolist(u8 ***p)
 *
 *  point to the stock topo list array
 *
 */
void getAmdTopolist(u8 ***p)
{
	*p = (u8 **)amd_topo_list;
}

/**
 * BOOL AMD_CB_IgnoreLink(u8 Node, u8 Link)
 * Description:
 *	This routine is used to ignore connected yet faulty HT links,
 *	such as those present in a G34 processor package.
 *
 * Parameters:
 *	@param[in]  node   = The node on which this chain is located
 *	@param[in]  link   = The link on the host for this chain
 */
static BOOL AMD_CB_IgnoreLink (u8 node, u8 link)
{
	return 0;
}

/**
 * void amd_ht_init(struct sys_info *sysinfo)
 *
 *  AMD HT init coreboot wrapper
 *
 */
static void amd_ht_init(struct sys_info *sysinfo)
{

	AMD_HTBLOCK ht_wrapper = {
		NULL,	// u8 **topolist;
		0,	// u8 AutoBusStart;
		32,	// u8 AutoBusMax;
		6,	// u8 AutoBusIncrement;
		AMD_CB_IgnoreLink,		// BOOL (*AMD_CB_IgnoreLink)();
		NULL,	// BOOL (*AMD_CB_OverrideBusNumbers)();
		AMD_CB_ManualBUIDSwapList,	// BOOL (*AMD_CB_ManualBUIDSwapList)();
		NULL,	// void (*AMD_CB_DeviceCapOverride)();
		NULL,	// void (*AMD_CB_Cpu2CpuPCBLimits)();
		NULL,	// void (*AMD_CB_IOPCBLimits)();
		NULL,	// BOOL (*AMD_CB_SkipRegang)();
		NULL,	// BOOL (*AMD_CB_CustomizeTrafficDistribution)();
		NULL,	// BOOL (*AMD_CB_CustomizeBuffers)();
		NULL,	// void (*AMD_CB_OverrideDevicePort)();
		NULL,	// void (*AMD_CB_OverrideCpuPort)();
		AMD_CB_EventNotify,	// void (*AMD_CB_EventNotify) ();
		&sysinfo->ht_link_cfg // struct ht_link_config*
	};

	printk(BIOS_DEBUG, "Enter amd_ht_init()\n");
	amdHtInitialize(&ht_wrapper);
	printk(BIOS_DEBUG, "Exit amd_ht_init()\n");
}

/**
 * void amd_ht_fixup(struct sys_info *sysinfo)
 *
 *  AMD HT fixup
 *
 */
void amd_ht_fixup(struct sys_info *sysinfo) {
	printk(BIOS_DEBUG, "amd_ht_fixup()\n");
	if (IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX)) {
		uint8_t rev_gte_d = 0;
		uint8_t fam15h = 0;
		uint8_t dual_node = 0;
		uint32_t f3xe8;
		uint32_t family;
		uint32_t model;

		family = model = cpuid_eax(0x80000001);
		model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4);
		family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);

		if (family >= 0x6f)
			/* Family 15h or later */
			fam15h = 1;

		if ((model >= 0x8) || fam15h)
			/* Family 10h Revision D or later */
			rev_gte_d = 1;

		if (rev_gte_d) {
			f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8);

			/* Check for dual node capability */
			if (f3xe8 & 0x20000000)
				dual_node = 1;

			if (dual_node) {
				/* Each G34 processor contains a defective HT link.
				* See the Family 10h BKDG Rev 3.62 section 2.7.1.5 for details
				* For Family 15h see the BKDG Rev. 3.14 section 2.12.1.5 for details.
				*/
				uint8_t node;
				uint8_t node_count = get_nodes();
				uint32_t dword;
				for (node = 0; node < node_count; node++) {
					f3xe8 = pci_read_config32(NODE_PCI(node, 3), 0xe8);
					uint8_t internal_node_number = ((f3xe8 & 0xc0000000) >> 30);
					printk(BIOS_DEBUG, "amd_ht_fixup(): node %d (internal node ID %d): disabling defective HT link", node, internal_node_number);
					if (internal_node_number == 0) {
						uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x98:0xd8) & 0x1;
						printk(BIOS_DEBUG, " (L3 connected: %d)\n", package_link_3_connected);
						if (package_link_3_connected) {
							/* Set WidthIn and WidthOut to 0 */
							dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x84:0xc4);
							dword &= ~0x77000000;
							pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x84:0xc4, dword);
							/* Set Ganged to 1 */
							dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x170:0x178);
							dword |= 0x00000001;
							pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x170:0x178, dword);
						} else {
							/* Set ConnDly to 1 */
							dword = pci_read_config32(NODE_PCI(node, 0), 0x16c);
							dword |= 0x00000100;
							pci_write_config32(NODE_PCI(node, 0), 0x16c, dword);
							/* Set TransOff and EndOfChain to 1 */
							dword = pci_read_config32(NODE_PCI(node, 4), (fam15h)?0x84:0xc4);
							dword |= 0x000000c0;
							pci_write_config32(NODE_PCI(node, 4), (fam15h)?0x84:0xc4, dword);
						}
					} else if (internal_node_number == 1) {
						uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0xf8:0xb8) & 0x1;
						printk(BIOS_DEBUG, " (L3 connected: %d)\n", package_link_3_connected);
						if (package_link_3_connected) {
							/* Set WidthIn and WidthOut to 0 */
							dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0xe4:0xa4);
							dword &= ~0x77000000;
							pci_write_config32(NODE_PCI(node, 0), (fam15h)?0xe4:0xa4, dword);
							/* Set Ganged to 1 */
							/* WARNING
							 * The Family 15h BKDG states that 0x18c should be set,
							 * however this is in error.  0x17c is the correct control
							 * register (sublink 0) for these processors...
							 */
							dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x17c:0x174);
							dword |= 0x00000001;
							pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x17c:0x174, dword);
						} else {
							/* Set ConnDly to 1 */
							dword = pci_read_config32(NODE_PCI(node, 0), 0x16c);
							dword |= 0x00000100;
							pci_write_config32(NODE_PCI(node, 0), 0x16c, dword);
							/* Set TransOff and EndOfChain to 1 */
							dword = pci_read_config32(NODE_PCI(node, 4), (fam15h)?0xe4:0xa4);
							dword |= 0x000000c0;
							pci_write_config32(NODE_PCI(node, 4), (fam15h)?0xe4:0xa4, dword);
						}
					}
				}
			}
		}
	}
}
