/*
 * This file is part of the coreboot project.
 *
 * Copyright 2018       Facebook, Inc.
 * Copyright 2003-2017  Cavium Inc.  <support@cavium.com>
 *
 * 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.
 *
 * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
 */

#include <bootmode.h>
#include <console/console.h>
#include <device/device.h>
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <soc/sdram.h>
#include <soc/timer.h>
#include <soc/uart.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <symbols.h>
#include <libbdk-boot/bdk-boot.h>
#include <soc/ecam0.h>
#include <console/uart.h>
#include <libbdk-hal/bdk-pcie.h>
#include <device/pci.h>
#include <libbdk-hal/bdk-qlm.h>
#include <libbdk-hal/bdk-config.h>
#include <libbdk-arch/bdk-csrs-bgx.h>
#include <bootmem.h>
#include <soc/bl31_plat_params.h>
#include <cbfs.h>
#include <cbmem.h>
#include <fit.h>

static const char *QLM_BGX_MODE_MAP[BDK_QLM_MODE_LAST] = {
	[BDK_QLM_MODE_SGMII_4X1]    = "sgmii",
	[BDK_QLM_MODE_SGMII_2X1]    = "sgmii",
	[BDK_QLM_MODE_SGMII_1X1]    = "sgmii",
	[BDK_QLM_MODE_XAUI_1X4]     = "xaui",
	[BDK_QLM_MODE_RXAUI_2X2]    = "rxaui",
	[BDK_QLM_MODE_RXAUI_1X2]    = "rxaui",
	[BDK_QLM_MODE_XFI_4X1]      = "xfi",
	[BDK_QLM_MODE_XFI_2X1]      = "xfi",
	[BDK_QLM_MODE_XFI_1X1]      = "xfi",
	[BDK_QLM_MODE_XLAUI_1X4]    = "xlaui",
	[BDK_QLM_MODE_10G_KR_4X1]   = "xfi-10g-kr",
	[BDK_QLM_MODE_10G_KR_2X1]   = "xfi-10g-kr",
	[BDK_QLM_MODE_10G_KR_1X1]   = "xfi-10g-kr",
	[BDK_QLM_MODE_40G_KR4_1X4]  = "xlaui-40g-kr",
	[BDK_QLM_MODE_QSGMII_4X1]   = "qsgmii",
};

static void dt_platform_fixup_phy(struct device_tree_node *node, char *path,
				  int64_t phy_address, bdk_qlm_modes_t qlm_mode)
{
	const char *data = NULL;
	size_t size = 0;
	dt_find_bin_prop(node, "qlm-mode", (const void **)&data, &size);

	if (!data || strncmp(data, path, 6) != 0)
		return; /* No key prefix match. */
	printk(BIOS_INFO, "%s: Node %s = %s\n", __func__, node->name, data);

	if (strlen(path) == strlen(data) && strcmp(data, path) == 0) {
		/* Keep node, remove "qlm-mode" property */
		dt_delete_prop(node, "qlm-mode");
		printk(BIOS_INFO, "%s: Removing qlm-mode on "
		       "node %s\n", __func__, node->name);
		/* Linux only access the Phy via MDIO.
		Remove 'phy-handle' if this option is not available */
		switch (qlm_mode) {
		case BDK_QLM_MODE_SGMII_4X1:
		case BDK_QLM_MODE_SGMII_2X1:
		case BDK_QLM_MODE_SGMII_1X1:
		case BDK_QLM_MODE_QSGMII_4X1:
			if ((phy_address & BDK_IF_PHY_TYPE_MASK) !=
			    BDK_IF_PHY_MDIO) {
				dt_delete_prop(node, "phy-handle");
				printk(BIOS_INFO, "%s: Removing phy-handle on "
				       "node %s\n", __func__, node->name);
			}
			break;
		default:
			break;
		}
	} else {
		printk(BIOS_INFO, "%s: Removing node %s\n", __func__,
		       node->name);
		/* No match, remove node */
		list_remove(&node->list_node);
	}
}

static void dt_iterate_phy(struct device_tree_node *parent,
				  const char *name,
				  char *path,
				  int64_t phy_address,
				  bdk_qlm_modes_t qlm_mode)
{
	struct device_tree_property *prop;

	/* Check if parent itself has the required property value. */
	list_for_each(prop, parent->properties, list_node) {
		if (!strcmp(name, prop->prop.name)) {
			dt_platform_fixup_phy(parent, path, phy_address,
					      qlm_mode);
		}
	}

	struct device_tree_node *child;
	list_for_each(child, parent->children, list_node) {
		dt_iterate_phy(child, name, path, phy_address, qlm_mode);
	}
}

