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