xref: /openbmc/linux/arch/mips/lantiq/prom.c (revision 7d7ae873b5e0f46d19e5dc818d1a7809e4b7cc81)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2171bb2f1SJohn Crispin /*
3171bb2f1SJohn Crispin  *
497b92108SJohn Crispin  * Copyright (C) 2010 John Crispin <john@phrozen.org>
5171bb2f1SJohn Crispin  */
6171bb2f1SJohn Crispin 
74af92e7aSJohn Crispin #include <linux/export.h>
8171bb2f1SJohn Crispin #include <linux/clk.h>
957c8a661SMike Rapoport #include <linux/memblock.h>
10a9188bc1SJohn Crispin #include <linux/of_fdt.h>
11a9188bc1SJohn Crispin 
12171bb2f1SJohn Crispin #include <asm/bootinfo.h>
13171bb2f1SJohn Crispin #include <asm/time.h>
14089a49b6SRob Herring #include <asm/prom.h>
15171bb2f1SJohn Crispin 
16171bb2f1SJohn Crispin #include <lantiq.h>
17171bb2f1SJohn Crispin 
18171bb2f1SJohn Crispin #include "prom.h"
19171bb2f1SJohn Crispin #include "clk.h"
20171bb2f1SJohn Crispin 
21a0392222SJohn Crispin /* access to the ebu needs to be locked between different drivers */
22a0392222SJohn Crispin DEFINE_SPINLOCK(ebu_lock);
23a0392222SJohn Crispin EXPORT_SYMBOL_GPL(ebu_lock);
24171bb2f1SJohn Crispin 
25a0392222SJohn Crispin /*
26a0392222SJohn Crispin  * this struct is filled by the soc specific detection code and holds
27a0392222SJohn Crispin  * information about the specific soc type, revision and name
28a0392222SJohn Crispin  */
29a0392222SJohn Crispin static struct ltq_soc_info soc_info;
30171bb2f1SJohn Crispin 
31730320fdSAleksander Jan Bajkowski /*
32730320fdSAleksander Jan Bajkowski  * These structs are used to override vsmp_init_secondary()
33730320fdSAleksander Jan Bajkowski  */
34730320fdSAleksander Jan Bajkowski #if defined(CONFIG_MIPS_MT_SMP)
35730320fdSAleksander Jan Bajkowski extern const struct plat_smp_ops vsmp_smp_ops;
36730320fdSAleksander Jan Bajkowski static struct plat_smp_ops lantiq_smp_ops;
37730320fdSAleksander Jan Bajkowski #endif
38730320fdSAleksander Jan Bajkowski 
get_system_type(void)39171bb2f1SJohn Crispin const char *get_system_type(void)
40171bb2f1SJohn Crispin {
41171bb2f1SJohn Crispin 	return soc_info.sys_type;
42171bb2f1SJohn Crispin }
43171bb2f1SJohn Crispin 
ltq_soc_type(void)44e8b8ca8cSJohn Crispin int ltq_soc_type(void)
45e8b8ca8cSJohn Crispin {
46e8b8ca8cSJohn Crispin 	return soc_info.type;
47e8b8ca8cSJohn Crispin }
48e8b8ca8cSJohn Crispin 
prom_init_cmdline(void)49171bb2f1SJohn Crispin static void __init prom_init_cmdline(void)
50171bb2f1SJohn Crispin {
51171bb2f1SJohn Crispin 	int argc = fw_arg0;
52171bb2f1SJohn Crispin 	char **argv = (char **) KSEG1ADDR(fw_arg1);
53171bb2f1SJohn Crispin 	int i;
54171bb2f1SJohn Crispin 
55730fa039SThomas Langer 	arcs_cmdline[0] = '\0';
56730fa039SThomas Langer 
57171bb2f1SJohn Crispin 	for (i = 0; i < argc; i++) {
58171bb2f1SJohn Crispin 		char *p = (char *) KSEG1ADDR(argv[i]);
59171bb2f1SJohn Crispin 
60730fa039SThomas Langer 		if (CPHYSADDR(p) && *p) {
61171bb2f1SJohn Crispin 			strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
62171bb2f1SJohn Crispin 			strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
63171bb2f1SJohn Crispin 		}
64171bb2f1SJohn Crispin 	}
65171bb2f1SJohn Crispin }
66171bb2f1SJohn Crispin 
plat_mem_setup(void)67a0392222SJohn Crispin void __init plat_mem_setup(void)
68a0392222SJohn Crispin {
6984f47cf4SHauke Mehrtens 	void *dtb;
7084f47cf4SHauke Mehrtens 
71a0392222SJohn Crispin 	ioport_resource.start = IOPORT_RESOURCE_START;
72a0392222SJohn Crispin 	ioport_resource.end = IOPORT_RESOURCE_END;
73a0392222SJohn Crispin 	iomem_resource.start = IOMEM_RESOURCE_START;
74a0392222SJohn Crispin 	iomem_resource.end = IOMEM_RESOURCE_END;
75a0392222SJohn Crispin 
76a0392222SJohn Crispin 	set_io_port_base((unsigned long) KSEG1);
77a0392222SJohn Crispin 
78b83ba0b9SThomas Bogendoerfer 	dtb = get_fdt();
79b83ba0b9SThomas Bogendoerfer 	if (dtb == NULL)
8084f47cf4SHauke Mehrtens 		panic("no dtb found");
8184f47cf4SHauke Mehrtens 
82a0392222SJohn Crispin 	/*
8384f47cf4SHauke Mehrtens 	 * Load the devicetree. This causes the chosen node to be
84a0392222SJohn Crispin 	 * parsed resulting in our memory appearing
85a0392222SJohn Crispin 	 */
8684f47cf4SHauke Mehrtens 	__dt_setup_arch(dtb);
87a0392222SJohn Crispin }
88a0392222SJohn Crispin 
89730320fdSAleksander Jan Bajkowski #if defined(CONFIG_MIPS_MT_SMP)
lantiq_init_secondary(void)90730320fdSAleksander Jan Bajkowski static void lantiq_init_secondary(void)
91730320fdSAleksander Jan Bajkowski {
92730320fdSAleksander Jan Bajkowski 	/*
93730320fdSAleksander Jan Bajkowski 	 * MIPS CPU startup function vsmp_init_secondary() will only
94730320fdSAleksander Jan Bajkowski 	 * enable some of the interrupts for the second CPU/VPE.
95730320fdSAleksander Jan Bajkowski 	 */
96730320fdSAleksander Jan Bajkowski 	set_c0_status(ST0_IM);
97730320fdSAleksander Jan Bajkowski }
98730320fdSAleksander Jan Bajkowski #endif
99730320fdSAleksander Jan Bajkowski 
prom_init(void)100171bb2f1SJohn Crispin void __init prom_init(void)
101171bb2f1SJohn Crispin {
102a0392222SJohn Crispin 	/* call the soc specific detetcion code and get it to fill soc_info */
103171bb2f1SJohn Crispin 	ltq_soc_detect(&soc_info);
104a0392222SJohn Crispin 	snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
105a0392222SJohn Crispin 		soc_info.name, soc_info.rev_type);
106171bb2f1SJohn Crispin 	soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
107171bb2f1SJohn Crispin 	pr_info("SoC: %s\n", soc_info.sys_type);
108171bb2f1SJohn Crispin 	prom_init_cmdline();
109a8d096efSJohn Crispin 
110a8d096efSJohn Crispin #if defined(CONFIG_MIPS_MT_SMP)
111730320fdSAleksander Jan Bajkowski 	lantiq_smp_ops = vsmp_smp_ops;
112*d21fbe29SAleksander Jan Bajkowski 	if (cpu_has_mipsmt)
113730320fdSAleksander Jan Bajkowski 		lantiq_smp_ops.init_secondary = lantiq_init_secondary;
114730320fdSAleksander Jan Bajkowski 	register_smp_ops(&lantiq_smp_ops);
115a8d096efSJohn Crispin #endif
116171bb2f1SJohn Crispin }
117