// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2016-2017 Intel Corporation
 */

#include <altera.h>
#include <common.h>
#include <errno.h>
#include <fdtdec.h>
#include <miiphy.h>
#include <netdev.h>
#include <ns16550.h>
#include <watchdog.h>
#include <asm/arch/misc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/reset_manager_arria10.h>
#include <asm/arch/sdram_arria10.h>
#include <asm/arch/system_manager.h>
#include <asm/arch/nic301.h>
#include <asm/io.h>
#include <asm/pl310.h>

#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3	0x08
#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11	0x58
#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3	0x68
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7	0x18
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7	0x78
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3	0x98

#if defined(CONFIG_SPL_BUILD)
static struct pl310_regs *const pl310 =
	(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base =
	(void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS;
#endif

static struct socfpga_system_manager *sysmgr_regs =
	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;

/*
 * DesignWare Ethernet initialization
 */
#ifdef CONFIG_ETH_DESIGNWARE
static void arria10_dwmac_reset(const u8 of_reset_id, const u8 phymode)
{
	u32 reset;

	if (of_reset_id == EMAC0_RESET) {
		reset = SOCFPGA_RESET(EMAC0);
	} else if (of_reset_id == EMAC1_RESET) {
		reset = SOCFPGA_RESET(EMAC1);
	} else if (of_reset_id == EMAC2_RESET) {
		reset = SOCFPGA_RESET(EMAC2);
	} else {
		printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id);
		return;
	}

	clrsetbits_le32(&sysmgr_regs->emac[of_reset_id - EMAC0_RESET],
			SYSMGR_EMACGRP_CTRL_PHYSEL_MASK,
			phymode);

	/* Release the EMAC controller from reset */
	socfpga_per_reset(reset, 0);
}

static int socfpga_eth_reset(void)
{
	/* Put all GMACs into RESET state. */
	socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1);
	socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1);
	socfpga_per_reset(SOCFPGA_RESET(EMAC2), 1);
	return socfpga_eth_reset_common(arria10_dwmac_reset);
};
#else
static int socfpga_eth_reset(void)
{
	return 0;
};
#endif

#if defined(CONFIG_SPL_BUILD)
/*
+ * This function initializes security policies to be consistent across
+ * all logic units in the Arria 10.
+ *
+ * The idea is to set all security policies to be normal, nonsecure
+ * for all units.
+ */
static void initialize_security_policies(void)
{
	/* Put OCRAM in non-secure */
	writel(0x003f0000, &noc_fw_ocram_base->region0);
	writel(0x1, &noc_fw_ocram_base->enable);

	/* Put DDR in non-secure */
	writel(0xffff0000, SOCFPGA_SDR_FIREWALL_L3_ADDRESS + 0xc);
	writel(0x1, SOCFPGA_SDR_FIREWALL_L3_ADDRESS);

	/* Enable priviledged and non-priviledged access to L4 peripherals */
	writel(~0, SOCFPGA_NOC_L4_PRIV_FLT_OFST);

	/* Enable secure and non-secure transactions to bridges */
	writel(~0, SOCFPGA_NOC_FW_H2F_SCR_OFST);
	writel(~0, SOCFPGA_NOC_FW_H2F_SCR_OFST + 4);

	writel(0x0007FFFF, &sysmgr_regs->ecc_intmask_set);
}

int arch_early_init_r(void)
{
	initialize_security_policies();

	/* Configure the L2 controller to make SDRAM start at 0 */
	writel(0x1, &pl310->pl310_addr_filter_start);

	/* assert reset to all except L4WD0 and L4TIMER0 */
	socfpga_per_reset_all();

	return 0;
}
#else
int arch_early_init_r(void)
{
	return 0;
}
#endif

/*
 * This function looking the 1st encounter UART peripheral,
 * and then return its offset of the dedicated/shared IO pin
 * mux. offset value (zero and above).
 */
static int find_peripheral_uart(const void *blob,
	int child, const char *node_name)
{
	int len;
	fdt_addr_t base_addr = 0;
	fdt_size_t size;
	const u32 *cell;
	u32 value, offset = 0;

	base_addr = fdtdec_get_addr_size(blob, child, "reg", &size);
	if (base_addr != FDT_ADDR_T_NONE) {
		cell = fdt_getprop(blob, child, "pinctrl-single,pins",
			&len);
		if (cell != NULL) {
			for (; len > 0; len -= (2 * sizeof(u32))) {
				offset = fdt32_to_cpu(*cell++);
				value = fdt32_to_cpu(*cell++);
				/* Found UART peripheral. */
				if (value == PINMUX_UART)
					return offset;
			}
		}
	}
	return -EINVAL;
}

/*
 * This function looks up the 1st encounter UART peripheral,
 * and then return its offset of the dedicated/shared IO pin
 * mux. UART peripheral is found if the offset is not in negative
 * value.
 */
static int is_peripheral_uart_true(const void *blob,
	int node, const char *child_name)
{
	int child, len;
	const char *node_name;

	child = fdt_first_subnode(blob, node);

	if (child < 0)
		return -EINVAL;

	node_name = fdt_get_name(blob, child, &len);

	while (node_name) {
		if (!strcmp(child_name, node_name))
			return find_peripheral_uart(blob, child, node_name);

		child = fdt_next_subnode(blob, child);
		if (child < 0)
			break;

		node_name = fdt_get_name(blob, child, &len);
	}

	return -1;
}

/*
 * This function looking the 1st encounter UART dedicated IO peripheral,
 * and then return based address of the 1st encounter UART dedicated
 * IO peripheral.
 */
unsigned int dedicated_uart_com_port(const void *blob)
{
	int node;

	node = fdtdec_next_compatible(blob, 0,
		 COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
	if (node < 0)
		return 0;

	if (is_peripheral_uart_true(blob, node, "dedicated") >= 0)
		return SOCFPGA_UART1_ADDRESS;

	return 0;
}

/*
 * This function looking the 1st encounter UART shared IO peripheral, and then
 * return based address of the 1st encounter UART shared IO peripheral.
 */
unsigned int shared_uart_com_port(const void *blob)
{
	int node, ret;

	node = fdtdec_next_compatible(blob, 0,
		 COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
	if (node < 0)
		return 0;

	ret = is_peripheral_uart_true(blob, node, "shared");

	if (ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 ||
	    ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 ||
	    ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3)
		return SOCFPGA_UART0_ADDRESS;
	else if (ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7 ||
		ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 ||
		ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3)
		return SOCFPGA_UART1_ADDRESS;

	return 0;
}

/*
 * This function looking the 1st encounter UART peripheral, and then return
 * base address of the 1st encounter UART peripheral.
 */
unsigned int uart_com_port(const void *blob)
{
	unsigned int ret;

	ret = dedicated_uart_com_port(blob);

	if (ret)
		return ret;

	return shared_uart_com_port(blob);
}

/*
 * Print CPU information
 */
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
	const u32 bsel =
		SYSMGR_GET_BOOTINFO_BSEL(readl(&sysmgr_regs->bootinfo));

	puts("CPU:   Altera SoCFPGA Arria 10\n");

	printf("BOOT:  %s\n", bsel_str[bsel].name);
	return 0;
}
#endif

#ifdef CONFIG_ARCH_MISC_INIT
int arch_misc_init(void)
{
	return socfpga_eth_reset();
}
#endif

void do_bridge_reset(int enable)
{
	if (enable)
		socfpga_reset_deassert_bridges_handoff();
	else
		socfpga_bridges_reset();
}