static void dt_platform_fixup_mac(struct device_tree_node *node)
{
	const char *name = "local-mac-address";
	const u64 *localmac = NULL;
	size_t size = 0;

	dt_find_bin_prop(node, name, (const void **)&localmac, &size);

	if (!localmac)
		return;
	static size_t used_mac;

	/* Extract our MAC address info so we can assign them */
	size_t next_free_mac_address =
		bdk_config_get_int(BDK_CONFIG_MAC_ADDRESS);
	size_t num_free_mac_addresses =
		bdk_config_get_int(BDK_CONFIG_MAC_ADDRESS_NUM);
	size_t num_free_override =
		bdk_config_get_int(BDK_CONFIG_MAC_ADDRESS_NUM_OVERRIDE);
	if (num_free_override != -1)
		num_free_mac_addresses = num_free_override;

	if (size == 6) {
		if (*localmac)
			return;
		if (used_mac < num_free_mac_addresses) {
			const u64 genmac = next_free_mac_address + used_mac;
			dt_add_bin_prop(node, name, &genmac, 6);
			used_mac++;
			return;
		}
	}

	printk(BIOS_INFO, "%s: Removing node %s\n", __func__, node->name);
	list_remove(&node->list_node);
}

static void dt_iterate_mac(struct device_tree_node *parent)
{
	struct device_tree_property *prop;
	const char *name = "local-mac-address";

	/* Check if parent itself has the required property value. */
	list_for_each(prop, parent->properties, list_node) {
		if (!strcmp(name, prop->prop.name))
			dt_platform_fixup_mac(parent);
	}

	struct device_tree_node *child;
	list_for_each(child, parent->children, list_node) {
		dt_iterate_mac(child);
	}
}

/* Do additional device_tree modifications. */
static int dt_platform_fixup(struct device_tree_fixup *fixup,
			      struct device_tree *tree)
{
	struct device_tree_node *dt_node;
	size_t i;

	/* Set the sclk clock rate. */
	dt_node = dt_find_node_by_path(tree->root, "soc@0/sclk", NULL, NULL, 0);
	if (dt_node) {
		const u32 freq = thunderx_get_io_clock();
		printk(BIOS_INFO, "%s: Set SCLK to %u Hz\n", __func__, freq);
		dt_add_u32_prop(dt_node, "clock-frequency", freq);
	} else
		printk(BIOS_ERR, "%s: Node not found. OS might miss-behave !\n",
		       __func__);

	/* Set refclkuaa clock rate. */
	dt_node = dt_find_node_by_path(tree->root, "soc@0/refclkuaa", NULL,
				       NULL, 0);
	if (dt_node) {
		const u32 freq = uart_platform_refclk();
		printk(BIOS_INFO, "%s: Set REFCLKUAA to %u Hz\n", __func__,
		       freq);
		dt_add_u32_prop(dt_node, "clock-frequency", freq);
	} else
		printk(BIOS_ERR, "%s: Node not found. OS might miss-behave !\n",
		       __func__);

	/* Remove unused UART entries */
	for (i = 0; i < 4; i++) {
		char path[32];
		const uint64_t addr = UAAx_PF_BAR0(i);
		/* Remove the node */
		snprintf(path, sizeof(path), "soc@0/serial@%llx", addr);
		dt_node = dt_find_node_by_path(tree->root, path, NULL, NULL, 0);
		if (!dt_node || uart_is_enabled(i)) {
			printk(BIOS_INFO, "%s: ignoring %s\n", __func__, path);
			continue;
		}
		printk(BIOS_INFO, "%s: Removing node %s\n", __func__, path);
		list_remove(&dt_node->list_node);
	}

	/* Remove unused PEM entries */
	for (i = 0; i < 8; i++) {
		char path[32];
		u32 phandle = 0;
		const uint64_t addr = PEM_PEMX_PF_BAR0(i);
		/* Remove the node */
		snprintf(path, sizeof(path), "soc@0/pci@%llx", addr);
		dt_node = dt_find_node_by_path(tree->root, path, NULL, NULL, 0);
		if (!dt_node || bdk_pcie_is_running(0, i)) {
			printk(BIOS_INFO, "%s: ignoring %s\n", __func__, path);
			continue;
		}
		/* Store the phandle */
		phandle = dt_get_phandle(dt_node);
		printk(BIOS_INFO, "%s: Removing node %s\n", __func__, path);
		list_remove(&dt_node->list_node);

		/* Remove phandle to non existing nodes */
		snprintf(path, sizeof(path), "soc@0/smmu0@%llx", SMMU_PF_BAR0);
		dt_node = dt_find_node_by_path(tree->root, path, NULL, NULL, 0);
		if (!dt_node) {
			printk(BIOS_ERR, "%s: SMMU entry not found\n",
			       __func__);
			continue;
		}
		const u32 *data = NULL;
		size_t size = 0;
		dt_find_bin_prop(dt_node, "mmu-masters", (const void **)&data,
				 &size);
		if (!size) {
			printk(BIOS_ERR, "%s: mmu-masters entry not found\n",
			       __func__);
			continue;
		}

		u32 *data_cleaned = malloc(size);
		if (!data_cleaned)
			continue;

		size_t n = 0;
		/* Remove phandle from mmu-masters list */
		for (size_t j = 0; j < size / (sizeof(u32) * 2); j++)
			if (be32_to_cpu(data[j * 2]) != phandle) {
				data_cleaned[n * 2] = data[j * 2];
				data_cleaned[n * 2 + 1] = data[j * 2 + 1];
				n++;
			}

		dt_add_bin_prop(dt_node, "mmu-masters", data_cleaned,
				n * sizeof(u32) * 2);

		free(data_cleaned);
	}

