summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2016-10-05 13:18:20 -0400
committerRalf Baechle <ralf@linux-mips.org>2016-10-06 12:04:04 -0400
commiteed0eabd12ef061821cbfa20d903476e07645320 (patch)
treedabf064a54995ba234fba3bd03d19f5dd07058c4
parentcf2a5e0bb4c66e8c43caf9f1be93a1bd7fd07b17 (diff)
MIPS: generic: Introduce generic DT-based board support
Introduce a "generic" platform, which aims to be board-agnostic by making use of device trees passed by the boot protocol defined in the MIPS UHI (Universal Hosting Interface) specification. Provision is made for supporting boards which use a legacy boot protocol that can't be changed, but adding support for such boards or any others is left to followon patches. Right now the built kernels expect to be loaded to 0x80100000, ie. in kseg0. This is fine for the vast majority of MIPS platforms, but nevertheless it would be good to remove this limitation in the future by mapping the kernel via the TLB such that it can be loaded anywhere & map itself appropriately. Configuration is handled by dynamically generating configs using scripts/kconfig/merge_config.sh, somewhat similar to the way powerpc makes use of it. This allows for variations upon the configuration, eg. differing architecture revisions or subsets of driver support for differing boards, to be handled without having a large number of defconfig files. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14353/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/Kbuild.platforms1
-rw-r--r--arch/mips/Kconfig52
-rw-r--r--arch/mips/Makefile56
-rw-r--r--arch/mips/boot/Makefile11
-rw-r--r--arch/mips/configs/generic/32r1.config2
-rw-r--r--arch/mips/configs/generic/32r2.config3
-rw-r--r--arch/mips/configs/generic/32r6.config2
-rw-r--r--arch/mips/configs/generic/64r1.config4
-rw-r--r--arch/mips/configs/generic/64r2.config5
-rw-r--r--arch/mips/configs/generic/64r6.config4
-rw-r--r--arch/mips/configs/generic/eb.config1
-rw-r--r--arch/mips/configs/generic/el.config1
-rw-r--r--arch/mips/configs/generic/micro32r2.config4
-rw-r--r--arch/mips/configs/generic_defconfig96
-rw-r--r--arch/mips/generic/Kconfig12
-rw-r--r--arch/mips/generic/Makefile13
-rw-r--r--arch/mips/generic/Platform14
-rw-r--r--arch/mips/generic/init.c176
-rw-r--r--arch/mips/generic/irq.c64
-rw-r--r--arch/mips/generic/proc.c29
-rw-r--r--arch/mips/generic/vmlinux.its.S31
-rw-r--r--arch/mips/include/asm/machine.h63
22 files changed, 643 insertions, 1 deletions
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index c5cd63a4b6d5..9c1e8f9f854a 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -11,6 +11,7 @@ platforms += cavium-octeon
11platforms += cobalt 11platforms += cobalt
12platforms += dec 12platforms += dec
13platforms += emma 13platforms += emma
14platforms += generic
14platforms += jazz 15platforms += jazz
15platforms += jz4740 16platforms += jz4740
16platforms += lantiq 17platforms += lantiq
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 235643970517..82b45dc9fa4d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -73,6 +73,57 @@ choice
73 prompt "System type" 73 prompt "System type"
74 default SGI_IP22 74 default SGI_IP22
75 75
76config MIPS_GENERIC
77 bool "Generic board-agnostic MIPS kernel"
78 select BOOT_RAW
79 select BUILTIN_DTB
80 select CEVT_R4K
81 select CLKSRC_MIPS_GIC
82 select COMMON_CLK
83 select CPU_MIPSR2_IRQ_VI
84 select CPU_MIPSR2_IRQ_EI
85 select CSRC_R4K
86 select DMA_PERDEV_COHERENT
87 select HW_HAS_PCI
88 select IRQ_MIPS_CPU
89 select LIBFDT
90 select MIPS_CPU_SCACHE
91 select MIPS_GIC
92 select MIPS_L1_CACHE_SHIFT_7
93 select NO_EXCEPT_FILL
94 select PCI_DRIVERS_GENERIC
95 select PINCTRL
96 select SMP_UP if SMP
97 select SYS_HAS_CPU_MIPS32_R1
98 select SYS_HAS_CPU_MIPS32_R2
99 select SYS_HAS_CPU_MIPS32_R6
100 select SYS_HAS_CPU_MIPS64_R1
101 select SYS_HAS_CPU_MIPS64_R2
102 select SYS_HAS_CPU_MIPS64_R6
103 select SYS_SUPPORTS_32BIT_KERNEL
104 select SYS_SUPPORTS_64BIT_KERNEL
105 select SYS_SUPPORTS_BIG_ENDIAN
106 select SYS_SUPPORTS_HIGHMEM
107 select SYS_SUPPORTS_LITTLE_ENDIAN
108 select SYS_SUPPORTS_MICROMIPS
109 select SYS_SUPPORTS_MIPS_CPS
110 select SYS_SUPPORTS_MIPS16
111 select SYS_SUPPORTS_MULTITHREADING
112 select SYS_SUPPORTS_RELOCATABLE
113 select SYS_SUPPORTS_SMARTMIPS
114 select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
115 select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
116 select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
117 select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
118 select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
119 select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
120 select USE_OF
121 help
122 Select this to build a kernel which aims to support multiple boards,
123 generally using a flattened device tree passed from the bootloader
124 using the boot protocol defined in the UHI (Unified Hosting
125 Interface) specification.
126
76config MIPS_ALCHEMY 127config MIPS_ALCHEMY
77 bool "Alchemy processor based machines" 128 bool "Alchemy processor based machines"
78 select ARCH_PHYS_ADDR_T_64BIT 129 select ARCH_PHYS_ADDR_T_64BIT
@@ -989,6 +1040,7 @@ source "arch/mips/ath79/Kconfig"
989source "arch/mips/bcm47xx/Kconfig" 1040source "arch/mips/bcm47xx/Kconfig"
990source "arch/mips/bcm63xx/Kconfig" 1041source "arch/mips/bcm63xx/Kconfig"
991source "arch/mips/bmips/Kconfig" 1042source "arch/mips/bmips/Kconfig"
1043source "arch/mips/generic/Kconfig"
992source "arch/mips/jazz/Kconfig" 1044source "arch/mips/jazz/Kconfig"
993source "arch/mips/jz4740/Kconfig" 1045source "arch/mips/jz4740/Kconfig"
994source "arch/mips/lantiq/Kconfig" 1046source "arch/mips/lantiq/Kconfig"
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 691a6e125879..f3e768a69a52 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -264,6 +264,12 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
264bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ 264bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \
265 VMLINUX_ENTRY_ADDRESS=$(entry-y) \ 265 VMLINUX_ENTRY_ADDRESS=$(entry-y) \
266 PLATFORM=$(platform-y) 266 PLATFORM=$(platform-y)
267ifdef CONFIG_32BIT
268bootvars-y += ADDR_BITS=32
269endif
270ifdef CONFIG_64BIT
271bootvars-y += ADDR_BITS=64
272endif
267 273
268LDFLAGS += -m $(ld-emul) 274LDFLAGS += -m $(ld-emul)
269 275
@@ -431,4 +437,54 @@ define archhelp
431 echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)' 437 echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)'
432 echo 438 echo
433 echo ' These will be default as appropriate for a configured platform.' 439 echo ' These will be default as appropriate for a configured platform.'
440 echo
441 echo ' If you are targeting a system supported by generic kernels you may'
442 echo ' configure the kernel for a given architecture target like so:'
443 echo
444 echo ' {micro32,32,64}{r1,r2,r6}{el,}_defconfig <BOARDS="list of boards">'
445 echo
446 echo ' Otherwise, the following default configurations are available:'
434endef 447endef
448
449generic_config_dir = $(srctree)/arch/$(ARCH)/configs/generic
450generic_defconfigs :=
451
452#
453# If the user generates a generic kernel configuration without specifying a
454# list of boards to include the config fragments for, default to including all
455# available board config fragments.
456#
457ifeq ($(BOARDS),)
458BOARDS = $(patsubst board-%.config,%,$(notdir $(wildcard $(generic_config_dir)/board-*.config)))
459endif
460
461#
462# Generic kernel configurations which merge generic_defconfig with the
463# appropriate config fragments from arch/mips/configs/generic/, resulting in
464# the ability to easily configure the kernel for a given architecture,
465# endianness & set of boards without duplicating the needed configuration in
466# hundreds of defconfig files.
467#
468define gen_generic_defconfigs
469$(foreach bits,$(1),$(foreach rev,$(2),$(foreach endian,$(3),
470target := $(bits)$(rev)$(filter el,$(endian))_defconfig
471generic_defconfigs += $$(target)
472$$(target): $(generic_config_dir)/$(bits)$(rev).config
473$$(target): $(generic_config_dir)/$(endian).config
474)))
475endef
476
477$(eval $(call gen_generic_defconfigs,32 64,r1 r2 r6,eb el))
478$(eval $(call gen_generic_defconfigs,micro32,r2,eb el))
479
480.PHONY: $(generic_defconfigs)
481$(generic_defconfigs):
482 $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \
483 -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \
484 $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config)
485 $(Q)$(MAKE) olddefconfig
486
487#
488# Prevent generic merge_config rules attempting to merge single fragments
489#
490$(generic_config_dir)/%.config: ;
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index ed656636acce..2728a9a9c7c5 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -111,13 +111,22 @@ targets += vmlinux.bz2.itb
111targets += vmlinux.lzma.itb 111targets += vmlinux.lzma.itb
112targets += vmlinux.lzo.itb 112targets += vmlinux.lzo.itb
113 113
114ifeq ($(ADDR_BITS),32)
115 itb_addr_cells = 1
116endif
117ifeq ($(ADDR_BITS),64)
118 itb_addr_cells = 2
119endif
120
114quiet_cmd_cpp_its_S = ITS $@ 121quiet_cmd_cpp_its_S = ITS $@
115 cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ 122 cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \
116 -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ 123 -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \
117 -DVMLINUX_BINARY="\"$(3)\"" \ 124 -DVMLINUX_BINARY="\"$(3)\"" \
118 -DVMLINUX_COMPRESSION="\"$(2)\"" \ 125 -DVMLINUX_COMPRESSION="\"$(2)\"" \
119 -DVMLINUX_LOAD_ADDRESS=$(VMLINUX_LOAD_ADDRESS) \ 126 -DVMLINUX_LOAD_ADDRESS=$(VMLINUX_LOAD_ADDRESS) \
120 -DVMLINUX_ENTRY_ADDRESS=$(VMLINUX_ENTRY_ADDRESS) 127 -DVMLINUX_ENTRY_ADDRESS=$(VMLINUX_ENTRY_ADDRESS) \
128 -DADDR_BITS=$(ADDR_BITS) \
129 -DADDR_CELLS=$(itb_addr_cells)
121 130
122$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE 131$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
123 $(call if_changed_dep,cpp_its_S,none,vmlinux.bin) 132 $(call if_changed_dep,cpp_its_S,none,vmlinux.bin)
diff --git a/arch/mips/configs/generic/32r1.config b/arch/mips/configs/generic/32r1.config
new file mode 100644
index 000000000000..a11cd8715519
--- /dev/null
+++ b/arch/mips/configs/generic/32r1.config
@@ -0,0 +1,2 @@
1CONFIG_CPU_MIPS32_R1=y
2CONFIG_HIGHMEM=y
diff --git a/arch/mips/configs/generic/32r2.config b/arch/mips/configs/generic/32r2.config
new file mode 100644
index 000000000000..9570672d4f9f
--- /dev/null
+++ b/arch/mips/configs/generic/32r2.config
@@ -0,0 +1,3 @@
1CONFIG_CPU_MIPS32_R2=y
2CONFIG_MIPS_O32_FP64_SUPPORT=y
3CONFIG_HIGHMEM=y
diff --git a/arch/mips/configs/generic/32r6.config b/arch/mips/configs/generic/32r6.config
new file mode 100644
index 000000000000..ca606e71f4d0
--- /dev/null
+++ b/arch/mips/configs/generic/32r6.config
@@ -0,0 +1,2 @@
1CONFIG_CPU_MIPS32_R6=y
2CONFIG_HIGHMEM=y
diff --git a/arch/mips/configs/generic/64r1.config b/arch/mips/configs/generic/64r1.config
new file mode 100644
index 000000000000..7c1ea7e7bae3
--- /dev/null
+++ b/arch/mips/configs/generic/64r1.config
@@ -0,0 +1,4 @@
1CONFIG_CPU_MIPS64_R1=y
2CONFIG_64BIT=y
3CONFIG_MIPS32_O32=y
4CONFIG_MIPS32_N32=y
diff --git a/arch/mips/configs/generic/64r2.config b/arch/mips/configs/generic/64r2.config
new file mode 100644
index 000000000000..b4d31ae8bfec
--- /dev/null
+++ b/arch/mips/configs/generic/64r2.config
@@ -0,0 +1,5 @@
1CONFIG_CPU_MIPS64_R2=y
2CONFIG_MIPS_O32_FP64_SUPPORT=y
3CONFIG_64BIT=y
4CONFIG_MIPS32_O32=y
5CONFIG_MIPS32_N32=y
diff --git a/arch/mips/configs/generic/64r6.config b/arch/mips/configs/generic/64r6.config
new file mode 100644
index 000000000000..7cac0339c4d5
--- /dev/null
+++ b/arch/mips/configs/generic/64r6.config
@@ -0,0 +1,4 @@
1CONFIG_CPU_MIPS64_R6=y
2CONFIG_64BIT=y
3CONFIG_MIPS32_O32=y
4CONFIG_MIPS32_N32=y
diff --git a/arch/mips/configs/generic/eb.config b/arch/mips/configs/generic/eb.config
new file mode 100644
index 000000000000..c5cdc99a6530
--- /dev/null
+++ b/arch/mips/configs/generic/eb.config
@@ -0,0 +1 @@
CONFIG_CPU_BIG_ENDIAN=y
diff --git a/arch/mips/configs/generic/el.config b/arch/mips/configs/generic/el.config
new file mode 100644
index 000000000000..ee43fdb3b8f4
--- /dev/null
+++ b/arch/mips/configs/generic/el.config
@@ -0,0 +1 @@
CONFIG_CPU_LITTLE_ENDIAN=y
diff --git a/arch/mips/configs/generic/micro32r2.config b/arch/mips/configs/generic/micro32r2.config
new file mode 100644
index 000000000000..b701fe7aaa68
--- /dev/null
+++ b/arch/mips/configs/generic/micro32r2.config
@@ -0,0 +1,4 @@
1CONFIG_CPU_MIPS32_R2=y
2CONFIG_CPU_MICROMIPS=y
3CONFIG_MIPS_O32_FP64_SUPPORT=y
4CONFIG_HIGHMEM=y
diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig
new file mode 100644
index 000000000000..c95d94c7838b
--- /dev/null
+++ b/arch/mips/configs/generic_defconfig
@@ -0,0 +1,96 @@
1CONFIG_MIPS_GENERIC=y
2CONFIG_CPU_LITTLE_ENDIAN=y
3CONFIG_MIPS_CPS=y
4CONFIG_CPU_HAS_MSA=y
5CONFIG_HIGHMEM=y
6CONFIG_NR_CPUS=2
7CONFIG_MIPS_O32_FP64_SUPPORT=y
8CONFIG_SYSVIPC=y
9CONFIG_NO_HZ_IDLE=y
10CONFIG_IKCONFIG=y
11CONFIG_IKCONFIG_PROC=y
12CONFIG_MEMCG=y
13CONFIG_MEMCG_SWAP=y
14CONFIG_BLK_CGROUP=y
15CONFIG_CFS_BANDWIDTH=y
16CONFIG_RT_GROUP_SCHED=y
17CONFIG_CGROUP_PIDS=y
18CONFIG_CGROUP_FREEZER=y
19CONFIG_CPUSETS=y
20CONFIG_CGROUP_DEVICE=y
21CONFIG_CGROUP_CPUACCT=y
22CONFIG_NAMESPACES=y
23CONFIG_USER_NS=y
24CONFIG_SCHED_AUTOGROUP=y
25CONFIG_BLK_DEV_INITRD=y
26CONFIG_BPF_SYSCALL=y
27CONFIG_USERFAULTFD=y
28CONFIG_EMBEDDED=y
29# CONFIG_SLUB_DEBUG is not set
30# CONFIG_COMPAT_BRK is not set
31CONFIG_CC_STACKPROTECTOR_REGULAR=y
32CONFIG_MODULES=y
33CONFIG_MODULE_UNLOAD=y
34CONFIG_TRIM_UNUSED_KSYMS=y
35CONFIG_NET=y
36CONFIG_PACKET=y
37CONFIG_UNIX=y
38CONFIG_INET=y
39CONFIG_NETFILTER=y
40# CONFIG_WIRELESS is not set
41CONFIG_DEVTMPFS=y
42CONFIG_DEVTMPFS_MOUNT=y
43CONFIG_SCSI=y
44# CONFIG_INPUT_MOUSEDEV is not set
45# CONFIG_INPUT_KEYBOARD is not set
46# CONFIG_INPUT_MOUSE is not set
47# CONFIG_SERIO is not set
48CONFIG_HW_RANDOM=y
49# CONFIG_HWMON is not set
50CONFIG_MFD_SYSCON=y
51CONFIG_HID_A4TECH=y
52CONFIG_HID_APPLE=y
53CONFIG_HID_BELKIN=y
54CONFIG_HID_CHERRY=y
55CONFIG_HID_CHICONY=y
56CONFIG_HID_CYPRESS=y
57CONFIG_HID_EZKEY=y
58CONFIG_HID_KENSINGTON=y
59CONFIG_HID_LOGITECH=y
60CONFIG_HID_MICROSOFT=y
61CONFIG_HID_MONTEREY=y
62# CONFIG_USB_SUPPORT is not set
63# CONFIG_MIPS_PLATFORM_DEVICES is not set
64# CONFIG_IOMMU_SUPPORT is not set
65CONFIG_EXT4_FS=y
66CONFIG_EXT4_FS_POSIX_ACL=y
67CONFIG_EXT4_FS_SECURITY=y
68CONFIG_EXT4_ENCRYPTION=y
69CONFIG_FANOTIFY=y
70CONFIG_FUSE_FS=y
71CONFIG_CUSE=y
72CONFIG_OVERLAY_FS=y
73CONFIG_MSDOS_FS=y
74CONFIG_VFAT_FS=y
75CONFIG_TMPFS=y
76CONFIG_TMPFS_POSIX_ACL=y
77# CONFIG_MISC_FILESYSTEMS is not set
78CONFIG_NFS_FS=y
79CONFIG_NFS_V3_ACL=y
80CONFIG_NFS_V4=y
81CONFIG_NFS_V4_1=y
82CONFIG_NFS_V4_2=y
83CONFIG_PRINTK_TIME=y
84CONFIG_DEBUG_INFO=y
85CONFIG_DEBUG_INFO_REDUCED=y
86CONFIG_DEBUG_FS=y
87# CONFIG_SCHED_DEBUG is not set
88# CONFIG_FTRACE is not set
89CONFIG_CMDLINE_BOOL=y
90CONFIG_CMDLINE="earlycon"
91# CONFIG_XZ_DEC_X86 is not set
92# CONFIG_XZ_DEC_POWERPC is not set
93# CONFIG_XZ_DEC_IA64 is not set
94# CONFIG_XZ_DEC_ARM is not set
95# CONFIG_XZ_DEC_ARMTHUMB is not set
96# CONFIG_XZ_DEC_SPARC is not set
diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig
new file mode 100644
index 000000000000..baddb0646b23
--- /dev/null
+++ b/arch/mips/generic/Kconfig
@@ -0,0 +1,12 @@
1if MIPS_GENERIC
2
3config LEGACY_BOARDS
4 bool
5 help
6 Select this from your board if the board must use a legacy, non-UHI,
7 boot protocol. This will cause the kernel to scan through the list of
8 supported machines calling their detect functions in turn if the
9 kernel is booted without being provided with an FDT via the UHI
10 boot protocol.
11
12endif
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
new file mode 100644
index 000000000000..26e64207f7ad
--- /dev/null
+++ b/arch/mips/generic/Makefile
@@ -0,0 +1,13 @@
1#
2# Copyright (C) 2016 Imagination Technologies
3# Author: Paul Burton <paul.burton@imgtec.com>
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the
7# Free Software Foundation; either version 2 of the License, or (at your
8# option) any later version.
9#
10
11obj-y += init.o
12obj-y += irq.o
13obj-y += proc.o
diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform
new file mode 100644
index 000000000000..9a30d69e2281
--- /dev/null
+++ b/arch/mips/generic/Platform
@@ -0,0 +1,14 @@
1#
2# Copyright (C) 2016 Imagination Technologies
3# Author: Paul Burton <paul.burton@imgtec.com>
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the
7# Free Software Foundation; either version 2 of the License, or (at your
8# option) any later version.
9#
10
11platform-$(CONFIG_MIPS_GENERIC) += generic/
12cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic
13load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000
14all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb
diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c
new file mode 100644
index 000000000000..0ea73e845440
--- /dev/null
+++ b/arch/mips/generic/init.c
@@ -0,0 +1,176 @@
1/*
2 * Copyright (C) 2016 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/clk.h>
12#include <linux/clk-provider.h>
13#include <linux/clocksource.h>
14#include <linux/init.h>
15#include <linux/irqchip.h>
16#include <linux/of_fdt.h>
17#include <linux/of_platform.h>
18
19#include <asm/fw/fw.h>
20#include <asm/irq_cpu.h>
21#include <asm/machine.h>
22#include <asm/mips-cpc.h>
23#include <asm/prom.h>
24#include <asm/smp-ops.h>
25#include <asm/time.h>
26
27static __initdata const void *fdt;
28static __initdata const struct mips_machine *mach;
29static __initdata const void *mach_match_data;
30
31void __init prom_init(void)
32{
33 const struct mips_machine *check_mach;
34 const struct of_device_id *match;
35
36 if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_arg1)) {
37 /*
38 * We booted using the UHI boot protocol, so we have been
39 * provided with the appropriate device tree for the board.
40 * Make use of it & search for any machine struct based upon
41 * the root compatible string.
42 */
43 fdt = (void *)fw_arg1;
44
45 for_each_mips_machine(check_mach) {
46 match = mips_machine_is_compatible(check_mach, fdt);
47 if (match) {
48 mach = check_mach;
49 mach_match_data = match->data;
50 break;
51 }
52 }
53 } else if (IS_ENABLED(CONFIG_LEGACY_BOARDS)) {
54 /*
55 * We weren't booted using the UHI boot protocol, but do
56 * support some number of boards with legacy boot protocols.
57 * Attempt to find the right one.
58 */
59 for_each_mips_machine(check_mach) {
60 if (!check_mach->detect)
61 continue;
62
63 if (!check_mach->detect())
64 continue;
65
66 mach = check_mach;
67 }
68
69 /*
70 * If we don't recognise the machine then we can't continue, so
71 * die here.
72 */
73 BUG_ON(!mach);
74
75 /* Retrieve the machine's FDT */
76 fdt = mach->fdt;
77 }
78
79 BUG_ON(!fdt);
80}
81
82void __init *plat_get_fdt(void)
83{
84 return (void *)fdt;
85}
86
87void __init plat_mem_setup(void)
88{
89 if (mach && mach->fixup_fdt)
90 fdt = mach->fixup_fdt(fdt, mach_match_data);
91
92 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
93 __dt_setup_arch((void *)fdt);
94}
95
96void __init device_tree_init(void)
97{
98 int err;
99
100 unflatten_and_copy_device_tree();
101 mips_cpc_probe();
102
103 err = register_cps_smp_ops();
104 if (err)
105 err = register_up_smp_ops();
106}
107
108void __init plat_time_init(void)
109{
110 struct device_node *np;
111 struct clk *clk;
112
113 of_clk_init(NULL);
114
115 if (!cpu_has_counter) {
116 mips_hpt_frequency = 0;
117 } else if (mach && mach->measure_hpt_freq) {
118 mips_hpt_frequency = mach->measure_hpt_freq();
119 } else {
120 np = of_get_cpu_node(0, NULL);
121 if (!np) {
122 pr_err("Failed to get CPU node\n");
123 return;
124 }
125
126 clk = of_clk_get(np, 0);
127 if (IS_ERR(clk)) {
128 pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
129 return;
130 }
131
132 mips_hpt_frequency = clk_get_rate(clk);
133 clk_put(clk);
134
135 switch (boot_cpu_type()) {
136 case CPU_20KC:
137 case CPU_25KF:
138 /* The counter runs at the CPU clock rate */
139 break;
140 default:
141 /* The counter runs at half the CPU clock rate */
142 mips_hpt_frequency /= 2;
143 break;
144 }
145 }
146
147 clocksource_probe();
148}
149
150void __init arch_init_irq(void)
151{
152 struct device_node *intc_node;
153
154 intc_node = of_find_compatible_node(NULL, NULL,
155 "mti,cpu-interrupt-controller");
156 if (!cpu_has_veic && !intc_node)
157 mips_cpu_irq_init();
158
159 irqchip_init();
160}
161
162static int __init publish_devices(void)
163{
164 if (!of_have_populated_dt())
165 panic("Device-tree not present");
166
167 if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL))
168 panic("Failed to populate DT");
169
170 return 0;
171}
172arch_initcall(publish_devices);
173
174void __init prom_free_prom_memory(void)
175{
176}
diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
new file mode 100644
index 000000000000..14064bdd91dd
--- /dev/null
+++ b/arch/mips/generic/irq.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2016 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/clk.h>
12#include <linux/clk-provider.h>
13#include <linux/clocksource.h>
14#include <linux/init.h>
15#include <linux/irqchip/mips-gic.h>
16#include <linux/types.h>
17
18#include <asm/irq.h>
19
20int get_c0_fdc_int(void)
21{
22 int mips_cpu_fdc_irq;
23
24 if (cpu_has_veic)
25 panic("Unimplemented!");
26 else if (gic_present)
27 mips_cpu_fdc_irq = gic_get_c0_fdc_int();
28 else if (cp0_fdc_irq >= 0)
29 mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
30 else
31 mips_cpu_fdc_irq = -1;
32
33 return mips_cpu_fdc_irq;
34}
35
36int get_c0_perfcount_int(void)
37{
38 int mips_cpu_perf_irq;
39
40 if (cpu_has_veic)
41 panic("Unimplemented!");
42 else if (gic_present)
43 mips_cpu_perf_irq = gic_get_c0_perfcount_int();
44 else if (cp0_perfcount_irq >= 0)
45 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
46 else
47 mips_cpu_perf_irq = -1;
48
49 return mips_cpu_perf_irq;
50}
51
52unsigned int get_c0_compare_int(void)
53{
54 int mips_cpu_timer_irq;
55
56 if (cpu_has_veic)
57 panic("Unimplemented!");
58 else if (gic_present)
59 mips_cpu_timer_irq = gic_get_c0_compare_int();
60 else
61 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
62
63 return mips_cpu_timer_irq;
64}
diff --git a/arch/mips/generic/proc.c b/arch/mips/generic/proc.c
new file mode 100644
index 000000000000..42b33250a4a2
--- /dev/null
+++ b/arch/mips/generic/proc.c
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2016 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/of.h>
12
13#include <asm/bootinfo.h>
14
15const char *get_system_type(void)
16{
17 const char *str;
18 int err;
19
20 err = of_property_read_string(of_root, "model", &str);
21 if (!err)
22 return str;
23
24 err = of_property_read_string_index(of_root, "compatible", 0, &str);
25 if (!err)
26 return str;
27
28 return "Unknown";
29}
diff --git a/arch/mips/generic/vmlinux.its.S b/arch/mips/generic/vmlinux.its.S
new file mode 100644
index 000000000000..f67fbf1c8541
--- /dev/null
+++ b/arch/mips/generic/vmlinux.its.S
@@ -0,0 +1,31 @@
1/dts-v1/;
2
3/ {
4 description = KERNEL_NAME;
5 #address-cells = <ADDR_CELLS>;
6
7 images {
8 kernel@0 {
9 description = KERNEL_NAME;
10 data = /incbin/(VMLINUX_BINARY);
11 type = "kernel";
12 arch = "mips";
13 os = "linux";
14 compression = VMLINUX_COMPRESSION;
15 load = /bits/ ADDR_BITS <VMLINUX_LOAD_ADDRESS>;
16 entry = /bits/ ADDR_BITS <VMLINUX_ENTRY_ADDRESS>;
17 hash@0 {
18 algo = "sha1";
19 };
20 };
21 };
22
23 configurations {
24 default = "conf@default";
25
26 conf@default {
27 description = "Generic Linux kernel";
28 kernel = "kernel@0";
29 };
30 };
31};
diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h
new file mode 100644
index 000000000000..6b444cd9526f
--- /dev/null
+++ b/arch/mips/include/asm/machine.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2016 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __MIPS_ASM_MACHINE_H__
12#define __MIPS_ASM_MACHINE_H__
13
14#include <linux/libfdt.h>
15#include <linux/of.h>
16
17struct mips_machine {
18 const struct of_device_id *matches;
19 const void *fdt;
20 bool (*detect)(void);
21 const void *(*fixup_fdt)(const void *fdt, const void *match_data);
22 unsigned int (*measure_hpt_freq)(void);
23};
24
25extern long __mips_machines_start;
26extern long __mips_machines_end;
27
28#define MIPS_MACHINE(name) \
29 static const struct mips_machine __mips_mach_##name \
30 __used __section(.mips.machines.init)
31
32#define for_each_mips_machine(mach) \
33 for ((mach) = (struct mips_machine *)&__mips_machines_start; \
34 (mach) < (struct mips_machine *)&__mips_machines_end; \
35 (mach)++)
36
37/**
38 * mips_machine_is_compatible() - check if a machine is compatible with an FDT
39 * @mach: the machine struct to check
40 * @fdt: the FDT to check for compatibility with
41 *
42 * Check whether the given machine @mach is compatible with the given flattened
43 * device tree @fdt, based upon the compatibility property of the root node.
44 *
45 * Return: the device id matched if any, else NULL
46 */
47static inline const struct of_device_id *
48mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt)
49{
50 const struct of_device_id *match;
51
52 if (!mach->matches)
53 return NULL;
54
55 for (match = mach->matches; match->compatible; match++) {
56 if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0)
57 return match;
58 }
59
60 return NULL;
61}
62
63#endif /* __MIPS_ASM_MACHINE_H__ */