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