162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Based on reduced version of METAG
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/init.h>
1062306a36Sopenharmony_ci#include <linux/reboot.h>
1162306a36Sopenharmony_ci#include <linux/memblock.h>
1262306a36Sopenharmony_ci#include <linux/of.h>
1362306a36Sopenharmony_ci#include <linux/of_fdt.h>
1462306a36Sopenharmony_ci#include <asm/mach_desc.h>
1562306a36Sopenharmony_ci#include <asm/serial.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_EARLYCON
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic unsigned int __initdata arc_base_baud;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ciunsigned int __init arc_early_base_baud(void)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	return arc_base_baud/16;
2462306a36Sopenharmony_ci}
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistatic void __init arc_set_early_base_baud(unsigned long dt_root)
2762306a36Sopenharmony_ci{
2862306a36Sopenharmony_ci	if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x"))
2962306a36Sopenharmony_ci		arc_base_baud = 166666666;	/* Fixed 166.6MHz clk (TB10x) */
3062306a36Sopenharmony_ci	else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp") ||
3162306a36Sopenharmony_ci		 of_flat_dt_is_compatible(dt_root, "snps,hsdk"))
3262306a36Sopenharmony_ci		arc_base_baud = 33333333;	/* Fixed 33MHz clk (AXS10x & HSDK) */
3362306a36Sopenharmony_ci	else
3462306a36Sopenharmony_ci		arc_base_baud = 50000000;	/* Fixed default 50MHz */
3562306a36Sopenharmony_ci}
3662306a36Sopenharmony_ci#else
3762306a36Sopenharmony_ci#define arc_set_early_base_baud(dt_root)
3862306a36Sopenharmony_ci#endif
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic const void * __init arch_get_next_mach(const char *const **match)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	static const struct machine_desc *mdesc = __arch_info_begin;
4362306a36Sopenharmony_ci	const struct machine_desc *m = mdesc;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	if (m >= __arch_info_end)
4662306a36Sopenharmony_ci		return NULL;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	mdesc++;
4962306a36Sopenharmony_ci	*match = m->dt_compat;
5062306a36Sopenharmony_ci	return m;
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/**
5462306a36Sopenharmony_ci * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
5562306a36Sopenharmony_ci * @dt:		virtual address pointer to dt blob
5662306a36Sopenharmony_ci *
5762306a36Sopenharmony_ci * If a dtb was passed to the kernel, then use it to choose the correct
5862306a36Sopenharmony_ci * machine_desc and to setup the system.
5962306a36Sopenharmony_ci */
6062306a36Sopenharmony_ciconst struct machine_desc * __init setup_machine_fdt(void *dt)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	const struct machine_desc *mdesc;
6362306a36Sopenharmony_ci	unsigned long dt_root;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	if (!early_init_dt_scan(dt))
6662306a36Sopenharmony_ci		return NULL;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	mdesc = of_flat_dt_match_machine(NULL, arch_get_next_mach);
6962306a36Sopenharmony_ci	if (!mdesc)
7062306a36Sopenharmony_ci		machine_halt();
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	dt_root = of_get_flat_dt_root();
7362306a36Sopenharmony_ci	arc_set_early_base_baud(dt_root);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	return mdesc;
7662306a36Sopenharmony_ci}
77