18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2010 John Crispin <john@phrozen.org> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/export.h> 88c2ecf20Sopenharmony_ci#include <linux/clk.h> 98c2ecf20Sopenharmony_ci#include <linux/memblock.h> 108c2ecf20Sopenharmony_ci#include <linux/of_fdt.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <asm/bootinfo.h> 138c2ecf20Sopenharmony_ci#include <asm/time.h> 148c2ecf20Sopenharmony_ci#include <asm/prom.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <lantiq.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include "prom.h" 198c2ecf20Sopenharmony_ci#include "clk.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* access to the ebu needs to be locked between different drivers */ 228c2ecf20Sopenharmony_ciDEFINE_SPINLOCK(ebu_lock); 238c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(ebu_lock); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* 268c2ecf20Sopenharmony_ci * this struct is filled by the soc specific detection code and holds 278c2ecf20Sopenharmony_ci * information about the specific soc type, revision and name 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_cistatic struct ltq_soc_info soc_info; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ciconst char *get_system_type(void) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci return soc_info.sys_type; 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ciint ltq_soc_type(void) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci return soc_info.type; 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_civoid __init prom_free_prom_memory(void) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic void __init prom_init_cmdline(void) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci int argc = fw_arg0; 488c2ecf20Sopenharmony_ci char **argv = (char **) KSEG1ADDR(fw_arg1); 498c2ecf20Sopenharmony_ci int i; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci arcs_cmdline[0] = '\0'; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci for (i = 0; i < argc; i++) { 548c2ecf20Sopenharmony_ci char *p = (char *) KSEG1ADDR(argv[i]); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci if (CPHYSADDR(p) && *p) { 578c2ecf20Sopenharmony_ci strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); 588c2ecf20Sopenharmony_ci strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_civoid __init plat_mem_setup(void) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci void *dtb; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci ioport_resource.start = IOPORT_RESOURCE_START; 688c2ecf20Sopenharmony_ci ioport_resource.end = IOPORT_RESOURCE_END; 698c2ecf20Sopenharmony_ci iomem_resource.start = IOMEM_RESOURCE_START; 708c2ecf20Sopenharmony_ci iomem_resource.end = IOMEM_RESOURCE_END; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci set_io_port_base((unsigned long) KSEG1); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci if (fw_passed_dtb) /* UHI interface */ 758c2ecf20Sopenharmony_ci dtb = (void *)fw_passed_dtb; 768c2ecf20Sopenharmony_ci else if (&__dtb_start != &__dtb_end) 778c2ecf20Sopenharmony_ci dtb = (void *)__dtb_start; 788c2ecf20Sopenharmony_ci else 798c2ecf20Sopenharmony_ci panic("no dtb found"); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci /* 828c2ecf20Sopenharmony_ci * Load the devicetree. This causes the chosen node to be 838c2ecf20Sopenharmony_ci * parsed resulting in our memory appearing 848c2ecf20Sopenharmony_ci */ 858c2ecf20Sopenharmony_ci __dt_setup_arch(dtb); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_civoid __init device_tree_init(void) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci unflatten_and_copy_device_tree(); 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_civoid __init prom_init(void) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci /* call the soc specific detetcion code and get it to fill soc_info */ 968c2ecf20Sopenharmony_ci ltq_soc_detect(&soc_info); 978c2ecf20Sopenharmony_ci snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s", 988c2ecf20Sopenharmony_ci soc_info.name, soc_info.rev_type); 998c2ecf20Sopenharmony_ci soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; 1008c2ecf20Sopenharmony_ci pr_info("SoC: %s\n", soc_info.sys_type); 1018c2ecf20Sopenharmony_ci prom_init_cmdline(); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci#if defined(CONFIG_MIPS_MT_SMP) 1048c2ecf20Sopenharmony_ci if (register_vsmp_smp_ops()) 1058c2ecf20Sopenharmony_ci panic("failed to register_vsmp_smp_ops()"); 1068c2ecf20Sopenharmony_ci#endif 1078c2ecf20Sopenharmony_ci} 108