// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2016 Imagination Technologies
 * Author: Paul Burton <paul.burton@mips.com>
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/irqchip.h>
#include <linux/of_fdt.h>

#include <asm/bootinfo.h>
#include <asm/fw/fw.h>
#include <asm/irq_cpu.h>
#include <asm/machine.h>
#include <asm/mips-cps.h>
#include <asm/prom.h>
#include <asm/smp-ops.h>
#include <asm/time.h>

static __initconst const void *fdt;
static __initconst const struct mips_machine *mach;
static __initconst const void *mach_match_data;

void __init prom_init(void)
{
	plat_get_fdt();
	BUG_ON(!fdt);
}

void __init *plat_get_fdt(void)
{
	const struct mips_machine *check_mach;
	const struct of_device_id *match;

	if (fdt)
		/* Already set up */
		return (void *)fdt;

	if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_passed_dtb)) {
		/*
		 * We booted using the UHI boot protocol, so we have been
		 * provided with the appropriate device tree for the board.
		 * Make use of it & search for any machine struct based upon
		 * the root compatible string.
		 */
		fdt = (void *)fw_passed_dtb;

		for_each_mips_machine(check_mach) {
			match = mips_machine_is_compatible(check_mach, fdt);
			if (match) {
				mach = check_mach;
				mach_match_data = match->data;
				break;
			}
		}
	} else if (IS_ENABLED(CONFIG_LEGACY_BOARDS)) {
		/*
		 * We weren't booted using the UHI boot protocol, but do
		 * support some number of boards with legacy boot protocols.
		 * Attempt to find the right one.
		 */
		for_each_mips_machine(check_mach) {
			if (!check_mach->detect)
				continue;

			if (!check_mach->detect())
				continue;

			mach = check_mach;
		}

		/*
		 * If we don't recognise the machine then we can't continue, so
		 * die here.
		 */
		BUG_ON(!mach);

		/* Retrieve the machine's FDT */
		fdt = mach->fdt;
	}
	return (void *)fdt;
}

#ifdef CONFIG_RELOCATABLE

void __init plat_fdt_relocated(void *new_location)
{
	/*
	 * reset fdt as the cached value would point to the location
	 * before relocations happened and update the location argument
	 * if it was passed using UHI
	 */
	fdt = NULL;

	if (fw_arg0 == -2)
		fw_arg1 = (unsigned long)new_location;
}

#endif /* CONFIG_RELOCATABLE */

void __init plat_mem_setup(void)
{
	if (mach && mach->fixup_fdt)
		fdt = mach->fixup_fdt(fdt, mach_match_data);

	strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
	__dt_setup_arch((void *)fdt);
}

void __init device_tree_init(void)
{
	int err;

	unflatten_and_copy_device_tree();
	mips_cpc_probe();

	err = register_cps_smp_ops();
	if (err)
		err = register_up_smp_ops();
}

int __init apply_mips_fdt_fixups(void *fdt_out, size_t fdt_out_size,
				 const void *fdt_in,
				 const struct mips_fdt_fixup *fixups)
{
	int err;

	err = fdt_open_into(fdt_in, fdt_out, fdt_out_size);
	if (err) {
		pr_err("Failed to open FDT\n");
		return err;
	}

	for (; fixups->apply; fixups++) {
		err = fixups->apply(fdt_out);
		if (err) {
			pr_err("Failed to apply FDT fixup \"%s\"\n",
			       fixups->description);
			return err;
		}
	}

	err = fdt_pack(fdt_out);
	if (err)
		pr_err("Failed to pack FDT\n");
	return err;
}

void __init plat_time_init(void)
{
	struct device_node *np;
	struct clk *clk;

	of_clk_init(NULL);

	if (!cpu_has_counter) {
		mips_hpt_frequency = 0;
	} else if (mach && mach->measure_hpt_freq) {
		mips_hpt_frequency = mach->measure_hpt_freq();
	} else {
		np = of_get_cpu_node(0, NULL);
		if (!np) {
			pr_err("Failed to get CPU node\n");
			return;
		}

		clk = of_clk_get(np, 0);
		if (IS_ERR(clk)) {
			pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
			return;
		}

		mips_hpt_frequency = clk_get_rate(clk);
		clk_put(clk);

		switch (boot_cpu_type()) {
		case CPU_20KC:
		case CPU_25KF:
			/* The counter runs at the CPU clock rate */
			break;
		default:
			/* The counter runs at half the CPU clock rate */
			mips_hpt_frequency /= 2;
			break;
		}
	}

	timer_probe();
}

void __init arch_init_irq(void)
{
	struct device_node *intc_node;

	intc_node = of_find_compatible_node(NULL, NULL,
					    "mti,cpu-interrupt-controller");
	if (!cpu_has_veic && !intc_node)
		mips_cpu_irq_init();
	of_node_put(intc_node);

	irqchip_init();
}

void __init prom_free_prom_memory(void)
{
}
