18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
58c2ecf20Sopenharmony_ci * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
68c2ecf20Sopenharmony_ci * Copyright (C) 2013 John Crispin <john@phrozen.org>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/io.h>
108c2ecf20Sopenharmony_ci#include <linux/clk.h>
118c2ecf20Sopenharmony_ci#include <linux/export.h>
128c2ecf20Sopenharmony_ci#include <linux/init.h>
138c2ecf20Sopenharmony_ci#include <linux/sizes.h>
148c2ecf20Sopenharmony_ci#include <linux/of_fdt.h>
158c2ecf20Sopenharmony_ci#include <linux/kernel.h>
168c2ecf20Sopenharmony_ci#include <linux/memblock.h>
178c2ecf20Sopenharmony_ci#include <linux/of_platform.h>
188c2ecf20Sopenharmony_ci#include <linux/of_address.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <asm/reboot.h>
218c2ecf20Sopenharmony_ci#include <asm/bootinfo.h>
228c2ecf20Sopenharmony_ci#include <asm/addrspace.h>
238c2ecf20Sopenharmony_ci#include <asm/prom.h>
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include "common.h"
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci__iomem void *rt_sysc_membase;
288c2ecf20Sopenharmony_ci__iomem void *rt_memc_membase;
298c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(rt_sysc_membase);
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci__iomem void *plat_of_remap_node(const char *node)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	struct resource res;
348c2ecf20Sopenharmony_ci	struct device_node *np;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	np = of_find_compatible_node(NULL, NULL, node);
378c2ecf20Sopenharmony_ci	if (!np)
388c2ecf20Sopenharmony_ci		panic("Failed to find %s node", node);
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	if (of_address_to_resource(np, 0, &res))
418c2ecf20Sopenharmony_ci		panic("Failed to get resource for %s", node);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	if (!request_mem_region(res.start,
448c2ecf20Sopenharmony_ci				resource_size(&res),
458c2ecf20Sopenharmony_ci				res.name))
468c2ecf20Sopenharmony_ci		panic("Failed to request resources for %s", node);
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	return ioremap(res.start, resource_size(&res));
498c2ecf20Sopenharmony_ci}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_civoid __init device_tree_init(void)
528c2ecf20Sopenharmony_ci{
538c2ecf20Sopenharmony_ci	unflatten_and_copy_device_tree();
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic int memory_dtb;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic int __init early_init_dt_find_memory(unsigned long node,
598c2ecf20Sopenharmony_ci				const char *uname, int depth, void *data)
608c2ecf20Sopenharmony_ci{
618c2ecf20Sopenharmony_ci	if (depth == 1 && !strcmp(uname, "memory@0"))
628c2ecf20Sopenharmony_ci		memory_dtb = 1;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	return 0;
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_civoid __init plat_mem_setup(void)
688c2ecf20Sopenharmony_ci{
698c2ecf20Sopenharmony_ci	void *dtb = NULL;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	set_io_port_base(KSEG1);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	/*
748c2ecf20Sopenharmony_ci	 * Load the builtin devicetree. This causes the chosen node to be
758c2ecf20Sopenharmony_ci	 * parsed resulting in our memory appearing. fw_passed_dtb is used
768c2ecf20Sopenharmony_ci	 * by CONFIG_MIPS_APPENDED_RAW_DTB as well.
778c2ecf20Sopenharmony_ci	 */
788c2ecf20Sopenharmony_ci	if (fw_passed_dtb)
798c2ecf20Sopenharmony_ci		dtb = (void *)fw_passed_dtb;
808c2ecf20Sopenharmony_ci	else if (&__dtb_start != &__dtb_end)
818c2ecf20Sopenharmony_ci		dtb = (void *)__dtb_start;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	__dt_setup_arch(dtb);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	of_scan_flat_dt(early_init_dt_find_memory, NULL);
868c2ecf20Sopenharmony_ci	if (memory_dtb)
878c2ecf20Sopenharmony_ci		of_scan_flat_dt(early_init_dt_scan_memory, NULL);
888c2ecf20Sopenharmony_ci	else if (soc_info.mem_size)
898c2ecf20Sopenharmony_ci		memblock_add(soc_info.mem_base, soc_info.mem_size * SZ_1M);
908c2ecf20Sopenharmony_ci	else
918c2ecf20Sopenharmony_ci		detect_memory_region(soc_info.mem_base,
928c2ecf20Sopenharmony_ci				     soc_info.mem_size_min * SZ_1M,
938c2ecf20Sopenharmony_ci				     soc_info.mem_size_max * SZ_1M);
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistatic int __init plat_of_setup(void)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	__dt_register_buses(soc_info.compatible, "palmbus");
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	/* make sure that the reset controller is setup early */
1018c2ecf20Sopenharmony_ci	ralink_rst_init();
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	return 0;
1048c2ecf20Sopenharmony_ci}
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ciarch_initcall(plat_of_setup);
107