	/* Remove QLM mode entries */
	size_t bgx_index, bgx_iface;
	for (bgx_iface = 0; bgx_iface < 4; bgx_iface++) {
		for (bgx_index = 0; bgx_index < 4; bgx_index++) {
			char path[32];
			int qlm = bdk_qlm_get_qlm_num(0, BDK_IF_BGX,
						      bgx_iface, bgx_index);
			bdk_qlm_modes_t qlm_mode = (qlm == -1) ?
				BDK_QLM_MODE_DISABLED :
				bdk_qlm_get_mode(0, qlm);

			/* BGXX_CMRX_RX_DMAC_CTL is used to mark ports as
			 * disabled that would otherwise be enabled */
			if (qlm_mode != BDK_QLM_MODE_DISABLED) {
				BDK_CSR_INIT(rx_dmac_ctl, 0,
					BDK_BGXX_CMRX_RX_DMAC_CTL(bgx_iface,
								  bgx_index));
				if (rx_dmac_ctl.u == 0)
					qlm_mode = BDK_QLM_MODE_DISABLED;
			}

			if (qlm_mode == BDK_QLM_MODE_DISABLED)
				snprintf(path, sizeof(path), "0x0%x%x,disabled",
					 bgx_iface, bgx_index);
			else
				snprintf(path, sizeof(path), "0x0%x%x,%s",
					 bgx_iface, bgx_index,
					 QLM_BGX_MODE_MAP[qlm_mode]);

			int64_t phy_address =
			    bdk_config_get_int(BDK_CONFIG_PHY_ADDRESS, 0,
					       bgx_iface, bgx_index);

			dt_iterate_phy(tree->root, "qlm-mode", path,
				       phy_address, qlm_mode);
		}
	}

	/* Set local MAC address */
	dt_iterate_mac(tree->root);

	return 0;
}

extern u8 _sff8104[];
extern u8 _esff8104[];

void bootmem_platform_add_ranges(void)
{
	bootmem_add_range((uintptr_t)_sff8104,
			  ((uintptr_t)_esff8104 - (uintptr_t)_sff8104),
			  BM_MEM_RESERVED);

	/* Scratchpad for ATF SATA quirks */
	bootmem_add_range((sdram_size_mb() - 1) * MiB, 1 * MiB,
			  BM_MEM_RESERVED);
}

static void soc_read_resources(struct device *dev)
{
	// HACK: Don't advertise bootblock romstage CAR region, it's broken...
	ram_resource(dev, 0, 2 * KiB, sdram_size_mb() * KiB - 2 * KiB);
}

static void soc_init_atf(void)
{
	static struct bl31_fdt_param fdt_param = {
		.h = { .type = PARAM_FDT, },
	};

	size_t size = 0;

	void *ptr = cbfs_boot_map_with_leak("sff8104-linux.dtb",
					    CBFS_TYPE_RAW, &size);
	if (ptr)
		memcpy(_sff8104, ptr, size);
	/* Point to devicetree in secure memory */
	fdt_param.fdt_ptr = (uintptr_t)_sff8104;

	register_bl31_param(&fdt_param.h);

	static struct bl31_u64_param cbtable_param = {
		.h = { .type = PARAM_COREBOOT_TABLE, },
	};
	/* Point to coreboot tables */
	cbtable_param.value = (uint64_t)cbmem_find(CBMEM_ID_CBTABLE);
	if (cbtable_param.value)
		register_bl31_param(&cbtable_param.h);
}

static void soc_init(struct device *dev)
{
	/* Init ECAM, MDIO, PEM, PHY, QLM ... */
	bdk_boot();

	if (IS_ENABLED(CONFIG_PAYLOAD_FIT_SUPPORT)) {
		struct device_tree_fixup *dt_fixup;

		dt_fixup = malloc(sizeof(*dt_fixup));
		if (dt_fixup) {
			dt_fixup->fixup = dt_platform_fixup;
			list_insert_after(&dt_fixup->list_node,
					  &device_tree_fixups);
		}
	}

	if (IS_ENABLED(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE))
		soc_init_atf();
}

static void soc_final(struct device *dev)
{
	watchdog_disable(0);
}

static struct device_operations soc_ops = {
	.read_resources   = soc_read_resources,
	.set_resources    = DEVICE_NOOP,
	.enable_resources = DEVICE_NOOP,
	.init             = soc_init,
	.final            = soc_final,
	.scan_bus         = NULL,
};

static void enable_soc_dev(struct device *dev)
{
	if (dev->path.type == DEVICE_PATH_DOMAIN &&
		dev->path.domain.domain == 0) {
		dev->ops = &pci_domain_ops_ecam0;
	} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
		dev->ops = &soc_ops;
	}
}

struct chip_operations soc_cavium_cn81xx_ops = {
	CHIP_NAME("SOC Cavium CN81XX")
	.enable_dev = enable_soc_dev,
};
