summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-04-24 09:04:23 -0400
committerTom Rini <trini@konsulko.com>2019-04-24 09:04:23 -0400
commit3fbd2dce351ab5d40d3244f26bd713caa4f826e2 (patch)
tree4a8e5c2fd2dee4abed674da4ce0312af06f97bc1 /arch
parent8a94262435ca559a5e2dad79f2dc3c130e9047a8 (diff)
parent74a7e0018a97a0e7318c4c7a3b473fd9ebbb5ad1 (diff)
Merge branch '2019-04-22-master-imports'
- Add and enable brcmnand driver on a number of relevant platforms. Also add and enable LED drivers on more bcm platforms. - Various ARMv8 fixes/improvements, including extending PSCI functionality. - fs_loader improvments - Various FIT/SPL improvements - PCI bugfixes - Poplar platform ethernet support - MediaTek MMC improvements - Android boot improvements
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv8/Makefile2
-rw-r--r--arch/arm/cpu/armv8/fwcall.c3
-rw-r--r--arch/arm/cpu/armv8/psci.S46
-rw-r--r--arch/arm/cpu/armv8/u-boot.lds4
-rw-r--r--arch/arm/dts/bcm63158.dtsi20
-rw-r--r--arch/arm/dts/bcm6858.dtsi20
-rw-r--r--arch/arm/dts/bcm963158.dts64
-rw-r--r--arch/arm/dts/bcm968580xref.dts63
-rw-r--r--arch/arm/dts/hi3798cv200-u-boot.dtsi14
-rw-r--r--arch/arm/dts/mt8516-u-boot.dtsi25
-rw-r--r--arch/arm/dts/mt8516.dtsi136
-rw-r--r--arch/arm/include/asm/io.h21
-rw-r--r--arch/arm/include/asm/secure.h31
-rw-r--r--arch/arm/lib/relocate_64.S19
-rw-r--r--arch/arm/mach-mediatek/Kconfig10
-rw-r--r--arch/arm/mach-mediatek/Makefile1
-rw-r--r--arch/arm/mach-mediatek/mt8516/Makefile3
-rw-r--r--arch/arm/mach-mediatek/mt8516/init.c120
-rw-r--r--arch/mips/dts/brcm,bcm6838.dtsi13
-rw-r--r--arch/mips/dts/brcm,bcm968380gerg.dts12
20 files changed, 605 insertions, 22 deletions
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index a5f54330e3..b349b13f49 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -19,7 +19,9 @@ endif
obj-y += cache.o
obj-y += tlb.o
obj-y += transition.o
+ifndef CONFIG_ARMV8_PSCI
obj-y += fwcall.o
+endif
obj-y += cpu-dt.o
obj-$(CONFIG_ARM_SMCCC) += smccc-call.o
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
index 9957c2974b..b0aca1b72a 100644
--- a/arch/arm/cpu/armv8/fwcall.c
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -28,7 +28,6 @@ static void hvc_call(struct pt_regs *args)
"ldr x4, %4\n"
"ldr x5, %5\n"
"ldr x6, %6\n"
- "ldr x7, %7\n"
"hvc #0\n"
"str x0, %0\n"
"str x1, %1\n"
@@ -37,7 +36,7 @@ static void hvc_call(struct pt_regs *args)
: "+m" (args->regs[0]), "+m" (args->regs[1]),
"+m" (args->regs[2]), "+m" (args->regs[3])
: "m" (args->regs[4]), "m" (args->regs[5]),
- "m" (args->regs[6]), "m" (args->regs[7])
+ "m" (args->regs[6])
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
"x16", "x17");
diff --git a/arch/arm/cpu/armv8/psci.S b/arch/arm/cpu/armv8/psci.S
index 358df8fee9..7ffc8dbadb 100644
--- a/arch/arm/cpu/armv8/psci.S
+++ b/arch/arm/cpu/armv8/psci.S
@@ -8,6 +8,7 @@
#include <config.h>
#include <linux/linkage.h>
#include <asm/psci.h>
+#include <asm/secure.h>
/* Default PSCI function, return -1, Not Implemented */
#define PSCI_DEFAULT(__fn) \
@@ -19,8 +20,8 @@
/* PSCI function and ID table definition*/
#define PSCI_TABLE(__id, __fn) \
- .word __id; \
- .word __fn
+ .quad __id; \
+ .quad __fn
.pushsection ._secure.text, "ax"
@@ -132,33 +133,52 @@ PSCI_TABLE(0, 0)
/* Caller must put PSCI function-ID table base in x9 */
handle_psci:
psci_enter
-1: ldr x10, [x9] /* Load PSCI function table */
- ubfx x11, x10, #32, #32
- ubfx x10, x10, #0, #32
+1: ldr x10, [x9] /* Load PSCI function table */
cbz x10, 3f /* If reach the end, bail out */
cmp x10, x0
b.eq 2f /* PSCI function found */
- add x9, x9, #8 /* If not match, try next entry */
+ add x9, x9, #16 /* If not match, try next entry */
b 1b
-2: blr x11 /* Call PSCI function */
+2: ldr x11, [x9, #8] /* Load PSCI function */
+ blr x11 /* Call PSCI function */
psci_return
3: mov x0, #ARM_PSCI_RET_NI
psci_return
-unknown_smc_id:
- ldr x0, =0xFFFFFFFF
+/*
+ * Handle SiP service functions defined in SiP service function table.
+ * Use DECLARE_SECURE_SVC(_name, _id, _fn) to add platform specific SiP
+ * service function into the SiP service function table.
+ * SiP service function table is located in '._secure_svc_tbl_entries' section,
+ * which is next to '._secure.text' section.
+ */
+handle_svc:
+ adr x9, __secure_svc_tbl_start
+ adr x10, __secure_svc_tbl_end
+ subs x12, x10, x9 /* Get number of entries in table */
+ b.eq 2f /* Make sure SiP function table is not empty */
+ psci_enter
+1: ldr x10, [x9] /* Load SiP function table */
+ ldr x11, [x9, #8]
+ cmp w10, w0
+ b.eq 2b /* SiP service function found */
+ add x9, x9, #SECURE_SVC_TBL_OFFSET /* Move to next entry */
+ subs x12, x12, #SECURE_SVC_TBL_OFFSET
+ b.eq 3b /* If reach the end, bail out */
+ b 1b
+2: ldr x0, =0xFFFFFFFF
eret
handle_smc32:
/* SMC function ID 0x84000000-0x8400001F: 32 bits PSCI */
ldr w9, =0x8400001F
cmp w0, w9
- b.gt unknown_smc_id
+ b.gt handle_svc
ldr w9, =0x84000000
cmp w0, w9
- b.lt unknown_smc_id
+ b.lt handle_svc
adr x9, _psci_32_table
b handle_psci
@@ -171,10 +191,10 @@ handle_smc64:
/* SMC function ID 0xC4000000-0xC400001F: 64 bits PSCI */
ldr x9, =0xC400001F
cmp x0, x9
- b.gt unknown_smc_id
+ b.gt handle_svc
ldr x9, =0xC4000000
cmp x0, x9
- b.lt unknown_smc_id
+ b.lt handle_svc
adr x9, _psci_64_table
b handle_psci
diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
index 53de80f745..2554980595 100644
--- a/arch/arm/cpu/armv8/u-boot.lds
+++ b/arch/arm/cpu/armv8/u-boot.lds
@@ -58,6 +58,10 @@ SECTIONS
AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
{
*(._secure.text)
+ . = ALIGN(8);
+ __secure_svc_tbl_start = .;
+ KEEP(*(._secure_svc_tbl_entries))
+ __secure_svc_tbl_end = .;
}
.secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
diff --git a/arch/arm/dts/bcm63158.dtsi b/arch/arm/dts/bcm63158.dtsi
index 4f41f62738..4b2eaeea2e 100644
--- a/arch/arm/dts/bcm63158.dtsi
+++ b/arch/arm/dts/bcm63158.dtsi
@@ -82,6 +82,13 @@
status = "disabled";
};
+ leds: led-controller@ff800800 {
+ compatible = "brcm,bcm6858-leds";
+ reg = <0x0 0xff800800 0x0 0xe4>;
+
+ status = "disabled";
+ };
+
wdt1: watchdog@ff800480 {
compatible = "brcm,bcm6345-wdt";
reg = <0x0 0xff800480 0x0 0x14>;
@@ -178,5 +185,18 @@
status = "disabled";
};
+
+ nand: nand-controller@ff801800 {
+ compatible = "brcm,nand-bcm63158",
+ "brcm,brcmnand-v5.0",
+ "brcm,brcmnand";
+ reg-names = "nand", "nand-int-base", "nand-cache";
+ reg = <0x0 0xff801800 0x0 0x180>,
+ <0x0 0xff802000 0x0 0x10>,
+ <0x0 0xff801c00 0x0 0x200>;
+ parameter-page-big-endian = <0>;
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/dts/bcm6858.dtsi b/arch/arm/dts/bcm6858.dtsi
index 5d5e64db08..76ba0ea167 100644
--- a/arch/arm/dts/bcm6858.dtsi
+++ b/arch/arm/dts/bcm6858.dtsi
@@ -82,6 +82,13 @@
status = "disabled";
};
+ leds: led-controller@ff800800 {
+ compatible = "brcm,bcm6858-leds";
+ reg = <0x0 0xff800800 0x0 0xe4>;
+
+ status = "disabled";
+ };
+
wdt1: watchdog@ff802780 {
compatible = "brcm,bcm6345-wdt";
reg = <0x0 0xff802780 0x0 0x14>;
@@ -178,5 +185,18 @@
status = "disabled";
};
+
+ nand: nand-controller@ff801800 {
+ compatible = "brcm,nand-bcm6858",
+ "brcm,brcmnand-v5.0",
+ "brcm,brcmnand";
+ reg-names = "nand", "nand-int-base", "nand-cache";
+ reg = <0x0 0xff801800 0x0 0x180>,
+ <0x0 0xff802000 0x0 0x10>,
+ <0x0 0xff801c00 0x0 0x200>;
+ parameter-page-big-endian = <0>;
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/dts/bcm963158.dts b/arch/arm/dts/bcm963158.dts
index b5c825b052..85659440da 100644
--- a/arch/arm/dts/bcm963158.dts
+++ b/arch/arm/dts/bcm963158.dts
@@ -61,3 +61,67 @@
&gpio7 {
status = "okay";
};
+
+&nand {
+ status = "okay";
+ write-protect = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ nandcs@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ brcm,nand-oob-sector-size = <16>;
+ };
+};
+
+&leds {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ brcm,serial-led-en-pol;
+ brcm,serial-led-data-ppol;
+
+ led@16 {
+ reg = <16>;
+ label = "red:dsl2";
+ };
+
+ led@17 {
+ reg = <17>;
+ label = "green:dsl1";
+ };
+
+ led@18 {
+ reg = <18>;
+ label = "green:fxs2";
+ };
+
+ led@19 {
+ reg = <19>;
+ label = "green:fxs1";
+ };
+
+ led@26 {
+ reg = <26>;
+ label = "green:wan1_act";
+ };
+
+ led@27 {
+ reg = <27>;
+ label = "green:wps";
+ };
+
+ led@28 {
+ reg = <28>;
+ active-low;
+ label = "green:aggregate_act";
+ };
+
+ led@29 {
+ reg = <29>;
+ label = "green:aggregate_link";
+ };
+};
diff --git a/arch/arm/dts/bcm968580xref.dts b/arch/arm/dts/bcm968580xref.dts
index 15febb030f..861e9891a7 100644
--- a/arch/arm/dts/bcm968580xref.dts
+++ b/arch/arm/dts/bcm968580xref.dts
@@ -61,3 +61,66 @@
&gpio7 {
status = "okay";
};
+
+&nand {
+ status = "okay";
+ write-protect = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ nandcs@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ brcm,nand-oob-sector-size = <16>;
+ };
+};
+
+&leds {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ brcm,serial-led-en-pol;
+ brcm,serial-led-data-ppol;
+
+ led@2 {
+ reg = <2>;
+ label = "green:inet";
+ };
+
+ led@5 {
+ reg = <5>;
+ label = "red:alarm";
+ };
+
+ led@8 {
+ reg = <8>;
+ label = "green:wlan_link";
+ };
+
+ led@11 {
+ reg = <11>;
+ label = "green:fxs1";
+ };
+
+ led@14 {
+ reg = <14>;
+ label = "green:fxs2";
+ };
+
+ led@15 {
+ reg = <15>;
+ label = "green:usb0";
+ };
+
+ led@16 {
+ reg = <16>;
+ label = "green:usb1";
+ };
+
+ led@17 {
+ reg = <17>;
+ label = "green:wps";
+ };
+};
diff --git a/arch/arm/dts/hi3798cv200-u-boot.dtsi b/arch/arm/dts/hi3798cv200-u-boot.dtsi
index 7844c5208c..2de06d9529 100644
--- a/arch/arm/dts/hi3798cv200-u-boot.dtsi
+++ b/arch/arm/dts/hi3798cv200-u-boot.dtsi
@@ -8,7 +8,15 @@
* (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
*/
+#include <dt-bindings/reset/ti-syscon.h>
+
&soc {
+ rst: reset-controller@8a22000 {
+ compatible = "hisilicon,hi3798cv200-reset";
+ reg = <0x8a22000 0x1000>;
+ #reset-cells = <3>;
+ };
+
usb2: ehci@9890000 {
compatible = "generic-ehci";
reg = <0x9890000 0x100>;
@@ -16,6 +24,12 @@
};
};
+&gmac1 {
+ resets = <&rst 0xcc 9 ASSERT_SET>,
+ <&rst 0xcc 11 ASSERT_SET>,
+ <&rst 0xcc 13 DEASSERT_SET>;
+};
+
&uart0 {
clock = <75000000>;
status = "okay";
diff --git a/arch/arm/dts/mt8516-u-boot.dtsi b/arch/arm/dts/mt8516-u-boot.dtsi
new file mode 100644
index 0000000000..3c0d843f35
--- /dev/null
+++ b/arch/arm/dts/mt8516-u-boot.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2019 BayLibre, SAS
+ * Author: Fabien Parent <fparent@baylibre.com>
+ */
+
+&infracfg {
+ u-boot,dm-pre-reloc;
+};
+
+&topckgen_ {
+ u-boot,dm-pre-reloc;
+};
+
+&topckgen_cg {
+ u-boot,dm-pre-reloc;
+};
+
+&apmixedsys {
+ u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/mt8516.dtsi b/arch/arm/dts/mt8516.dtsi
new file mode 100644
index 0000000000..1c33582086
--- /dev/null
+++ b/arch/arm/dts/mt8516.dtsi
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2019 BayLibre, SAS
+ * Author: Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <dt-bindings/clock/mt8516-clk.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "mediatek,mt8516";
+ interrupt-parent = <&sysirq>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "mediatek,mt8516-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0>;
+ clock-frequency = <1300000000>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x1>;
+ clock-frequency = <1300000000>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x2>;
+ clock-frequency = <1300000000>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x3>;
+ clock-frequency = <1300000000>;
+ };
+ };
+
+ topckgen: clock-controller@10000000 {
+ compatible = "mediatek,mt8516-topckgen";
+ reg = <0x10000000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ topckgen_cg: clock-controller-cg@10000000 {
+ compatible = "mediatek,mt8516-topckgen-cg";
+ reg = <0x10000000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ infracfg: clock-controller@10001000 {
+ compatible = "mediatek,mt8516-infracfg";
+ reg = <0x10001000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ apmixedsys: clock-controller@10018000 {
+ compatible = "mediatek,mt8516-apmixedsys";
+ reg = <0x10018000 0x710>;
+ #clock-cells = <1>;
+ };
+
+ gic: interrupt-controller@10310000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10310000 0x1000>,
+ <0x10320000 0x1000>,
+ <0x10340000 0x2000>,
+ <0x10360000 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ sysirq: interrupt-controller@10200620 {
+ compatible = "mediatek,sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10200620 0x20>;
+ };
+
+ watchdog: watchdog@10007000 {
+ compatible = "mediatek,wdt";
+ reg = <0x10007000 0x1000>;
+ interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_FALLING>;
+ #reset-cells = <1>;
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@10005000 {
+ compatible = "mediatek,mt8516-pinctrl";
+ reg = <0x10005000 0x1000>;
+
+ gpio: gpio-controller {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ mmc0: mmc@11120000 {
+ compatible = "mediatek,mt8516-mmc";
+ reg = <0x11120000 0x1000>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen_cg CLK_TOP_MSDC0>,
+ <&topckgen CLK_TOP_AHB_INFRA_SEL>,
+ <&topckgen_cg CLK_TOP_MSDC0_INFRA>;
+ clock-names = "source", "hclk", "source_cg";
+ status = "disabled";
+ };
+
+ uart0: serial@11005000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11005000 0x1000>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART0_SEL>,
+ <&topckgen_cg CLK_TOP_UART0>;
+ clock-names = "baud","bus";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 12bc7fbe06..e6d27b69f9 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -123,6 +123,27 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define readq(c) ({ u64 __v = __arch_getq(c); __iormb(); __v; })
/*
+ * Relaxed I/O memory access primitives. These follow the Device memory
+ * ordering rules but do not guarantee any ordering relative to Normal memory
+ * accesses.
+ */
+#define readb_relaxed(c) ({ u8 __r = __raw_readb(c); __r; })
+#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
+ __raw_readw(c)); __r; })
+#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
+ __raw_readl(c)); __r; })
+#define readq_relaxed(c) ({ u64 __r = le64_to_cpu((__force __le64) \
+ __raw_readq(c)); __r; })
+
+#define writeb_relaxed(v, c) ((void)__raw_writeb((v), (c)))
+#define writew_relaxed(v, c) ((void)__raw_writew((__force u16) \
+ cpu_to_le16(v), (c)))
+#define writel_relaxed(v, c) ((void)__raw_writel((__force u32) \
+ cpu_to_le32(v), (c)))
+#define writeq_relaxed(v, c) ((void)__raw_writeq((__force u64) \
+ cpu_to_le64(v), (c)))
+
+/*
* The compiler seems to be incapable of optimising constants
* properly. Spell it out to the compiler in some cases.
* These are only valid for small values of "off" (< 1<<12)
diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h
index d23044a1c3..50582c972b 100644
--- a/arch/arm/include/asm/secure.h
+++ b/arch/arm/include/asm/secure.h
@@ -6,6 +6,37 @@
#define __secure __attribute__ ((section ("._secure.text")))
#define __secure_data __attribute__ ((section ("._secure.data")))
+#ifndef __ASSEMBLY__
+
+typedef struct secure_svc_tbl {
+ u32 id;
+#ifdef CONFIG_ARMV8_PSCI
+ u8 pad[4];
+#endif
+ void *func;
+} secure_svc_tbl_t;
+
+/*
+ * Macro to declare a SiP function service in '_secure_svc_tbl_entries' section
+ */
+#define DECLARE_SECURE_SVC(_name, _id, _fn) \
+ static const secure_svc_tbl_t __secure_svc_ ## _name \
+ __attribute__((used, section("._secure_svc_tbl_entries"))) \
+ = { \
+ .id = _id, \
+ .func = _fn }
+
+#else
+
+#ifdef CONFIG_ARMV8_PSCI
+#define SECURE_SVC_TBL_OFFSET 16
+#else
+#define SECURE_SVC_TBL_OFFSET 8
+
+#endif
+
+#endif /* __ASSEMBLY__ */
+
#if defined(CONFIG_ARMV7_SECURE_BASE) || defined(CONFIG_ARMV8_SECURE_BASE)
/*
* Warning, horror ahead.
diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S
index 7603f52774..26d29c5324 100644
--- a/arch/arm/lib/relocate_64.S
+++ b/arch/arm/lib/relocate_64.S
@@ -26,9 +26,10 @@ ENTRY(relocate_code)
/*
* Copy u-boot from flash to RAM
*/
- adr x1, __image_copy_start /* x1 <- Run &__image_copy_start */
- subs x9, x0, x1 /* x8 <- Run to copy offset */
- b.eq relocate_done /* skip relocation */
+ adrp x1, __image_copy_start /* x1 <- address bits [31:12] */
+ add x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
+ subs x9, x0, x1 /* x9 <- Run to copy offset */
+ b.eq relocate_done /* skip relocation */
/*
* Don't ldr x1, __image_copy_start here, since if the code is already
* running at an address other than it was linked to, that instruction
@@ -42,8 +43,10 @@ ENTRY(relocate_code)
ldr x1, _TEXT_BASE /* x1 <- Linked &__image_copy_start */
subs x9, x0, x1 /* x9 <- Link to copy offset */
- adr x1, __image_copy_start /* x1 <- Run &__image_copy_start */
- adr x2, __image_copy_end /* x2 <- Run &__image_copy_end */
+ adrp x1, __image_copy_start /* x1 <- address bits [31:12] */
+ add x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
+ adrp x2, __image_copy_end /* x2 <- address bits [31:12] */
+ add x2, x2, :lo12:__image_copy_end /* x2 <- address bits [11:00] */
copy_loop:
ldp x10, x11, [x1], #16 /* copy from source address [x1] */
stp x10, x11, [x0], #16 /* copy to target address [x0] */
@@ -54,8 +57,10 @@ copy_loop:
/*
* Fix .rela.dyn relocations
*/
- adr x2, __rel_dyn_start /* x2 <- Run &__rel_dyn_start */
- adr x3, __rel_dyn_end /* x3 <- Run &__rel_dyn_end */
+ adrp x2, __rel_dyn_start /* x2 <- address bits [31:12] */
+ add x2, x2, :lo12:__rel_dyn_start /* x2 <- address bits [11:00] */
+ adrp x3, __rel_dyn_end /* x3 <- address bits [31:12] */
+ add x3, x3, :lo12:__rel_dyn_end /* x3 <- address bits [11:00] */
fixloop:
ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */
ldr x4, [x2], #8 /* x4 <- addend */
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index 7a733e95df..b5e91d4a7d 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -31,6 +31,16 @@ config TARGET_MT7629
including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
+config TARGET_MT8516
+ bool "MediaTek MT8516 SoC"
+ select ARM64
+ select ARCH_MISC_INIT
+ help
+ The MediaTek MT8516 is a ARM64-based SoC with a quad-core Cortex-A35.
+ including UART, SPI, USB2.0 and OTG, SD and MMC cards, NAND, PWM,
+ Ethernet, IR TX/RX, I2C, I2S, S/PDIF, and built-in Wi-Fi / Bluetooth combo
+ chip and several DDR3 and DDR4 options.
+
endchoice
source "board/mediatek/mt7623/Kconfig"
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index b5d3a379bc..ea414dc407 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_SPL_BUILD) += spl.o
obj-$(CONFIG_TARGET_MT7623) += mt7623/
obj-$(CONFIG_TARGET_MT7629) += mt7629/
+obj-$(CONFIG_TARGET_MT8516) += mt8516/
diff --git a/arch/arm/mach-mediatek/mt8516/Makefile b/arch/arm/mach-mediatek/mt8516/Makefile
new file mode 100644
index 0000000000..886ab7e4eb
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt8516/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
diff --git a/arch/arm/mach-mediatek/mt8516/init.c b/arch/arm/mach-mediatek/mt8516/init.c
new file mode 100644
index 0000000000..26a215a8b1
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt8516/init.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Copyright (C) 2019 BayLibre, SAS
+ * Author: Fabien Parent <fparent@baylibre.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ram.h>
+#include <asm/arch/misc.h>
+#include <asm/armv8/mmu.h>
+#include <asm/sections.h>
+#include <dm/uclass.h>
+#include <linux/io.h>
+#include <dt-bindings/clock/mt8516-clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define WDOG_SWRST 0x10007014
+#define WDOG_SWRST_KEY 0x1209
+
+int dram_init(void)
+{
+ int ret;
+
+ ret = fdtdec_setup_memory_banksize();
+ if (ret)
+ return ret;
+
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = gd->ram_base;
+ gd->bd->bi_dram[0].size = gd->ram_size;
+
+ return 0;
+}
+
+int mtk_pll_early_init(void)
+{
+ unsigned long pll_rates[] = {
+ [CLK_APMIXED_ARMPLL] = 1300000000,
+ [CLK_APMIXED_MAINPLL] = 1501000000,
+ [CLK_APMIXED_UNIVPLL] = 1248000000,
+ [CLK_APMIXED_MMPLL] = 380000000,
+ };
+ struct udevice *dev;
+ int ret, i;
+
+ ret = uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(mtk_clk_apmixedsys), &dev);
+ if (ret)
+ return ret;
+
+ /* configure default rate then enable apmixedsys */
+ for (i = 0; i < ARRAY_SIZE(pll_rates); i++) {
+ struct clk clk = { .id = i, .dev = dev };
+
+ ret = clk_set_rate(&clk, pll_rates[i]);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&clk);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int mtk_soc_early_init(void)
+{
+ int ret;
+
+ /* initialize early clocks */
+ ret = mtk_pll_early_init();
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+ while (1) {
+ writel(WDOG_SWRST_KEY, WDOG_SWRST);
+ mdelay(5);
+ }
+}
+
+int print_cpuinfo(void)
+{
+ printf("CPU: MediaTek MT8516\n");
+ return 0;
+}
+
+static struct mm_region mt8516_mem_map[] = {
+ {
+ /* DDR */
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x20000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+ }, {
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
+ .size = 0x20000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ 0,
+ }
+};
+struct mm_region *mem_map = mt8516_mem_map;
diff --git a/arch/mips/dts/brcm,bcm6838.dtsi b/arch/mips/dts/brcm,bcm6838.dtsi
index c060802e8a..6676f83b2a 100644
--- a/arch/mips/dts/brcm,bcm6838.dtsi
+++ b/arch/mips/dts/brcm,bcm6838.dtsi
@@ -125,5 +125,18 @@
status = "disabled";
};
+
+ nand: nand-controller@14e02200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm6838",
+ "brcm,brcmnand-v5.0",
+ "brcm,brcmnand";
+ reg-names = "nand", "nand-int-base", "nand-cache";
+ reg = <0x14e02200 0x180>,
+ <0x14e000f0 0x10>,
+ <0x14e02600 0x180>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/mips/dts/brcm,bcm968380gerg.dts b/arch/mips/dts/brcm,bcm968380gerg.dts
index 98471e3894..5a5ac0ea7d 100644
--- a/arch/mips/dts/brcm,bcm968380gerg.dts
+++ b/arch/mips/dts/brcm,bcm968380gerg.dts
@@ -50,3 +50,15 @@
&gpio_mid1 {
status = "okay";
};
+
+&nand {
+ status = "okay";
+
+ nandcs@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ brcm,nand-oob-sector-size = <16>;
+ };
+};