summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-10-31 19:21:12 +0300
committerTom Rini <trini@konsulko.com>2021-10-31 19:21:12 +0300
commit50bff6a6f86669a8652e2bf271eeb04f77911274 (patch)
tree2ab5f207ca3c191e5c1e67f66459d3b4a6f3fb0a
parenta09929cc6c5a108f89e91660f37d745ed119385b (diff)
parent3e2095e960b47a3c0211a3a1e52c74b1761cb0be (diff)
downloadu-boot-50bff6a6f86669a8652e2bf271eeb04f77911274.tar.xz
Merge branch '2021-10-31-assorted-platform-updates'
- Revert GIC LPI changes that need to be reworked. - mvebu SATA booting bugfix - Samsung Galaxy S9/S9+(SM-G96x0), Samsung Galaxy A and Apple M1 platform support.
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/arm/Kconfig25
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/soc.c41
-rw-r--r--arch/arm/dts/Makefile8
-rw-r--r--arch/arm/dts/exynos78x0-axy17lte.dts29
-rw-r--r--arch/arm/dts/exynos78x0-gpio.dtsi204
-rw-r--r--arch/arm/dts/exynos78x0-pinctrl.dtsi280
-rw-r--r--arch/arm/dts/exynos78x0.dtsi98
-rw-r--r--arch/arm/dts/fsl-ls1028a.dtsi6
-rw-r--r--arch/arm/dts/fsl-ls1088a.dtsi6
-rw-r--r--arch/arm/dts/fsl-ls2080a.dtsi6
-rw-r--r--arch/arm/dts/fsl-lx2160a.dtsi6
-rw-r--r--arch/arm/dts/sdm845.dtsi116
-rw-r--r--arch/arm/dts/starqltechn-uboot.dtsi39
-rw-r--r--arch/arm/dts/starqltechn.dts53
-rw-r--r--arch/arm/dts/t8103-j274.dts135
-rw-r--r--arch/arm/dts/t8103-j293.dts97
-rw-r--r--arch/arm/dts/t8103.dtsi560
-rw-r--r--arch/arm/include/asm/arch-m1/uart.h41
-rw-r--r--arch/arm/include/asm/gic-v3.h4
-rw-r--r--arch/arm/lib/gic-v3-its.c66
-rw-r--r--arch/arm/mach-apple/Kconfig18
-rw-r--r--arch/arm/mach-apple/Makefile4
-rw-r--r--arch/arm/mach-apple/board.c162
-rw-r--r--arch/arm/mach-apple/lowlevel_init.S17
-rw-r--r--arch/arm/mach-exynos/Kconfig28
-rw-r--r--arch/arm/mach-exynos/mmu-arm64.c66
-rw-r--r--arch/arm/mach-mvebu/spl.c4
-rw-r--r--arch/arm/mach-snapdragon/Kconfig21
-rw-r--r--arch/arm/mach-snapdragon/Makefile4
-rw-r--r--arch/arm/mach-snapdragon/clock-sdm845.c92
-rw-r--r--arch/arm/mach-snapdragon/clock-snapdragon.c1
-rw-r--r--arch/arm/mach-snapdragon/clock-snapdragon.h3
-rw-r--r--arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h42
-rw-r--r--arch/arm/mach-snapdragon/init_sdm845.c82
-rw-r--r--arch/arm/mach-snapdragon/pinctrl-sdm845.c44
-rw-r--r--arch/arm/mach-snapdragon/pinctrl-snapdragon.c3
-rw-r--r--arch/arm/mach-snapdragon/pinctrl-snapdragon.h1
-rw-r--r--arch/arm/mach-snapdragon/sysmap-sdm845.c31
-rw-r--r--arch/sandbox/dts/test.dts6
-rw-r--r--board/broadcom/bcmns3/ns3.c3
-rw-r--r--board/samsung/axy17lte/Kconfig58
-rw-r--r--board/samsung/axy17lte/MAINTAINERS8
-rw-r--r--board/samsung/axy17lte/Makefile3
-rw-r--r--board/samsung/axy17lte/axy17lte.c11
-rw-r--r--board/samsung/starqltechn/Kconfig22
-rw-r--r--board/samsung/starqltechn/MAINTAINERS6
-rw-r--r--board/samsung/starqltechn/Makefile9
-rw-r--r--board/samsung/starqltechn/starqltechn.c10
-rw-r--r--configs/a3y17lte_defconfig24
-rw-r--r--configs/a5y17lte_defconfig24
-rw-r--r--configs/a7y17lte_defconfig24
-rw-r--r--configs/apple_m1_defconfig20
-rw-r--r--configs/sandbox64_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--configs/sandbox_flattree_defconfig1
-rw-r--r--configs/sandbox_noinst_defconfig1
-rw-r--r--configs/sandbox_spl_defconfig1
-rw-r--r--configs/starqltechn_defconfig24
-rw-r--r--doc/board/apple/index.rst9
-rw-r--r--doc/board/apple/m1.rst59
-rw-r--r--doc/board/index.rst2
-rw-r--r--doc/board/qualcomm/index.rst1
-rw-r--r--doc/board/qualcomm/sdm845.rst38
-rw-r--r--doc/board/samsung/axy17lte.rst94
-rw-r--r--doc/board/samsung/index.rst9
-rw-r--r--doc/device-tree-bindings/iommu/iommu.txt206
-rw-r--r--doc/device-tree-bindings/serial/msm-geni-serial.txt6
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/core/device.c8
-rw-r--r--drivers/gpio/msm_gpio.c1
-rw-r--r--drivers/gpio/pm8916_gpio.c8
-rw-r--r--drivers/gpio/s5p_gpio.c1
-rw-r--r--drivers/iommu/Kconfig27
-rw-r--r--drivers/iommu/Makefile6
-rw-r--r--drivers/iommu/apple_dart.c59
-rw-r--r--drivers/iommu/iommu-uclass.c45
-rw-r--r--drivers/iommu/sandbox_iommu.c18
-rw-r--r--drivers/pinctrl/exynos/Kconfig8
-rw-r--r--drivers/pinctrl/exynos/Makefile1
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos.c28
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos78x0.c119
-rw-r--r--drivers/serial/Kconfig22
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/serial_msm_geni.c613
-rw-r--r--drivers/serial/serial_s5p.c107
-rw-r--r--drivers/spmi/spmi-msm.c154
-rw-r--r--include/configs/apple.h36
-rw-r--r--include/configs/exynos78x0-common.h112
-rw-r--r--include/configs/sdm845.h26
-rw-r--r--include/dm/uclass-id.h1
-rw-r--r--include/dt-bindings/interrupt-controller/apple-aic.h15
-rw-r--r--include/dt-bindings/pinctrl/apple.h13
-rw-r--r--include/dt-bindings/spmi/spmi.h10
-rw-r--r--include/iommu.h16
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/iommu.c28
99 files changed, 4434 insertions, 189 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5069f18806..9d8cba9028 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -108,6 +108,15 @@ L: uboot-snps-arc@synopsys.com
F: doc/device-tree-bindings/mmc/snps,dw-mmc.txt
F: drivers/mmc/snps_dw_mmc.c
+APPLE M1 SOC SUPPORT
+M: Mark Kettenis <kettenis@openbsd.org>
+S: Maintained
+F: arch/arm/include/asm/arch-m1/
+F: arch/arm/mach-apple/
+F: configs/apple_m1_defconfig
+F: drivers/iommu/apple_dart.c
+F: include/configs/apple.h
+
ARM
M: Tom Rini <trini@konsulko.com>
S: Maintained
@@ -391,7 +400,9 @@ F: drivers/gpio/msm_gpio.c
F: drivers/mmc/msm_sdhci.c
F: drivers/phy/msm8916-usbh-phy.c
F: drivers/serial/serial_msm.c
+F: drivers/serial/serial_msm_geni.c
F: drivers/smem/msm_smem.c
+F: drivers/spmi/spmi-msm.c
F: drivers/usb/host/ehci-msm.c
ARM STI
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 02f8306f15..b4808d4c75 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -82,8 +82,6 @@ config GICV3
config GIC_V3_ITS
bool "ARM GICV3 ITS"
- select REGMAP
- select SYSCON
select IRQ
help
ARM GICV3 Interrupt translation service (ITS).
@@ -922,6 +920,27 @@ config ARCH_NEXELL
select DM
select GPIO_EXTRA_HEADER
+config ARCH_APPLE
+ bool "Apple SoCs"
+ select ARM64
+ select BLK
+ select CLK
+ select CMD_USB
+ select DM
+ select DM_KEYBOARD
+ select DM_SERIAL
+ select DM_USB
+ select DM_VIDEO
+ select IOMMU
+ select LINUX_KERNEL_IMAGE_HEADER
+ select OF_CONTROL
+ select OF_BOARD
+ select POSITION_INDEPENDENT
+ select USB
+ imply CMD_DM
+ imply CMD_GPT
+ imply DISTRO_DEFAULTS
+
config ARCH_OWL
bool "Actions Semi OWL SoCs"
select DM
@@ -2018,6 +2037,8 @@ config ISW_ENTRY_ADDR
image headers.
endif
+source "arch/arm/mach-apple/Kconfig"
+
source "arch/arm/mach-aspeed/Kconfig"
source "arch/arm/mach-at91/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6c9a00c5a4..ad757e982e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -55,6 +55,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_APPLE) += apple
machine-$(CONFIG_ARCH_ASPEED) += aspeed
machine-$(CONFIG_ARCH_AT91) += at91
machine-$(CONFIG_ARCH_BCM283X) += bcm283x
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index 9820d3290e..a08ed3f544 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -41,27 +41,36 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
#ifdef CONFIG_GIC_V3_ITS
-int ls_gic_rd_tables_init(void *blob)
+#define PENDTABLE_MAX_SZ ALIGN(BIT(ITS_MAX_LPI_NRBITS), SZ_64K)
+#define PROPTABLE_MAX_SZ ALIGN(BIT(ITS_MAX_LPI_NRBITS) / 8, SZ_64K)
+#define GIC_LPI_SIZE ALIGN(cpu_numcores() * PENDTABLE_MAX_SZ + \
+ PROPTABLE_MAX_SZ, SZ_1M)
+static int fdt_add_resv_mem_gic_rd_tables(void *blob, u64 base, size_t size)
{
- struct fdt_memory lpi_base;
- fdt_addr_t addr;
- fdt_size_t size;
- int offset, ret;
+ int err;
+ struct fdt_memory gic_rd_tables;
- offset = fdt_path_offset(gd->fdt_blob, "/syscon@0x80000000");
- addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, offset, "reg",
- 0, &size, false);
+ gic_rd_tables.start = base;
+ gic_rd_tables.end = base + size - 1;
+ err = fdtdec_add_reserved_memory(blob, "gic-rd-tables", &gic_rd_tables,
+ NULL, 0, NULL, 0);
+ if (err < 0)
+ debug("%s: failed to add reserved memory: %d\n", __func__, err);
- lpi_base.start = addr;
- lpi_base.end = addr + size - 1;
- ret = fdtdec_add_reserved_memory(blob, "lpi_rd_table", &lpi_base, NULL,
- 0, NULL, 0);
- if (ret) {
- debug("%s: failed to add reserved memory\n", __func__);
+ return err;
+}
+
+int ls_gic_rd_tables_init(void *blob)
+{
+ u64 gic_lpi_base;
+ int ret;
+
+ gic_lpi_base = ALIGN(gd->arch.resv_ram - GIC_LPI_SIZE, SZ_64K);
+ ret = fdt_add_resv_mem_gic_rd_tables(blob, gic_lpi_base, GIC_LPI_SIZE);
+ if (ret)
return ret;
- }
- ret = gic_lpi_tables_init();
+ ret = gic_lpi_tables_init(gic_lpi_base, cpu_numcores());
if (ret)
debug("%s: failed to init gic-lpi-tables\n", __func__);
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index a88aecc5bd..cc34da7bd8 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -28,6 +28,13 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
exynos5800-peach-pi.dtb \
exynos5422-odroidxu3.dtb
dtb-$(CONFIG_EXYNOS7420) += exynos7420-espresso7420.dtb
+dtb-$(CONFIG_TARGET_A5Y17LTE) += exynos78x0-axy17lte.dtb
+dtb-$(CONFIG_TARGET_A3Y17LTE) += exynos78x0-axy17lte.dtb
+dtb-$(CONFIG_TARGET_A7Y17LTE) += exynos78x0-axy17lte.dtb
+
+dtb-$(CONFIG_ARCH_APPLE) += \
+ t8103-j274.dtb \
+ t8103-j293.dtb
dtb-$(CONFIG_ARCH_DAVINCI) += \
da850-evm.dtb \
@@ -473,6 +480,7 @@ dtb-$(CONFIG_TARGET_SL28) += fsl-ls1028a-kontron-sl28.dtb \
dtb-$(CONFIG_TARGET_DRAGONBOARD410C) += dragonboard410c.dtb
dtb-$(CONFIG_TARGET_DRAGONBOARD820C) += dragonboard820c.dtb
+dtb-$(CONFIG_TARGET_STARQLTECHN) += starqltechn.dtb
dtb-$(CONFIG_TARGET_STEMMY) += ste-ux500-samsung-stemmy.dtb
diff --git a/arch/arm/dts/exynos78x0-axy17lte.dts b/arch/arm/dts/exynos78x0-axy17lte.dts
new file mode 100644
index 0000000000..7fae8db874
--- /dev/null
+++ b/arch/arm/dts/exynos78x0-axy17lte.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Samsung Exynos78x0 SoC device tree source
+ *
+ * Copyright (c) 2020 Dzmitry Sankouski (dsankouski@gmail.com)
+ */
+
+/dts-v1/;
+#include "exynos78x0.dtsi"
+/ {
+ compatible = "samsung,exynos78x0", "samsung,exynos7880", "samsung,exynos7870";
+
+ aliases {
+ console = &uart2;
+ };
+
+ chosen {
+ stdout-path = &uart2;
+ };
+};
+
+&gpioi2c0 {
+ status = "okay";
+};
+
+&fin_pll {
+ clock-frequency = <26000000>;
+};
+
diff --git a/arch/arm/dts/exynos78x0-gpio.dtsi b/arch/arm/dts/exynos78x0-gpio.dtsi
new file mode 100644
index 0000000000..a7f75c5ca9
--- /dev/null
+++ b/arch/arm/dts/exynos78x0-gpio.dtsi
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Samsung's Exynos7880 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2020 Dzmitry Sankouski (dsankouski@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+ /* ALIVE */
+ gpio@139F0000 {
+ etc0: etc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ etc1: etc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpa2: gpa2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpa3: gpa3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpq0: gpq0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ /* CCORE */
+ gpio@10630000 {
+ gpm0: gpm0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ /* DISP/AUD */
+ gpio@148C0000 {
+ gpz0: gpz0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpz1: gpz1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpz2: gpz2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ /* FSYS0 */
+ gpio@13750000 {
+ gpr0: gpr0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpr1: gpr1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpr2: gpr2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpr3: gpr3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpr4: gpr4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ /* TOP */
+ gpio@139B0000 {
+ gpb0: gpb0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc4: gpc4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc5: gpc5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc6: gpc6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc8: gpc8 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc9: gpc9 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpd2: gpd2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpd3: gpd3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpd4: gpd4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpd5: gpd5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpf2: gpf2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpf3: gpf3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpf4: gpf4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+};
diff --git a/arch/arm/dts/exynos78x0-pinctrl.dtsi b/arch/arm/dts/exynos78x0-pinctrl.dtsi
new file mode 100644
index 0000000000..4958c55119
--- /dev/null
+++ b/arch/arm/dts/exynos78x0-pinctrl.dtsi
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Samsung's Exynos7880 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2020 Dzmitry Sankouski (dsankouski@gmail.com)
+ *
+ * Samsung's Exynos7880 SoC pin-mux and pin-config options are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+ /* ALIVE */
+ pinctrl@139F0000 {
+ uart2_bus: uart2-bus {
+ samsung,pins = "gpa1-1", "gpa1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ };
+
+ dwmmc2_cd_ext_irq: dwmmc2_cd_ext_irq {
+ samsung,pins = "gpa3-3";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <4>;
+ };
+
+ key_power: key-power {
+ samsung,pins = "gpa0-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ key_voldown: key-voldown {
+ samsung,pins = "gpa2-1";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ key_volup: key-volup {
+ samsung,pins = "gpa2-0";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ key_home: key-home {
+ samsung,pins = "gpa1-7";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ /* TOP */
+ pinctrl@139B0000 {
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpc1-1", "gpc1-0";
+ samsung,pin-function = <2>;
+ };
+
+ sd0_rst: sd0_rst {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <0>;
+ };
+ };
+
+ /* DISP/AUD */
+ pinctrl@148C0000 {
+ i2s_pmic_bus: i2s-pmic-bus {
+ samsung,pins = "gpz1-0", "gpz1-1", "gpz1-2", "gpz1-3", "gpz1-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s_pmic_bus_idle: i2s-pmic-bus_idle {
+ samsung,pins = "gpz1-0", "gpz1-1", "gpz1-2", "gpz1-3", "gpz1-4";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ /* FSYS0 */
+ pinctrl@13750000 {
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpr0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd0_rdqs: sd0-rdqs {
+ samsung,pins = "gpr0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd0_clk_fast_slew_rate_1x: sd0-clk_fast_slew_rate_1x {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ sd0_clk_fast_slew_rate_2x: sd0-clk_fast_slew_rate_2x {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <1>;
+ };
+
+ sd0_clk_fast_slew_rate_3x: sd0-clk_fast_slew_rate_3x {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd0_clk_fast_slew_rate_4x: sd0-clk_fast_slew_rate_4x {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_clk_fast_slew_rate_5x: sd0-clk_fast_slew_rate_5x {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <4>;
+ };
+
+ sd0_clk_fast_slew_rate_6x: sd0-clk_fast_slew_rate_6x {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <5>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpr1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpr2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpr2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpr3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ samsung,pin-con-pdn = <2>;
+ samsung,pin-pud-pdn = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ samsung,pin-con-pdn = <2>;
+ samsung,pin-pud-pdn = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpr4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpr4-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpr4-3", "gpr4-4", "gpr4-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_clk_output: sd2-clk-output {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_cmd_output: sd2-cmd-output {
+ samsung,pins = "gpr4-1";
+ samsung,pin-function = <1>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_clk_fast_slew_rate_1x: sd2-clk_fast_slew_rate_1x {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ sd2_clk_fast_slew_rate_2x: sd2-clk_fast_slew_rate_2x {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <1>;
+ };
+
+ sd2_clk_fast_slew_rate_3x: sd2-clk_fast_slew_rate_3x {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd2_clk_fast_slew_rate_4x: sd2-clk_fast_slew_rate_4x {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+ };
+};
diff --git a/arch/arm/dts/exynos78x0.dtsi b/arch/arm/dts/exynos78x0.dtsi
new file mode 100644
index 0000000000..fb9c9cbdf9
--- /dev/null
+++ b/arch/arm/dts/exynos78x0.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Samsung Exynos7880 SoC device tree source
+ *
+ * Copyright (c) 2020 Dzmitry Sankouski (dsankouski@gmail.com)
+ */
+
+/dts-v1/;
+#include "skeleton.dtsi"
+#include "exynos78x0-pinctrl.dtsi"
+#include "exynos78x0-gpio.dtsi"
+/ {
+ compatible = "samsung,exynos7880";
+
+ fin_pll: xxti {
+ compatible = "fixed-clock";
+ clock-output-names = "fin_pll";
+ u-boot,dm-pre-reloc;
+ #clock-cells = <0>;
+ };
+
+ /* Dummy clock for uart */
+ fin_uart: uart_dummy_fin {
+ compatible = "fixed-clock";
+ clock-output-names = "fin_uart";
+ clock-frequency = <132710400>;
+ u-boot,dm-pre-reloc;
+ #clock-cells = <0>;
+ };
+
+ uart2: serial@13820000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13820000 0x100>;
+ u-boot,dm-pre-reloc;
+ clocks = <&fin_uart>, <&fin_uart>; // driver uses 1st clock
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_bus>;
+ };
+
+ gpioi2c0: i2c-0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "i2c-gpio";
+ status = "disabled";
+ gpios = <
+ &gpc1 0 0 /* sda */
+ &gpc1 1 0 /* scl */
+ >;
+ i2c-gpio,delay-us = <5>;
+
+ s2mu004@3d {
+ compatible = "samsung,s2mu004mfd";
+ };
+ };
+
+ /* ALIVE */
+ pinctrl_0: pinctrl@139F0000 {
+ compatible = "samsung,exynos78x0-pinctrl";
+ reg = <0x139F0000 0x1000>;
+ };
+
+ /* DISP/AUD */
+ pinctrl_2: pinctrl@148C0000 {
+ compatible = "samsung,exynos78x0-pinctrl";
+ reg = <0x148C0000 0x1000>;
+ };
+
+ /* FSYS0 */
+ pinctrl_4: pinctrl@13750000 {
+ compatible = "samsung,exynos78x0-pinctrl";
+ reg = <0x13750000 0x1000>;
+ };
+
+ /* ALIVE */
+ gpio_0: gpio@139F0000 {
+ compatible = "samsung,exynos78x0-gpio";
+ reg = <0x139F0000 0x1000>;
+ };
+
+ /* DISP/AUD */
+ gpio_2: gpio@148C0000 {
+ compatible = "samsung,exynos78x0-gpio";
+ reg = <0x148C0000 0x1000>;
+ };
+
+ /* FSYS0 */
+ gpio_4: gpio@13750000 {
+ compatible = "samsung,exynos78x0-gpio";
+ reg = <0x13750000 0x1000>;
+ };
+
+ /* TOP */
+ gpio_6: gpio@139B0000 {
+ compatible = "samsung,exynos78x0-gpio";
+ reg = <0x139B0000 0x1000>;
+ };
+};
diff --git a/arch/arm/dts/fsl-ls1028a.dtsi b/arch/arm/dts/fsl-ls1028a.dtsi
index 50f9b527cd..53b052ed32 100644
--- a/arch/arm/dts/fsl-ls1028a.dtsi
+++ b/arch/arm/dts/fsl-ls1028a.dtsi
@@ -44,12 +44,6 @@
IRQ_TYPE_LEVEL_LOW)>;
};
- gic_lpi_base: syscon@0x80000000 {
- compatible = "gic-lpi-base";
- reg = <0x0 0x80000000 0x0 0x100000>;
- max-gic-redistributors = <2>;
- };
-
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
diff --git a/arch/arm/dts/fsl-ls1088a.dtsi b/arch/arm/dts/fsl-ls1088a.dtsi
index 64caa600ad..3a5a50fb83 100644
--- a/arch/arm/dts/fsl-ls1088a.dtsi
+++ b/arch/arm/dts/fsl-ls1088a.dtsi
@@ -27,12 +27,6 @@
interrupts = <1 9 0x4>;
};
- gic_lpi_base: syscon@0x80000000 {
- compatible = "gic-lpi-base";
- reg = <0x0 0x80000000 0x0 0x100000>;
- max-gic-redistributors = <8>;
- };
-
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
diff --git a/arch/arm/dts/fsl-ls2080a.dtsi b/arch/arm/dts/fsl-ls2080a.dtsi
index 7374d580e0..278daeeb6e 100644
--- a/arch/arm/dts/fsl-ls2080a.dtsi
+++ b/arch/arm/dts/fsl-ls2080a.dtsi
@@ -27,12 +27,6 @@
interrupts = <1 9 0x4>;
};
- gic_lpi_base: syscon@0x80000000 {
- compatible = "gic-lpi-base";
- reg = <0x0 0x80000000 0x0 0x100000>;
- max-gic-redistributors = <8>;
- };
-
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
diff --git a/arch/arm/dts/fsl-lx2160a.dtsi b/arch/arm/dts/fsl-lx2160a.dtsi
index a6f0e9bc56..3b5f0d119e 100644
--- a/arch/arm/dts/fsl-lx2160a.dtsi
+++ b/arch/arm/dts/fsl-lx2160a.dtsi
@@ -43,12 +43,6 @@
interrupts = <1 9 0x4>;
};
- gic_lpi_base: syscon@0x80000000 {
- compatible = "gic-lpi-base";
- reg = <0x0 0x80000000 0x0 0x200000>;
- max-gic-redistributors = <16>;
- };
-
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
diff --git a/arch/arm/dts/sdm845.dtsi b/arch/arm/dts/sdm845.dtsi
new file mode 100644
index 0000000000..1185b71216
--- /dev/null
+++ b/arch/arm/dts/sdm845.dtsi
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm SDM845 chip device tree source
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ */
+
+/dts-v1/;
+
+#include "skeleton64.dtsi"
+
+/ {
+ soc: soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0xffffffff>;
+ compatible = "simple-bus";
+
+ gcc: clock-controller@100000 {
+ u-boot,dm-pre-reloc;
+ compatible = "qcom,gcc-sdm845";
+ reg = <0x100000 0x1f0000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+ gpio_north: gpio_north@3900000 {
+ u-boot,dm-pre-reloc;
+ #gpio-cells = <2>;
+ compatible = "qcom,sdm845-pinctrl";
+ reg = <0x3900000 0x400000>;
+ gpio-count = <150>;
+ gpio-controller;
+ gpio-ranges = <&gpio_north 0 0 150>;
+ gpio-bank-name = "soc_north.";
+ };
+
+ tlmm_north: pinctrl_north@3900000 {
+ u-boot,dm-pre-reloc;
+ compatible = "qcom,tlmm-sdm845";
+ reg = <0x3900000 0x400000>;
+ gpio-count = <150>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&tlmm_north 0 0 150>;
+
+ /* DEBUG UART */
+ qup_uart9: qup-uart9-default {
+ pinmux {
+ pins = "GPIO_4", "GPIO_5";
+ function = "qup9";
+ };
+ };
+ };
+
+ debug_uart: serial@a84000 {
+ compatible = "qcom,msm-geni-uart";
+ reg = <0xa84000 0x4000>;
+ reg-names = "se_phys";
+ clock-names = "se-clk";
+ clocks = <&gcc 0x58>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&qup_uart9>;
+ qcom,wrapper-core = <0x8a>;
+ status = "disabled";
+ };
+
+ spmi@c440000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0xc440000 0x1100>,
+ <0xc600000 0x2000000>,
+ <0xe600000 0x100000>;
+ reg-names = "cnfg", "core", "obsrvr";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+
+ qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ pmic0: pm8998@0 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x0 0x1>;
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+
+ pm8998_pon: pm8998_pon@800 {
+ compatible = "qcom,pm8998-pwrkey";
+ reg = <0x800 0x100>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "pm8998_key.";
+ };
+
+ pm8998_gpios: pm8998_gpios@c000 {
+ compatible = "qcom,pm8998-gpio";
+ reg = <0xc000 0x1a00>;
+ gpio-controller;
+ gpio-count = <21>;
+ #gpio-cells = <2>;
+ gpio-bank-name = "pm8998.";
+ };
+ };
+
+ pmic1: pm8998@1 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x1 0x0>;
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/starqltechn-uboot.dtsi b/arch/arm/dts/starqltechn-uboot.dtsi
new file mode 100644
index 0000000000..d8d75e018a
--- /dev/null
+++ b/arch/arm/dts/starqltechn-uboot.dtsi
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot addition to handle Samsung S9 SM-G9600 (starqltechn) pins
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ */
+
+/
+{
+ soc {
+ u-boot,dm-pre-reloc;
+ gcc {
+ clock-controller@100000 {
+ u-boot,dm-pre-reloc;
+ };
+ serial@0xa84000 {
+ u-boot,dm-pre-reloc;
+ };
+ gpio_north@3900000 {
+ u-boot,dm-pre-reloc;
+ };
+ pinctrl@3900000 {
+ u-boot,dm-pre-reloc;
+ };
+ };
+ };
+};
+
+&pm8998_pon {
+ key_vol_down {
+ gpios = <&pm8998_pon 1 0>;
+ label = "key_vol_down";
+ };
+ key_power {
+ gpios = <&pm8998_pon 0 0>;
+ label = "key_power";
+ };
+};
diff --git a/arch/arm/dts/starqltechn.dts b/arch/arm/dts/starqltechn.dts
new file mode 100644
index 0000000000..387420f30b
--- /dev/null
+++ b/arch/arm/dts/starqltechn.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Samsung S9 SM-G9600 (starqltechn) board device tree source
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ */
+
+/dts-v1/;
+
+#include "sdm845.dtsi"
+
+/ {
+ model = "Samsung S9 (SM-G9600)";
+ compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen {
+ stdout-path = "serial0:921600n8";
+ };
+
+ aliases {
+ serial0 = &debug_uart;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000 0 0xfe1bffff>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ soc: soc {
+ serial@0xa84000 {
+ status = "ok";
+ };
+
+ pinctrl@3900000 {
+ muic_i2c: muic_i2c {
+ pins = "GPIO_33", "GPIO_34";
+ drive-strength = <0x2>;
+ function = "gpio";
+ bias-disable;
+ };
+ };
+ };
+};
+
+#include "starqltechn-uboot.dtsi"
diff --git a/arch/arm/dts/t8103-j274.dts b/arch/arm/dts/t8103-j274.dts
new file mode 100644
index 0000000000..aef1ae29b6
--- /dev/null
+++ b/arch/arm/dts/t8103-j274.dts
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple Mac mini (M1, 2020)
+ *
+ * target-type: J274
+ *
+ * Copyright The Asahi Linux Contributors
+ */
+
+/dts-v1/;
+
+#include "t8103.dtsi"
+
+/ {
+ compatible = "apple,j274", "apple,t8103", "apple,arm-platform";
+ model = "Apple Mac mini (M1, 2020)";
+
+ aliases {
+ serial0 = &serial0;
+ ethernet0 = &eth0;
+ wifi0 = &wifi0;
+ };
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ stdout-path = "serial0";
+
+ framebuffer0: framebuffer@0 {
+ compatible = "apple,simple-framebuffer", "simple-framebuffer";
+ reg = <0 0 0 0>; /* To be filled by loader */
+ /* Format properties will be added by loader */
+ status = "disabled";
+ };
+ };
+
+ memory@800000000 {
+ device_type = "memory";
+ reg = <0x8 0 0x2 0>; /* To be filled by loader */
+ };
+};
+
+&serial0 {
+ status = "okay";
+};
+
+&pcie0_dart_0 {
+ status = "okay";
+};
+
+&pcie0_dart_1 {
+ status = "okay";
+};
+
+&pcie0_dart_2 {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+
+ pci0: pci@0,0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ pwren-gpios = <&smc 13 0>;
+ reset-gpios = <&pinctrl_ap 152 0>;
+ max-link-speed = <2>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
+
+ pci1: pci@1,0 {
+ device_type = "pci";
+ reg = <0x800 0x0 0x0 0x0 0x0>;
+ reset-gpios = <&pinctrl_ap 153 0>;
+ max-link-speed = <2>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
+
+ pci2: pci@2,0 {
+ device_type = "pci";
+ reg = <0x1000 0x0 0x0 0x0 0x0>;
+ reset-gpios = <&pinctrl_ap 33 0>;
+ max-link-speed = <1>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
+};
+
+&pci0 {
+ wifi0: network@0,0 {
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+ local-mac-address = [00 00 00 00 00 00];
+ };
+};
+
+&pci2 {
+ eth0: ethernet@0,0 {
+ reg = <0x30000 0x0 0x0 0x0 0x0>;
+ local-mac-address = [00 00 00 00 00 00];
+ };
+};
+
+&dwc3_0_dart_0 {
+ status = "okay";
+};
+
+&dwc3_0_dart_1 {
+ status = "okay";
+};
+
+&dwc3_0 {
+ status = "okay";
+};
+
+&dwc3_1_dart_0 {
+ status = "okay";
+};
+
+&dwc3_1_dart_1 {
+ status = "okay";
+};
+
+&dwc3_1 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/t8103-j293.dts b/arch/arm/dts/t8103-j293.dts
new file mode 100644
index 0000000000..4a22596cf4
--- /dev/null
+++ b/arch/arm/dts/t8103-j293.dts
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple Macbook Pro (M1, 2020)
+ *
+ * target-type: J293
+ *
+ * Copyright The Asahi Linux Contributors
+ */
+
+/dts-v1/;
+
+#include "t8103.dtsi"
+
+/ {
+ compatible = "apple,j293", "apple,t8103", "apple,arm-platform";
+ model = "Apple Macbook Pro (M1, 2020)";
+
+ aliases {
+ serial0 = &serial0;
+ wifi0 = &wifi0;
+ };
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ stdout-path = "serial0";
+
+ framebuffer0: framebuffer@0 {
+ compatible = "apple,simple-framebuffer", "simple-framebuffer";
+ reg = <0 0 0 0>; /* To be filled by loader */
+ /* Format properties will be added by loader */
+ status = "disabled";
+ };
+ };
+
+ memory@800000000 {
+ device_type = "memory";
+ reg = <0x8 0 0x2 0>; /* To be filled by loader */
+ };
+};
+
+&serial0 {
+ status = "okay";
+};
+
+&pcie0_dart_0 {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+
+ pci0: pci@0,0 {
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ pwren-gpios = <&smc 13 0>;
+ reset-gpios = <&pinctrl_ap 152 0>;
+ max-link-speed = <2>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
+};
+
+&pci0 {
+ wifi0: network@0,0 {
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+ local-mac-address = [00 00 00 00 00 00];
+ };
+};
+
+&dwc3_0_dart_0 {
+ status = "okay";
+};
+
+&dwc3_0_dart_1 {
+ status = "okay";
+};
+
+&dwc3_0 {
+ status = "okay";
+};
+
+&dwc3_1_dart_0 {
+ status = "okay";
+};
+
+&dwc3_1_dart_1 {
+ status = "okay";
+};
+
+&dwc3_1 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/t8103.dtsi b/arch/arm/dts/t8103.dtsi
new file mode 100644
index 0000000000..7d9cb272f9
--- /dev/null
+++ b/arch/arm/dts/t8103.dtsi
@@ -0,0 +1,560 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T8103 "M1" SoC
+ *
+ * Other names: H13G, "Tonga"
+ *
+ * Copyright The Asahi Linux Contributors
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/apple.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+ compatible = "apple,t8103", "apple,arm-platform";
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "apple,icestorm";
+ device_type = "cpu";
+ reg = <0x0 0x0>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+
+ cpu1: cpu@1 {
+ compatible = "apple,icestorm";
+ device_type = "cpu";
+ reg = <0x0 0x1>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+
+ cpu2: cpu@2 {
+ compatible = "apple,icestorm";
+ device_type = "cpu";
+ reg = <0x0 0x2>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+
+ cpu3: cpu@3 {
+ compatible = "apple,icestorm";
+ device_type = "cpu";
+ reg = <0x0 0x3>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+
+ cpu4: cpu@10100 {
+ compatible = "apple,firestorm";
+ device_type = "cpu";
+ reg = <0x0 0x10100>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+
+ cpu5: cpu@10101 {
+ compatible = "apple,firestorm";
+ device_type = "cpu";
+ reg = <0x0 0x10101>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+
+ cpu6: cpu@10102 {
+ compatible = "apple,firestorm";
+ device_type = "cpu";
+ reg = <0x0 0x10102>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+
+ cpu7: cpu@10103 {
+ compatible = "apple,firestorm";
+ device_type = "cpu";
+ reg = <0x0 0x10103>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0>; /* To be filled by loader */
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&aic>;
+ interrupt-names = "hyp-phys", "hyp-virt", "phys", "virt";
+ interrupts = <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ clkref: clock-ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "clkref";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ranges;
+ dma-ranges;
+ dma-coherent;
+ nonposted-mmio;
+
+ serial0: serial@235200000 {
+ compatible = "apple,s5l-uart";
+ reg = <0x2 0x35200000 0x0 0x1000>;
+ reg-io-width = <4>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 605 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkref>, <&clkref>, <&clkref>;
+ clock-names = "uart", "clk_uart_baud0", "clk_uart_baud1";
+ power-domains = <&ps_uart0>;
+ status = "disabled";
+ };
+
+ serial2: serial@235208000 {
+ compatible = "apple,s5l-uart";
+ reg = <0x2 0x35208000 0x0 0x1000>;
+ reg-io-width = <4>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 607 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkref>, <&clkref>, <&clkref>;
+ clock-names = "uart", "clk_uart_baud0", "clk_uart_baud1";
+ power-domains = <&ps_uart2>;
+ status = "disabled";
+ };
+
+ aic: interrupt-controller@23b100000 {
+ compatible = "apple,t8103-aic", "apple,aic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x2 0x3b100000 0x0 0x8000>;
+ };
+
+ pmgr: power-controller@23b700000 {
+ compatible = "apple,t8103-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <0x2 0x3b700000 0x0 0x14000>;
+
+ ps_pcie_ref: power-controller@1a0 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x1a0>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "pcie_ref";
+ };
+
+ ps_imx: power-controller@1b8 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x1b8>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "imx";
+ apple,always-on;
+ };
+
+ ps_sio: power-controller@1c0 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x1c0>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "sio";
+ };
+
+ ps_uart_p: power-controller@220 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x220>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ power-domains = <&ps_sio>;
+ apple,domain-name = "uart_p";
+ };
+
+ ps_uart0: power-controller@270 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x270>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ power-domains = <&ps_uart_p>;
+ apple,domain-name = "uart0";
+ };
+
+ ps_uart1: power-controller@278 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x278>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "uart1";
+ power-domains = <&ps_uart_p>;
+ };
+
+ ps_uart2: power-controller@280 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x280>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "uart2";
+ power-domains = <&ps_uart_p>;
+ };
+
+ ps_uart3: power-controller@288 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x288>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "uart3";
+ power-domains = <&ps_uart_p>;
+ };
+
+ ps_apcie: power-controller@348 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x348>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "apcie";
+ power-domains = <&ps_imx>;
+ };
+
+ ps_apcie_gp: power-controller@3e8 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x3e8>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "apcie_gp";
+ power-domains = <&ps_apcie>;
+ };
+
+ ps_ans2: power-controller@3f0 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x3f0>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "ans2";
+ power-domains = <&ps_apcie_st>;
+ };
+
+ ps_apcie_st: power-controller@418 {
+ compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+ reg = <0x418>;
+ #power-domain-cells = <0>;
+ #reset-cells = <0>;
+ apple,domain-name = "apcie_st";
+ power-domains = <&ps_apcie>;
+ };
+ };
+
+ pinctrl_ap: pinctrl@23c100000 {
+ compatible = "apple,t8103-pinctrl", "apple,pinctrl";
+ reg = <0x2 0x3c100000 0x0 0x100000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_ap 0 0 212>;
+
+ interrupt-controller;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 190 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 191 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 192 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 193 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 194 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 195 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 196 IRQ_TYPE_LEVEL_HIGH>;
+
+ i2c0_pins: i2c0_pins {
+ pinmux = <APPLE_PINMUX(188, 1)>,
+ <APPLE_PINMUX(192, 1)>;
+ };
+
+ pcie_pins: pcie-pins {
+ pinmux = <APPLE_PINMUX(150, 1)>,
+ <APPLE_PINMUX(151, 1)>,
+ <APPLE_PINMUX(32, 1)>;
+ };
+ };
+
+ pinctrl_aop: pinctrl@24a820000 {
+ compatible = "apple,t8103-pinctrl", "apple,pinctrl";
+ reg = <0x2 0x4a820000 0x0 0x4000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_aop 0 0 42>;
+
+ interrupt-controller;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 268 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 269 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 270 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 271 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 272 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 273 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 274 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_nub: pinctrl@23d1f0000 {
+ compatible = "apple,t8103-pinctrl", "apple,pinctrl";
+ reg = <0x2 0x3d1f0000 0x0 0x4000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_nub 0 0 23>;
+
+ interrupt-controller;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 330 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 331 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 332 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 333 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 334 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 335 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 336 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_smc: pinctrl@23e820000 {
+ compatible = "apple,t8103-pinctrl", "apple,pinctrl";
+ reg = <0x2 0x3e820000 0x0 0x4000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_smc 0 0 16>;
+
+ interrupt-controller;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 391 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 392 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 393 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 394 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 395 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 396 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 397 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ i2c0: i2c@20a110000 {
+ compatible = "apple,i2c-v0";
+ reg = <0x2 0x35010000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 627 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkref>;
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ hpm0: hpm@38 {
+ compatible = "ti,tps6598x";
+ reg = <0x38>;
+ };
+
+ hpm1: hpm@3f {
+ compatible = "ti,tps6598x";
+ reg = <0x3f>;
+ };
+ };
+
+ ans_mbox: mbox@277400000 {
+ compatible = "apple,iop-mailbox-m1";
+ reg = <0x2 0x77400000 0x0 0x20000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 583 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 586 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&ps_ans2>;
+ #mbox-cells = <1>;
+ endpoints = <32>;
+ };
+
+ ans@27bcc0000 {
+ compatible = "apple,nvme-m1";
+ reg = <0x2 0x7bcc0000 0x0 0x40000>,
+ <0x2 0x7bc50000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 590 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&ps_apcie_st>;
+ mboxes = <&ans_mbox 32>;
+ };
+
+ pcie0_dart_0: iommu@681008000 {
+ compatible = "apple,t8103-dart", "apple,dart-m1";
+ reg = <0x6 0x81008000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 696 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ pcie0_dart_1: iommu@682008000 {
+ compatible = "apple,t8103-dart", "apple,dart-m1";
+ reg = <0x6 0x82008000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 699 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ pcie0_dart_2: iommu@683008000 {
+ compatible = "apple,t8103-dart", "apple,dart-m1";
+ reg = <0x6 0x83008000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 702 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ smc_mbox: mbox@23e400000 {
+ compatible = "apple,iop-mailbox-m1";
+ reg = <0x2 0x3e400000 0x0 0x20000>;
+ #mbox-cells = <1>;
+ endpoints = <32>;
+ };
+
+ smc: smc@23e050000 {
+ compatible = "apple,smc-m1";
+ reg = <0x2 0x3e050000 0x0 0x4000>;
+ mboxes = <&smc_mbox 32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-13 = <0x00800000>;
+ };
+
+ pcie0: pcie@690000000 {
+ compatible = "apple,t8103-pcie", "apple,pcie";
+
+ reg = <0x6 0x90000000 0x0 0x1000000>,
+ <0x6 0x80000000 0x0 0x4000>,
+ <0x6 0x81000000 0x0 0x8000>,
+ <0x6 0x82000000 0x0 0x8000>,
+ <0x6 0x83000000 0x0 0x8000>;
+ reg-names = "config", "rc", "port0", "port1", "port2";
+
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
+ <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
+
+ msi-controller;
+ msi-parent = <&pcie0>;
+ msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
+
+ iommu-map = <0x100 &pcie0_dart_0 1 1>,
+ <0x200 &pcie0_dart_1 1 1>,
+ <0x300 &pcie0_dart_2 1 1>;
+ iommu-map-mask = <0xff00>;
+
+ bus-range = <0 3>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000
+ 0x0 0x20000000>,
+ <0x02000000 0x0 0xc0000000 0x6 0xc0000000
+ 0x0 0x40000000>;
+
+ power-domains = <&ps_apcie>, <&ps_apcie_gp>, <&ps_pcie_ref>;
+ pinctrl-0 = <&pcie_pins>;
+ pinctrl-names = "default";
+
+ device_type = "pci";
+ status = "disabled";
+ };
+
+ dwc3_0_dart_0: iommu@382f00000 {
+ compatible = "apple,t8103-dart";
+ reg = <0x3 0x82f00000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ dwc3_0_dart_1: iommu@382f80000 {
+ compatible = "apple,t8103-dart";
+ reg = <0x3 0x82f80000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ dwc3_0: usb@382280000{
+ compatible = "snps,dwc3";
+ reg = <0x3 0x82280000 0x0 0x100000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 777 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>;
+ status = "disabled";
+ };
+
+ dwc3_1_dart_0: iommu@502f00000 {
+ compatible = "apple,t8103-dart";
+ reg = <0x5 0x02f00000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ dwc3_1_dart_1: iommu@502f80000 {
+ compatible = "apple,t8103-dart";
+ reg = <0x5 0x02f80000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>;
+ #iommu-cells = <1>;
+ status = "disabled";
+ };
+
+ dwc3_1: usb@502280000{
+ compatible = "snps,dwc3";
+ reg = <0x5 0x02280000 0x0 0x100000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 857 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ iommus = <&dwc3_1_dart_0 0>, <&dwc3_1_dart_1 1>;
+ status = "disabled";
+ };
+
+ reboot@23d2b0000 {
+ compatible = "apple,reboot-v0";
+ reg = <0x2 0x3d2b0000 0x0 0x4000>;
+ };
+
+ spi@23510c000 {
+ compatible = "apple,t8103-spi", "apple,spi";
+ reg = <0x2 0x3510c000 0x0 0x4000>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 617 IRQ_TYPE_LEVEL_HIGH>;
+ cs-gpios = <&pinctrl_ap 49 GPIO_ACTIVE_HIGH>;
+ };
+
+ spmi@23d0d8000 {
+ compatible = "apple,t8103-spmi", "apple,spmi";
+ reg = <0x2 0x3d0d9300 0x0 0x100>;
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_IRQ 343 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pmu@f {
+ compatible = "apple,sera-pmu";
+ reg = <0xf SPMI_USID>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/include/asm/arch-m1/uart.h b/arch/arm/include/asm/arch-m1/uart.h
new file mode 100644
index 0000000000..d2a17a221e
--- /dev/null
+++ b/arch/arm/include/asm/arch-m1/uart.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Heungjun Kim <riverful.kim@samsung.com>
+ */
+
+#ifndef __ASM_ARCH_UART_H_
+#define __ASM_ARCH_UART_H_
+
+#ifndef __ASSEMBLY__
+/* baudrate rest value */
+union br_rest {
+ unsigned short slot; /* udivslot */
+ unsigned char value; /* ufracval */
+};
+
+struct s5p_uart {
+ unsigned int ulcon;
+ unsigned int ucon;
+ unsigned int ufcon;
+ unsigned int umcon;
+ unsigned int utrstat;
+ unsigned int uerstat;
+ unsigned int ufstat;
+ unsigned int umstat;
+ unsigned int utxh;
+ unsigned int urxh;
+ unsigned int ubrdiv;
+ union br_rest rest;
+ unsigned char res3[0x3fd0];
+};
+
+static inline int s5p_uart_divslot(void)
+{
+ return 0;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arm/include/asm/gic-v3.h b/arch/arm/include/asm/gic-v3.h
index 35efec78c3..5131fabec4 100644
--- a/arch/arm/include/asm/gic-v3.h
+++ b/arch/arm/include/asm/gic-v3.h
@@ -127,9 +127,9 @@
#define GIC_REDISTRIBUTOR_OFFSET 0x20000
#ifdef CONFIG_GIC_V3_ITS
-int gic_lpi_tables_init(void);
+int gic_lpi_tables_init(u64 base, u32 max_redist);
#else
-int gic_lpi_tables_init(void)
+int gic_lpi_tables_init(u64 base, u32 max_redist)
{
return 0;
}
diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c
index 2d3fdb600e..f6211a2d92 100644
--- a/arch/arm/lib/gic-v3-its.c
+++ b/arch/arm/lib/gic-v3-its.c
@@ -5,8 +5,6 @@
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
-#include <regmap.h>
-#include <syscon.h>
#include <asm/gic.h>
#include <asm/gic-v3.h>
#include <asm/io.h>
@@ -19,22 +17,15 @@ static u32 lpi_id_bits;
#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K)
#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
-/* Number of GIC re-distributors */
-#define MAX_GIC_REDISTRIBUTORS 8
-
/*
* gic_v3_its_priv - gic details
*
* @gicd_base: gicd base address
* @gicr_base: gicr base address
- * @lpi_base: gic lpi base address
- * @num_redist: number of gic re-distributors
*/
struct gic_v3_its_priv {
ulong gicd_base;
ulong gicr_base;
- ulong lpi_base;
- u32 num_redist;
};
static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv *priv)
@@ -68,39 +59,13 @@ static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv *priv)
return 0;
}
-static int gic_v3_its_get_gic_lpi_addr(struct gic_v3_its_priv *priv)
-{
- struct regmap *regmap;
- struct udevice *dev;
- int ret;
-
- ret = uclass_get_device_by_driver(UCLASS_SYSCON,
- DM_DRIVER_GET(gic_lpi_syscon), &dev);
- if (ret) {
- pr_err("%s: failed to get %s syscon device\n", __func__,
- DM_DRIVER_GET(gic_lpi_syscon)->name);
- return ret;
- }
-
- regmap = syscon_get_regmap(dev);
- if (!regmap) {
- pr_err("%s: failed to regmap for %s syscon device\n", __func__,
- DM_DRIVER_GET(gic_lpi_syscon)->name);
- return -ENODEV;
- }
- priv->lpi_base = regmap->ranges[0].start;
-
- priv->num_redist = dev_read_u32_default(dev, "max-gic-redistributors",
- MAX_GIC_REDISTRIBUTORS);
-
- return 0;
-}
-
/*
* Program the GIC LPI configuration tables for all
* the re-distributors and enable the LPI table
+ * base: Configuration table address
+ * num_redist: number of redistributors
*/
-int gic_lpi_tables_init(void)
+int gic_lpi_tables_init(u64 base, u32 num_redist)
{
struct gic_v3_its_priv priv;
u32 gicd_typer;
@@ -109,15 +74,12 @@ int gic_lpi_tables_init(void)
int i;
u64 redist_lpi_base;
u64 pend_base;
- ulong pend_tab_total_sz;
+ ulong pend_tab_total_sz = num_redist * LPI_PENDBASE_SZ;
void *pend_tab_va;
if (gic_v3_its_get_gic_addr(&priv))
return -EINVAL;
- if (gic_v3_its_get_gic_lpi_addr(&priv))
- return -EINVAL;
-
gicd_typer = readl((uintptr_t)(priv.gicd_base + GICD_TYPER));
/* GIC support for Locality specific peripheral interrupts (LPI's) */
if (!(gicd_typer & GICD_TYPER_LPIS)) {
@@ -130,7 +92,7 @@ int gic_lpi_tables_init(void)
* Once the LPI table is enabled, can not program the
* LPI configuration tables again, unless the GIC is reset.
*/
- for (i = 0; i < priv.num_redist; i++) {
+ for (i = 0; i < num_redist; i++) {
u32 offset = i * GIC_REDISTRIBUTOR_OFFSET;
if ((readl((uintptr_t)(priv.gicr_base + offset))) &
@@ -146,7 +108,7 @@ int gic_lpi_tables_init(void)
ITS_MAX_LPI_NRBITS);
/* Set PropBase */
- val = (priv.lpi_base |
+ val = (base |
GICR_PROPBASER_INNERSHAREABLE |
GICR_PROPBASER_RAWAWB |
((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK));
@@ -163,8 +125,7 @@ int gic_lpi_tables_init(void)
}
}
- redist_lpi_base = priv.lpi_base + LPI_PROPBASE_SZ;
- pend_tab_total_sz = priv.num_redist * LPI_PENDBASE_SZ;
+ redist_lpi_base = base + LPI_PROPBASE_SZ;
pend_tab_va = map_physmem(redist_lpi_base, pend_tab_total_sz,
MAP_NOCACHE);
memset(pend_tab_va, 0, pend_tab_total_sz);
@@ -172,7 +133,7 @@ int gic_lpi_tables_init(void)
unmap_physmem(pend_tab_va, MAP_NOCACHE);
pend_base = priv.gicr_base + GICR_PENDBASER;
- for (i = 0; i < priv.num_redist; i++) {
+ for (i = 0; i < num_redist; i++) {
u32 offset = i * GIC_REDISTRIBUTOR_OFFSET;
val = ((redist_lpi_base + (i * LPI_PENDBASE_SZ)) |
@@ -207,14 +168,3 @@ U_BOOT_DRIVER(arm_gic_v3_its) = {
.id = UCLASS_IRQ,
.of_match = gic_v3_its_ids,
};
-
-static const struct udevice_id gic_lpi_syscon_ids[] = {
- { .compatible = "gic-lpi-base" },
- {}
-};
-
-U_BOOT_DRIVER(gic_lpi_syscon) = {
- .name = "gic-lpi-base",
- .id = UCLASS_SYSCON,
- .of_match = gic_lpi_syscon_ids,
-};
diff --git a/arch/arm/mach-apple/Kconfig b/arch/arm/mach-apple/Kconfig
new file mode 100644
index 0000000000..66cab91b2a
--- /dev/null
+++ b/arch/arm/mach-apple/Kconfig
@@ -0,0 +1,18 @@
+if ARCH_APPLE
+
+config SYS_TEXT_BASE
+ default 0x00000000
+
+config SYS_CONFIG_NAME
+ default "apple"
+
+config SYS_SOC
+ default "m1"
+
+config SYS_MALLOC_LEN
+ default 0x4000000
+
+config SYS_MALLOC_F_LEN
+ default 0x4000
+
+endif
diff --git a/arch/arm/mach-apple/Makefile b/arch/arm/mach-apple/Makefile
new file mode 100644
index 0000000000..e74a8c9df1
--- /dev/null
+++ b/arch/arm/mach-apple/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += board.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
new file mode 100644
index 0000000000..0bfbc473ec
--- /dev/null
+++ b/arch/arm/mach-apple/board.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <efi_loader.h>
+
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct mm_region apple_mem_map[] = {
+ {
+ /* I/O */
+ .virt = 0x200000000,
+ .phys = 0x200000000,
+ .size = 8UL * SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* I/O */
+ .virt = 0x500000000,
+ .phys = 0x500000000,
+ .size = 2UL * SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* I/O */
+ .virt = 0x680000000,
+ .phys = 0x680000000,
+ .size = SZ_512M,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* PCIE */
+ .virt = 0x6a0000000,
+ .phys = 0x6a0000000,
+ .size = SZ_512M,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+ PTE_BLOCK_INNER_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* PCIE */
+ .virt = 0x6c0000000,
+ .phys = 0x6c0000000,
+ .size = SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+ PTE_BLOCK_INNER_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* RAM */
+ .virt = 0x800000000,
+ .phys = 0x800000000,
+ .size = 8UL * SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ /* Empty entry for framebuffer */
+ 0,
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = apple_mem_map;
+
+int board_init(void)
+{
+ return 0;
+}
+
+int dram_init(void)
+{
+ ofnode node;
+ int index, ret;
+ fdt_addr_t base;
+ fdt_size_t size;
+
+ ret = fdtdec_setup_mem_size_base();
+ if (ret)
+ return ret;
+
+ /* Update RAM mapping */
+ index = ARRAY_SIZE(apple_mem_map) - 3;
+ apple_mem_map[index].virt = gd->ram_base;
+ apple_mem_map[index].phys = gd->ram_base;
+ apple_mem_map[index].size = gd->ram_size;
+
+ node = ofnode_path("/chosen/framebuffer");
+ if (!ofnode_valid(node))
+ return 0;
+
+ base = ofnode_get_addr_size(node, "reg", &size);
+ if (base == FDT_ADDR_T_NONE)
+ return 0;
+
+ /* Add framebuffer mapping */
+ index = ARRAY_SIZE(apple_mem_map) - 2;
+ apple_mem_map[index].virt = base;
+ apple_mem_map[index].phys = base;
+ apple_mem_map[index].size = size;
+ apple_mem_map[index].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+ PTE_BLOCK_INNER_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
+
+#define APPLE_WDT_BASE 0x23d2b0000ULL
+
+#define APPLE_WDT_SYS_CTL_ENABLE BIT(2)
+
+typedef struct apple_wdt {
+ u32 reserved0[3];
+ u32 chip_ctl;
+ u32 sys_tmr;
+ u32 sys_cmp;
+ u32 reserved1;
+ u32 sys_ctl;
+} apple_wdt_t;
+
+void reset_cpu(void)
+{
+ apple_wdt_t *wdt = (apple_wdt_t *)APPLE_WDT_BASE;
+
+ writel(0, &wdt->sys_cmp);
+ writel(APPLE_WDT_SYS_CTL_ENABLE, &wdt->sys_ctl);
+
+ while(1)
+ wfi();
+}
+
+extern long fw_dtb_pointer;
+
+void *board_fdt_blob_setup(int *err)
+{
+ /* Return DTB pointer passed by m1n1 */
+ *err = 0;
+ return (void *)fw_dtb_pointer;
+}
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+ /*
+ * Top part of RAM is used by firmware for things like the
+ * framebuffer. This gives us plenty of room to play with.
+ */
+ return 0x980000000;
+}
diff --git a/arch/arm/mach-apple/lowlevel_init.S b/arch/arm/mach-apple/lowlevel_init.S
new file mode 100644
index 0000000000..e1c0d91cef
--- /dev/null
+++ b/arch/arm/mach-apple/lowlevel_init.S
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+.align 8
+.global fw_dtb_pointer
+fw_dtb_pointer:
+ .quad 0
+
+.global save_boot_params
+save_boot_params:
+ /* Stash DTB pointer passed by m1n1 */
+ adr x1, fw_dtb_pointer
+ str x0, [x1]
+
+ b save_boot_params_ret
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 7df0e17617..7f3aee5712 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -151,6 +151,33 @@ config TARGET_ESPRESSO7420
select PINCTRL_EXYNOS7420
select SUPPORT_SPL
+config TARGET_A5Y17LTE
+ bool "Samsung SM-A520F board"
+ select ARM64
+ select CLK_EXYNOS
+ select OF_CONTROL
+ select PINCTRL
+ select PINCTRL_EXYNOS78x0
+ select SUPPORT_SPL
+
+config TARGET_A7Y17LTE
+ bool "Samsung SM-A520F board"
+ select ARM64
+ select CLK_EXYNOS
+ select OF_CONTROL
+ select PINCTRL
+ select PINCTRL_EXYNOS78x0
+ select SUPPORT_SPL
+
+config TARGET_A3Y17LTE
+ bool "Samsung SM-A520F board"
+ select ARM64
+ select CLK_EXYNOS
+ select OF_CONTROL
+ select PINCTRL
+ select PINCTRL_EXYNOS7880
+ select SUPPORT_SPL
+
endchoice
endif
@@ -167,6 +194,7 @@ source "board/samsung/arndale/Kconfig"
source "board/samsung/smdk5250/Kconfig"
source "board/samsung/smdk5420/Kconfig"
source "board/samsung/espresso7420/Kconfig"
+source "board/samsung/axy17lte/Kconfig"
config SPL_LDSCRIPT
default "board/samsung/common/exynos-uboot-spl.lds" if ARCH_EXYNOS5 || ARCH_EXYNOS4
diff --git a/arch/arm/mach-exynos/mmu-arm64.c b/arch/arm/mach-exynos/mmu-arm64.c
index 46b8169d19..e3bd995143 100644
--- a/arch/arm/mach-exynos/mmu-arm64.c
+++ b/arch/arm/mach-exynos/mmu-arm64.c
@@ -29,3 +29,69 @@ static struct mm_region exynos7420_mem_map[] = {
struct mm_region *mem_map = exynos7420_mem_map;
#endif
+
+#ifdef CONFIG_EXYNOS7870
+static struct mm_region exynos7870_mem_map[] = {
+ {
+ .virt = 0x10000000UL,
+ .phys = 0x10000000UL,
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN,
+ },
+ {
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x3E400000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE,
+ },
+ {
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE,
+ },
+
+ {
+ /* List terminator */
+ },
+};
+
+struct mm_region *mem_map = exynos7870_mem_map;
+#endif
+
+#ifdef CONFIG_EXYNOS7880
+static struct mm_region exynos7880_mem_map[] = {
+ {
+ .virt = 0x10000000UL,
+ .phys = 0x10000000UL,
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN,
+ },
+ {
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x3E400000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE,
+ },
+ {
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE,
+ },
+
+ {
+ /* List terminator */
+ },
+};
+
+struct mm_region *mem_map = exynos7880_mem_map;
+#endif
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index cad3f0a488..73c4b9af3e 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -199,8 +199,8 @@ u32 spl_boot_device(void)
return BOOT_DEVICE_MMC1;
#endif
#ifdef CONFIG_SPL_SATA
- case BOOT_FROM_SATA:
- return BOOT_FROM_SATA;
+ case BOOT_DEVICE_SATA:
+ return BOOT_DEVICE_SATA;
#endif
#ifdef CONFIG_SPL_SPI_FLASH_SUPPORT
case BOOT_DEVICE_SPI:
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index 0ec74fa5d3..12cf02a56a 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -9,6 +9,14 @@ config SYS_MALLOC_F_LEN
config SPL_SYS_MALLOC_F_LEN
default 0x2000
+config SDM845
+ bool "Qualcomm Snapdragon 845 SoC"
+ default n
+ select LINUX_KERNEL_IMAGE_HEADER
+
+config LNX_KRNL_IMG_TEXT_OFFSET_BASE
+ default 0x80000000
+
choice
prompt "Snapdragon board select"
@@ -36,9 +44,22 @@ config TARGET_DRAGONBOARD820C
- 3GiB RAM
- 32GiB UFS drive
+config TARGET_STARQLTECHN
+ bool "Samsung S9 SM-G9600(starqltechn)"
+ help
+ Support for Samsung S9 SM-G9600(starqltechn) board.
+ Features:
+ - Qualcomm Snapdragon SDM845 SoC
+ - 4GiB RAM
+ - 64GiB UFS drive
+ select MISC_INIT_R
+ select SDM845
+ select DM_ETH if NET
+
endchoice
source "board/qualcomm/dragonboard410c/Kconfig"
source "board/qualcomm/dragonboard820c/Kconfig"
+source "board/samsung/starqltechn/Kconfig"
endif
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
index 709919fce4..962855eb8c 100644
--- a/arch/arm/mach-snapdragon/Makefile
+++ b/arch/arm/mach-snapdragon/Makefile
@@ -2,6 +2,9 @@
#
# (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+obj-$(CONFIG_SDM845) += clock-sdm845.o
+obj-$(CONFIG_SDM845) += sysmap-sdm845.o
+obj-$(CONFIG_SDM845) += init_sdm845.o
obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o
obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o
obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o
@@ -12,3 +15,4 @@ obj-y += dram.o
obj-y += pinctrl-snapdragon.o
obj-y += pinctrl-apq8016.o
obj-y += pinctrl-apq8096.o
+obj-$(CONFIG_SDM845) += pinctrl-sdm845.o
diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/arch/arm/mach-snapdragon/clock-sdm845.c
new file mode 100644
index 0000000000..9572639238
--- /dev/null
+++ b/arch/arm/mach-snapdragon/clock-sdm845.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm SDM845
+ *
+ * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org>
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ * Based on Little Kernel driver, simplified
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include "clock-snapdragon.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+struct freq_tbl {
+ uint freq;
+ uint src;
+ u8 pre_div;
+ u16 m;
+ u16 n;
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+ F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
+ F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
+ F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
+ F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
+ F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
+ F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
+ F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
+ F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
+ F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
+ F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
+ F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
+ F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
+ F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
+ { }
+};
+
+static const struct bcr_regs uart2_regs = {
+ .cfg_rcgr = SE9_UART_APPS_CFG_RCGR,
+ .cmd_rcgr = SE9_UART_APPS_CMD_RCGR,
+ .M = SE9_UART_APPS_M,
+ .N = SE9_UART_APPS_N,
+ .D = SE9_UART_APPS_D,
+};
+
+const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)
+{
+ if (!f)
+ return NULL;
+
+ if (!f->freq)
+ return f;
+
+ for (; f->freq; f++)
+ if (rate <= f->freq)
+ return f;
+
+ /* Default to our fastest rate */
+ return f - 1;
+}
+
+static int clk_init_uart(struct msm_clk_priv *priv, uint rate)
+{
+ const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
+
+ clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
+ freq->pre_div, freq->m, freq->n, freq->src);
+
+ return 0;
+}
+
+ulong msm_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case 0x58: /*UART2*/
+ return clk_init_uart(priv, rate);
+ default:
+ return 0;
+ }
+}
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c
index 2b76371718..3deb08ac4a 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.c
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.c
@@ -135,6 +135,7 @@ static const struct udevice_id msm_clk_ids[] = {
{ .compatible = "qcom,gcc-apq8016" },
{ .compatible = "qcom,gcc-msm8996" },
{ .compatible = "qcom,gcc-apq8096" },
+ { .compatible = "qcom,gcc-sdm845" },
{ }
};
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/arch/arm/mach-snapdragon/clock-snapdragon.h
index 58fab40a2e..2ac53b538d 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.h
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Qualcomm APQ8016, APQ8096
+ * Qualcomm APQ8016, APQ8096, SDM845
*
* (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
*/
@@ -9,6 +9,7 @@
#define CFG_CLK_SRC_CXO (0 << 8)
#define CFG_CLK_SRC_GPLL0 (1 << 8)
+#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
#define CFG_CLK_SRC_MASK (7 << 8)
struct pll_vote_clk {
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h
new file mode 100644
index 0000000000..7165985bcd
--- /dev/null
+++ b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Qualcomm SDM845 sysmap
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ */
+#ifndef _MACH_SYSMAP_SDM845_H
+#define _MACH_SYSMAP_SDM845_H
+
+#define TLMM_BASE_ADDR (0x1010000)
+
+/* Strength (sdc1) */
+#define SDC1_HDRV_PULL_CTL_REG (TLMM_BASE_ADDR + 0x0012D000)
+
+/* Clocks: (from CLK_CTL_BASE) */
+#define GPLL0_STATUS (0x0000)
+#define APCS_GPLL_ENA_VOTE (0x52000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (0x52004)
+
+#define SDCC2_BCR (0x14000) /* block reset */
+#define SDCC2_APPS_CBCR (0x14004) /* branch control */
+#define SDCC2_AHB_CBCR (0x14008)
+#define SDCC2_CMD_RCGR (0x1400c)
+#define SDCC2_CFG_RCGR (0x14010)
+#define SDCC2_M (0x14014)
+#define SDCC2_N (0x14018)
+#define SDCC2_D (0x1401C)
+
+#define RCG2_CFG_REG 0x4
+#define M_REG 0x8
+#define N_REG 0xc
+#define D_REG 0x10
+
+#define SE9_AHB_CBCR (0x25004)
+#define SE9_UART_APPS_CBCR (0x29004)
+#define SE9_UART_APPS_CMD_RCGR (0x18148)
+#define SE9_UART_APPS_CFG_RCGR (0x1814C)
+#define SE9_UART_APPS_M (0x18150)
+#define SE9_UART_APPS_N (0x18154)
+#define SE9_UART_APPS_D (0x18158)
+
+#endif
diff --git a/arch/arm/mach-snapdragon/init_sdm845.c b/arch/arm/mach-snapdragon/init_sdm845.c
new file mode 100644
index 0000000000..5f53c21947
--- /dev/null
+++ b/arch/arm/mach-snapdragon/init_sdm845.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Common init part for boards based on SDM845
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ */
+
+#include <init.h>
+#include <env.h>
+#include <common.h>
+#include <asm/system.h>
+#include <asm/gpio.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+void reset_cpu(void)
+{
+ psci_system_reset();
+}
+
+__weak int board_init(void)
+{
+ return 0;
+}
+
+/* Check for vol- and power buttons */
+__weak int misc_init_r(void)
+{
+ struct udevice *pon;
+ struct gpio_desc resin;
+ int node, ret;
+
+ ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8998_pon@800", &pon);
+ if (ret < 0) {
+ printf("Failed to find PMIC pon node. Check device tree\n");
+ return 0;
+ }
+
+ node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
+ "key_vol_down");
+ if (node < 0) {
+ printf("Failed to find key_vol_down node. Check device tree\n");
+ return 0;
+ }
+ if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
+ &resin, 0)) {
+ printf("Failed to request key_vol_down button.\n");
+ return 0;
+ }
+ if (dm_gpio_get_value(&resin)) {
+ env_set("key_vol_down", "1");
+ printf("Volume down button pressed\n");
+ } else {
+ env_set("key_vol_down", "0");
+ }
+
+ node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
+ "key_power");
+ if (node < 0) {
+ printf("Failed to find key_power node. Check device tree\n");
+ return 0;
+ }
+ if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
+ &resin, 0)) {
+ printf("Failed to request key_power button.\n");
+ return 0;
+ }
+ if (dm_gpio_get_value(&resin)) {
+ env_set("key_power", "1");
+ printf("Power button pressed\n");
+ } else {
+ env_set("key_power", "0");
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-snapdragon/pinctrl-sdm845.c b/arch/arm/mach-snapdragon/pinctrl-sdm845.c
new file mode 100644
index 0000000000..40f2f012fa
--- /dev/null
+++ b/arch/arm/mach-snapdragon/pinctrl-sdm845.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm SDM845 pinctrl
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ */
+
+#include "pinctrl-snapdragon.h"
+#include <common.h>
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+ {"qup9", 1},
+ {"gpio", 0},
+};
+
+static const char *sdm845_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].name;
+}
+
+static const char *sdm845_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector);
+ return pin_name;
+}
+
+static unsigned int sdm845_get_function_mux(unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].val;
+}
+
+struct msm_pinctrl_data sdm845_data = {
+ .pin_count = 150,
+ .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+ .get_function_name = sdm845_get_function_name,
+ .get_function_mux = sdm845_get_function_mux,
+ .get_pin_name = sdm845_get_pin_name,
+};
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
index e6b87c3573..d1c560dd40 100644
--- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
+++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
@@ -116,6 +116,9 @@ static struct pinctrl_ops msm_pinctrl_ops = {
static const struct udevice_id msm_pinctrl_ids[] = {
{ .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data },
{ .compatible = "qcom,tlmm-apq8096", .data = (ulong)&apq8096_data },
+#ifdef CONFIG_SDM845
+ { .compatible = "qcom,tlmm-sdm845", .data = (ulong)&sdm845_data },
+#endif
{ }
};
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
index 61d466f4d8..ea524312a0 100644
--- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
+++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
@@ -27,5 +27,6 @@ struct pinctrl_function {
extern struct msm_pinctrl_data apq8016_data;
extern struct msm_pinctrl_data apq8096_data;
+extern struct msm_pinctrl_data sdm845_data;
#endif
diff --git a/arch/arm/mach-snapdragon/sysmap-sdm845.c b/arch/arm/mach-snapdragon/sysmap-sdm845.c
new file mode 100644
index 0000000000..721ac41166
--- /dev/null
+++ b/arch/arm/mach-snapdragon/sysmap-sdm845.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm SDM845 memory map
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankousk@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/armv8/mmu.h>
+
+static struct mm_region sdm845_mem_map[] = {
+ {
+ .virt = 0x0UL, /* Peripheral block */
+ .phys = 0x0UL, /* Peripheral block */
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ .virt = 0x80000000UL, /* DDR */
+ .phys = 0x80000000UL, /* DDR */
+ .size = 0x200000000UL, /* 8GiB - maximum allowed memory */
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = sdm845_mem_map;
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e27d106466..8cd688e8d2 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -764,6 +764,11 @@
vss-microvolts = <0>;
};
+ iommu: iommu@0 {
+ compatible = "sandbox,iommu";
+ #iommu-cells = <0>;
+ };
+
irq: irq {
compatible = "sandbox,irq";
interrupt-controller;
@@ -1226,6 +1231,7 @@
usb_1: usb@1 {
compatible = "sandbox,usb";
+ iommus = <&iommu>;
hub {
compatible = "usb-hub";
usb,device-class = <9>;
diff --git a/board/broadcom/bcmns3/ns3.c b/board/broadcom/bcmns3/ns3.c
index 758a358f54..32acf36784 100644
--- a/board/broadcom/bcmns3/ns3.c
+++ b/board/broadcom/bcmns3/ns3.c
@@ -196,7 +196,8 @@ int ft_board_setup(void *fdt, struct bd_info *bd)
{
u32 chimp_hs = CHIMP_HANDSHAKE_WAIT_TIMEOUT;
- gic_lpi_tables_init();
+ /* FIXME: Need to call gic_lpi_tables_init correctly now */
+ printf("%s: failed to init gic-lpi-tables\n", __func__);
/*
* Check for chimp handshake status.
diff --git a/board/samsung/axy17lte/Kconfig b/board/samsung/axy17lte/Kconfig
new file mode 100644
index 0000000000..2abf8e7acf
--- /dev/null
+++ b/board/samsung/axy17lte/Kconfig
@@ -0,0 +1,58 @@
+config SYS_CONFIG_NAME
+ string "Board configuration name"
+ default "exynos78x0-common.h"
+ help
+ This option contains information about board configuration name.
+ Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+ will be used for board configuration.
+
+if TARGET_A5Y17LTE
+config SYS_BOARD
+ default "axy17lte"
+ help
+ a5y17lte is a production board for SM-A520F phone on Exynos7880 SoC.
+
+config SYS_VENDOR
+ default "samsung"
+
+config SYS_CONFIG_NAME
+ default "a5y17lte"
+
+config EXYNOS7880
+ bool "Exynos 7880 SOC support"
+ default y
+endif
+
+if TARGET_A7Y17LTE
+config SYS_BOARD
+ default "axy17lte"
+ help
+ a5y17lte is a production board for SM-A520F phone on Exynos7880 SoC.
+
+config SYS_VENDOR
+ default "samsung"
+
+config SYS_CONFIG_NAME
+ default "a5y17lte"
+
+config EXYNOS7880
+ bool "Exynos 7880 SOC support"
+ default y
+endif
+
+if TARGET_A3Y17LTE
+config SYS_BOARD
+ default "axy17lte"
+ help
+ a3y17lte is a production board for SM-A520F phone on Exynos7880 SoC.
+
+config SYS_VENDOR
+ default "samsung"
+
+config SYS_CONFIG_NAME
+ default "a3y17lte"
+
+config EXYNOS7870
+ bool "Exynos 7870 SOC support"
+ default y
+endif
diff --git a/board/samsung/axy17lte/MAINTAINERS b/board/samsung/axy17lte/MAINTAINERS
new file mode 100644
index 0000000000..13feba62a7
--- /dev/null
+++ b/board/samsung/axy17lte/MAINTAINERS
@@ -0,0 +1,8 @@
+Samsung A series 2017 phones Board
+M: Dzmitry Sankouski <dsankouski@gmail.com>
+S: Maintained
+F: board/samsung/axy17lte/
+F: include/configs/exynos78x0-common.h
+F: configs/a3y17lte_defconfig
+F: configs/a5y17lte_defconfig
+F: configs/a7y17lte_defconfig
diff --git a/board/samsung/axy17lte/Makefile b/board/samsung/axy17lte/Makefile
new file mode 100644
index 0000000000..4e11f289dc
--- /dev/null
+++ b/board/samsung/axy17lte/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+obj-y += axy17lte.o
diff --git a/board/samsung/axy17lte/axy17lte.c b/board/samsung/axy17lte/axy17lte.c
new file mode 100644
index 0000000000..c38297a05b
--- /dev/null
+++ b/board/samsung/axy17lte/axy17lte.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Samsung A5Y17 and A3Y17 LTE boards based on Exynos 7880 and Exynos 7870 SoCs
+ */
+
+#include <common.h>
+
+int exynos_init(void)
+{
+ return 0;
+}
diff --git a/board/samsung/starqltechn/Kconfig b/board/samsung/starqltechn/Kconfig
new file mode 100644
index 0000000000..0eea666d03
--- /dev/null
+++ b/board/samsung/starqltechn/Kconfig
@@ -0,0 +1,22 @@
+if TARGET_STARQLTECHN
+
+config SYS_BOARD
+ default "starqltechn"
+ help
+ starqltechn is a production board for S9 and S9+ phones(SM-G96x0) phones based on SDM845 SoC.
+
+config SYS_CONFIG_NAME
+ string "Board configuration name"
+ default "sdm845"
+ help
+ This option contains information about board configuration name.
+ Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+ will be used for board configuration.
+
+config SYS_VENDOR
+ default "samsung"
+
+config SYS_CONFIG_NAME
+ default "starqltechn"
+
+endif
diff --git a/board/samsung/starqltechn/MAINTAINERS b/board/samsung/starqltechn/MAINTAINERS
new file mode 100644
index 0000000000..135cafdd69
--- /dev/null
+++ b/board/samsung/starqltechn/MAINTAINERS
@@ -0,0 +1,6 @@
+Samsung S9 (SM-G9600)(starqltechn) Board
+M: Dzmitry Sankouski <dsankouski@gmail.com>
+S: Maintained
+F: board/samsung/starqltechn/
+F: include/configs/starqltechn.h
+F: configs/starqltechn_defconfig
diff --git a/board/samsung/starqltechn/Makefile b/board/samsung/starqltechn/Makefile
new file mode 100644
index 0000000000..c38c0b4710
--- /dev/null
+++ b/board/samsung/starqltechn/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+#
+# This empty file prevents make error.
+# Board logic defined in board/qualcomm/common/sdm845.c, no custom logic for starqltechn so far.
+#
+
+obj-y += starqltechn.o
diff --git a/board/samsung/starqltechn/starqltechn.c b/board/samsung/starqltechn/starqltechn.c
new file mode 100644
index 0000000000..f2cdb4eec2
--- /dev/null
+++ b/board/samsung/starqltechn/starqltechn.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * This empty file prevents make linking error.
+ * No custom logic for starqltechn so far.
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ */
+
+void nooop(void) {}
diff --git a/configs/a3y17lte_defconfig b/configs/a3y17lte_defconfig
new file mode 100644
index 0000000000..36404d15f7
--- /dev/null
+++ b/configs/a3y17lte_defconfig
@@ -0,0 +1,24 @@
+CONFIG_ARM=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS7=y
+CONFIG_S5P=y
+CONFIG_TARGET_A3Y17LTE=y
+# This option is a number of 256MB DRAM banks, i.e. (ram size) / 256MB.
+# Used in samsung common board dram_init function.
+CONFIG_NR_DRAM_BANKS=8
+CONFIG_SYS_CONFIG_NAME="exynos78x0-common"
+CONFIG_DEFAULT_DEVICE_TREE="exynos78x0-axy17lte"
+CONFIG_SYS_TEXT_BASE=0x40001000
+CONFIG_SYS_LOAD_ADDR=0x40001000
+CONFIG_HUSH_PARSER=y
+CONFIG_FIT=y
+CONFIG_BOARD_EARLY_INIT_F=n
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_CMD_GPIO=y
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_CMD_I2C=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_PINCTRL_EXYNOS78x0=y
+CONFIG_PINCTRL_EXYNOS=y
+# CONFIG_DEBUG_UART_S5P=y
+# CONFIG_DEBUG_UART_BASE=0x13820000 \ No newline at end of file
diff --git a/configs/a5y17lte_defconfig b/configs/a5y17lte_defconfig
new file mode 100644
index 0000000000..273ad1078e
--- /dev/null
+++ b/configs/a5y17lte_defconfig
@@ -0,0 +1,24 @@
+CONFIG_ARM=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS7=y
+CONFIG_S5P=y
+CONFIG_TARGET_A5Y17LTE=y
+# This option is a number of 256MB DRAM banks, i.e. (ram size) / 256MB.
+# Used in samsung common board dram_init function.
+CONFIG_NR_DRAM_BANKS=12
+CONFIG_SYS_CONFIG_NAME="exynos78x0-common"
+CONFIG_DEFAULT_DEVICE_TREE="exynos78x0-axy17lte"
+CONFIG_SYS_TEXT_BASE=0x40001000
+CONFIG_SYS_LOAD_ADDR=0x40001000
+CONFIG_HUSH_PARSER=y
+CONFIG_FIT=y
+CONFIG_BOARD_EARLY_INIT_F=n
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_CMD_GPIO=y
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_CMD_I2C=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_PINCTRL_EXYNOS78x0=y
+CONFIG_PINCTRL_EXYNOS=y
+# CONFIG_DEBUG_UART_S5P=y
+# CONFIG_DEBUG_UART_BASE=0x13820000 \ No newline at end of file
diff --git a/configs/a7y17lte_defconfig b/configs/a7y17lte_defconfig
new file mode 100644
index 0000000000..f544f629ef
--- /dev/null
+++ b/configs/a7y17lte_defconfig
@@ -0,0 +1,24 @@
+CONFIG_ARM=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS7=y
+CONFIG_S5P=y
+CONFIG_TARGET_A7Y17LTE=y
+# This option is a number of 256MB DRAM banks, i.e. (ram size) / 256MB.
+# Used in samsung common board dram_init function.
+CONFIG_NR_DRAM_BANKS=12
+CONFIG_SYS_CONFIG_NAME="exynos78x0-common"
+CONFIG_DEFAULT_DEVICE_TREE="exynos78x0-axy17lte"
+CONFIG_SYS_TEXT_BASE=0x40001000
+CONFIG_SYS_LOAD_ADDR=0x40001000
+CONFIG_HUSH_PARSER=y
+CONFIG_FIT=y
+CONFIG_BOARD_EARLY_INIT_F=n
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_CMD_GPIO=y
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_CMD_I2C=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_PINCTRL_EXYNOS78x0=y
+CONFIG_PINCTRL_EXYNOS=y
+# CONFIG_DEBUG_UART_S5P=y
+# CONFIG_DEBUG_UART_BASE=0x13820000 \ No newline at end of file
diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
new file mode 100644
index 0000000000..d71cbfd043
--- /dev/null
+++ b/configs/apple_m1_defconfig
@@ -0,0 +1,20 @@
+CONFIG_ARM=y
+CONFIG_ARCH_APPLE=y
+CONFIG_DEFAULT_DEVICE_TREE="t8103-j274"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_MMC is not set
+# CONFIG_NET is not set
+CONFIG_VIDEO_SIMPLE=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="usb start"
+CONFIG_SYS_LOAD_ADDR=0x880000000
+# CONFIG_GENERATE_SMBIOS_TABLE is not set
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_BASE=0x235200000
+CONFIG_DEBUG_UART_CLOCK=240000
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 838280e147..45828899f2 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -130,6 +130,7 @@ CONFIG_SPL_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_CROS_EC_KEYB=y
CONFIG_I8042_KEYB=y
+CONFIG_IOMMU=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index d07a7f302e..93858574f8 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -168,6 +168,7 @@ CONFIG_SPL_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_CROS_EC_KEYB=y
CONFIG_I8042_KEYB=y
+CONFIG_IOMMU=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 5980c8610e..edfdac8b02 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -107,6 +107,7 @@ CONFIG_SPL_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_CROS_EC_KEYB=y
CONFIG_I8042_KEYB=y
+CONFIG_IOMMU=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig
index 238604f5cd..ab378494d2 100644
--- a/configs/sandbox_noinst_defconfig
+++ b/configs/sandbox_noinst_defconfig
@@ -128,6 +128,7 @@ CONFIG_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_CROS_EC_KEYB=y
CONFIG_I8042_KEYB=y
+CONFIG_IOMMU=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index b9da8dc8e9..9a0a678c03 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -130,6 +130,7 @@ CONFIG_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_CROS_EC_KEYB=y
CONFIG_I8042_KEYB=y
+CONFIG_IOMMU=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
diff --git a/configs/starqltechn_defconfig b/configs/starqltechn_defconfig
new file mode 100644
index 0000000000..f57bb859cc
--- /dev/null
+++ b/configs/starqltechn_defconfig
@@ -0,0 +1,24 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_SNAPDRAGON=y
+CONFIG_SYS_TEXT_BASE=0x80000000
+CONFIG_SYS_MALLOC_LEN=0x81f000
+CONFIG_DEFAULT_DEVICE_TREE="starqltechn"
+CONFIG_TARGET_STARQLTECHN=y
+CONFIG_IDENT_STRING="\nSamsung S9 SM-G9600"
+CONFIG_SYS_LOAD_ADDR=0x80000000
+CONFIG_USE_PREBOOT=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_GPIO=y
+# CONFIG_NET is not set
+# CONFIG_DM_STDIO is not set
+CONFIG_CLK=y
+CONFIG_MSM_GPIO=y
+CONFIG_PM8916_GPIO=y
+CONFIG_PINCTRL=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_PM8916=y
+CONFIG_MSM_GENI_SERIAL=y
+CONFIG_SPMI_MSM=y
diff --git a/doc/board/apple/index.rst b/doc/board/apple/index.rst
new file mode 100644
index 0000000000..8446847818
--- /dev/null
+++ b/doc/board/apple/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Apple
+=====
+
+.. toctree::
+ :maxdepth: 2
+
+ m1
diff --git a/doc/board/apple/m1.rst b/doc/board/apple/m1.rst
new file mode 100644
index 0000000000..9fa21767c9
--- /dev/null
+++ b/doc/board/apple/m1.rst
@@ -0,0 +1,59 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+U-Boot for Apple Silicon Macs
+=============================
+
+Allows Apple Silicon Macs to boot U-Boot via the m1n1 bootloader
+developed by the Asahi Linux project. At this point the machines with
+the following SoCs work:
+
+ - Apple M1 SoC
+
+On these SoCs the following hardware is supported:
+
+ - S5L serial port
+ - Framebuffer
+ - USB 3.1 Type-C ports
+
+Device trees are currently provided for the M1 Mac mini (2020, J274)
+and M1 MacBook Pro 13" (2020, J293). The M1 MacBook Air (2020) is
+expected to work with the J293 device tree. The M1 iMac (2021) may
+work with the J274 device tree.
+
+Building U-Boot
+---------------
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=aarch64-none-elf-
+ $ make apple_m1_defconfig
+ $ make
+
+This will build ``u-boot-nodtb.bin`` as well as devices trees for some
+of the supported machines. These device trees can be found in the
+``arch/arm/dts`` subdirectory of your build.
+
+Image creation
+--------------
+
+In order to run U-Boot on an Apple Silicon Mac, U-Boot has to be used
+as a payload for the m1n1 bootloader. Instructions for building m1n1
+can be found here:
+
+ https://github.com/AsahiLinux/docs/wiki/SW%3Am1n1
+
+.. code-block:: bash
+
+ $ cat m1n1.macho t8103-j274.dtb u-boot-nodtb.bin > u-boot.macho
+
+This uses ``u-boot-nodtb.bin`` as the device tree is passed to U-Boot
+by m1n1 after making some adjustments.
+
+Image installation
+------------------
+
+Instructions on how to install U-Boot on your Mac can be found at:
+
+ https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart
+
+Just replace ``m1n1.macho`` with ``u-boot.macho`` in the instructions.
diff --git a/doc/board/index.rst b/doc/board/index.rst
index aa397ab942..74ea33e081 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -10,6 +10,7 @@ Board-specific doc
advantech/index
AndesTech/index
amlogic/index
+ apple/index
atmel/index
congatec/index
coreboot/index
@@ -22,6 +23,7 @@ Board-specific doc
openpiton/index
qualcomm/index
rockchip/index
+ samsung/index
siemens/index
sifive/index
sipeed/index
diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst
index f7e0aa9298..10b98214e9 100644
--- a/doc/board/qualcomm/index.rst
+++ b/doc/board/qualcomm/index.rst
@@ -7,3 +7,4 @@ Qualcomm
:maxdepth: 2
dragonboard410c
+ sdm845
diff --git a/doc/board/qualcomm/sdm845.rst b/doc/board/qualcomm/sdm845.rst
new file mode 100644
index 0000000000..cd46cbe9cf
--- /dev/null
+++ b/doc/board/qualcomm/sdm845.rst
@@ -0,0 +1,38 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Dzmitry Sankouski <dsankouski@gmail.com>
+
+Snapdragon 845
+================
+
+About this
+----------
+This document describes the information about Qualcomm Snapdragon 845
+supported boards and it's usage steps.
+
+SDM845 - hi-end qualcomm chip, introduced in late 2017.
+Mostly used in flagship phones and tablets of 2018.
+
+U-Boot can be used as a replacement for Qualcomm's original ABL (UEFI) bootloader.
+It is loaded as an Android boot image through ABL
+
+Installation
+------------
+First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for your board::
+
+ $ export CROSS_COMPILE=<aarch64 toolchain prefix>
+ $ make <your board name here, see Boards section>_defconfig
+ $ make
+
+This will build ``u-boot.bin`` in the configured output directory.
+
+Boards
+------------
+starqlte
+^^^^^^^^^^^^
+
+The starqltechn is a production board for Samsung S9 (SM-G9600) phone,
+based on the Qualcomm SDM845 SoC.
+
+More information can be found on the `Samsung S9 page`_.
+
+.. _Samsung S9 page: https://en.wikipedia.org/wiki/Samsung_Galaxy_S9
diff --git a/doc/board/samsung/axy17lte.rst b/doc/board/samsung/axy17lte.rst
new file mode 100644
index 0000000000..511cd57a22
--- /dev/null
+++ b/doc/board/samsung/axy17lte.rst
@@ -0,0 +1,94 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Dzmitry Sankouski <dsankouski@gmail.com>
+
+Samsung 2017 A series phones
+============================
+
+About this
+----------
+This document describes the information about Samsung A(7/5/3) 2017 midrange
+phones and u-boot usage steps.
+
+U-Boot can be used as a chain-loaded bootloader to replace Samsung's original SBOOT bootloader.
+It is loaded as an Android boot image through SBOOT.
+
+Phone specs
+-----------
+A3 (SM-320) (a3y17lte)
+^^^^^^^^^^^^^^^^^^^^^^
+- 4.7 AMOLED display
+- Exynos 7870 SoC
+- 16GB flash
+- 2GB RAM
+
+.. A3 2017 wiki page: https://en.wikipedia.org/wiki/Samsung_Galaxy_A3_(2017)
+
+A5 (SM-520) (a5y17lte)
+^^^^^^^^^^^^^^^^^^^^^^
+- 5.2 AMOLED display
+- Exynos 7880 SoC
+- 32GB flash
+- 3GB RAM
+
+.. A5 2017 wiki page: https://en.wikipedia.org/wiki/Samsung_Galaxy_A5_(2017)
+
+A7 (SM-720) (a5y17lte)
+^^^^^^^^^^^^^^^^^^^^^^
+- 5.7 AMOLED display
+- Exynos 7880 SoC
+- 32GB flash
+- 3GB RAM
+
+.. A7 2017 wiki page: https://en.wikipedia.org/wiki/Samsung_Galaxy_A7_(2017)
+
+Installation
+------------
+
+Building u-boot
+^^^^^^^^^^^^^^^
+
+First, setup ``CROSS_COMPILE`` for aarch64.
+Then, build U-Boot for your phone, for example ``a5y17lte``::
+
+ $ export CROSS_COMPILE=<aarch64 toolchain prefix>
+ $ make a5y17lte_defconfig
+ $ make
+
+This will build ``u-boot.bin`` in the configured output directory.
+
+Payload
+^^^^^^^
+What is a payload?
+""""""""""""""""""
+A payload file is a file to be used instead of linux kernel in android boot image.
+This file will be loaded into memory, and executed by SBOOT,
+and is therefore SBOOT's payload.
+It may be pure u-boot (with loading u-boot's payload from flash in mind),
+or u-boot + u-boot's payload.
+
+It should be kept in mind, that SBOOT binary patches it's payload after loading
+in address range 0x401f8550-0x401f9280. Given SBOOT loads payload to 0x40001000,
+a range of 0x1f7550-0x1f8280 (2061648-2065024) in a payload file
+will be corrupted after loading to RAM.
+
+Creating payload file
+"""""""""""""""""""""
+- Assemble FIT image for your kernel
+- Create a file for u-boot payload ``touch sboot-payload``
+- Write zeroes till 0x200000 address to be sure SBOOT won't corrupt your info
+ ``dd if=/dev/zero of=sboot-payload bs=$((0x200000)) count=1``
+- Write u-boot to the start of the payload ``dd if=<u-boot.bin path> of=sboot-payload``
+- Write FIT image to payload from 0x200000 address
+ ``dd if=<FIT image path> of=sboot-payload seek=1 bs=2M``
+
+Creating android boot image
+"""""""""""""""""""""""""""
+Once payload created, it's time for android image::
+
+ mkbootimg --base 0x40000000 --kernel_offset 0x00000000 --ramdisk_offset 0x01000000 --tags_offset 0x00000100 --pagesize 2048 --second_offset 0x00f00000 --kernel <sboot-payload path> -o uboot.img
+
+Note, that stock Samsung bootloader ignores offsets, set in mkbootimg.
+
+Flashing
+""""""""
+Flash like regular android boot image.
diff --git a/doc/board/samsung/index.rst b/doc/board/samsung/index.rst
new file mode 100644
index 0000000000..c904372dff
--- /dev/null
+++ b/doc/board/samsung/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Samsung
+========
+
+.. toctree::
+ :maxdepth: 2
+
+ axy17lte
diff --git a/doc/device-tree-bindings/iommu/iommu.txt b/doc/device-tree-bindings/iommu/iommu.txt
new file mode 100644
index 0000000000..26ba9e530f
--- /dev/null
+++ b/doc/device-tree-bindings/iommu/iommu.txt
@@ -0,0 +1,206 @@
+This document describes the generic device tree binding for IOMMUs and their
+master(s).
+
+
+IOMMU device node:
+==================
+
+An IOMMU can provide the following services:
+
+* Remap address space to allow devices to access physical memory ranges that
+ they otherwise wouldn't be capable of accessing.
+
+ Example: 32-bit DMA to 64-bit physical addresses
+
+* Implement scatter-gather at page level granularity so that the device does
+ not have to.
+
+* Provide system protection against "rogue" DMA by forcing all accesses to go
+ through the IOMMU and faulting when encountering accesses to unmapped
+ address regions.
+
+* Provide address space isolation between multiple contexts.
+
+ Example: Virtualization
+
+Device nodes compatible with this binding represent hardware with some of the
+above capabilities.
+
+IOMMUs can be single-master or multiple-master. Single-master IOMMU devices
+typically have a fixed association to the master device, whereas multiple-
+master IOMMU devices can translate accesses from more than one master.
+
+The device tree node of the IOMMU device's parent bus must contain a valid
+"dma-ranges" property that describes how the physical address space of the
+IOMMU maps to memory. An empty "dma-ranges" property means that there is a
+1:1 mapping from IOMMU to memory.
+
+Required properties:
+--------------------
+- #iommu-cells: The number of cells in an IOMMU specifier needed to encode an
+ address.
+
+The meaning of the IOMMU specifier is defined by the device tree binding of
+the specific IOMMU. Below are a few examples of typical use-cases:
+
+- #iommu-cells = <0>: Single master IOMMU devices are not configurable and
+ therefore no additional information needs to be encoded in the specifier.
+ This may also apply to multiple master IOMMU devices that do not allow the
+ association of masters to be configured. Note that an IOMMU can by design
+ be multi-master yet only expose a single master in a given configuration.
+ In such cases the number of cells will usually be 1 as in the next case.
+- #iommu-cells = <1>: Multiple master IOMMU devices may need to be configured
+ in order to enable translation for a given master. In such cases the single
+ address cell corresponds to the master device's ID. In some cases more than
+ one cell can be required to represent a single master ID.
+- #iommu-cells = <4>: Some IOMMU devices allow the DMA window for masters to
+ be configured. The first cell of the address in this may contain the master
+ device's ID for example, while the second cell could contain the start of
+ the DMA window for the given device. The length of the DMA window is given
+ by the third and fourth cells.
+
+Note that these are merely examples and real-world use-cases may use different
+definitions to represent their individual needs. Always refer to the specific
+IOMMU binding for the exact meaning of the cells that make up the specifier.
+
+
+IOMMU master node:
+==================
+
+Devices that access memory through an IOMMU are called masters. A device can
+have multiple master interfaces (to one or more IOMMU devices).
+
+Required properties:
+--------------------
+- iommus: A list of phandle and IOMMU specifier pairs that describe the IOMMU
+ master interfaces of the device. One entry in the list describes one master
+ interface of the device.
+
+When an "iommus" property is specified in a device tree node, the IOMMU will
+be used for address translation. If a "dma-ranges" property exists in the
+device's parent node it will be ignored. An exception to this rule is if the
+referenced IOMMU is disabled, in which case the "dma-ranges" property of the
+parent shall take effect. Note that merely disabling a device tree node does
+not guarantee that the IOMMU is really disabled since the hardware may not
+have a means to turn off translation. But it is invalid in such cases to
+disable the IOMMU's device tree node in the first place because it would
+prevent any driver from properly setting up the translations.
+
+Optional properties:
+--------------------
+- pasid-num-bits: Some masters support multiple address spaces for DMA, by
+ tagging DMA transactions with an address space identifier. By default,
+ this is 0, which means that the device only has one address space.
+
+- dma-can-stall: When present, the master can wait for a transaction to
+ complete for an indefinite amount of time. Upon translation fault some
+ IOMMUs, instead of aborting the translation immediately, may first
+ notify the driver and keep the transaction in flight. This allows the OS
+ to inspect the fault and, for example, make physical pages resident
+ before updating the mappings and completing the transaction. Such IOMMU
+ accepts a limited number of simultaneous stalled transactions before
+ having to either put back-pressure on the master, or abort new faulting
+ transactions.
+
+ Firmware has to opt-in stalling, because most buses and masters don't
+ support it. In particular it isn't compatible with PCI, where
+ transactions have to complete before a time limit. More generally it
+ won't work in systems and masters that haven't been designed for
+ stalling. For example the OS, in order to handle a stalled transaction,
+ may attempt to retrieve pages from secondary storage in a stalled
+ domain, leading to a deadlock.
+
+
+Notes:
+======
+
+One possible extension to the above is to use an "iommus" property along with
+a "dma-ranges" property in a bus device node (such as PCI host bridges). This
+can be useful to describe how children on the bus relate to the IOMMU if they
+are not explicitly listed in the device tree (e.g. PCI devices). However, the
+requirements of that use-case haven't been fully determined yet. Implementing
+this is therefore not recommended without further discussion and extension of
+this binding.
+
+
+Examples:
+=========
+
+Single-master IOMMU:
+--------------------
+
+ iommu {
+ #iommu-cells = <0>;
+ };
+
+ master {
+ iommus = <&{/iommu}>;
+ };
+
+Multiple-master IOMMU with fixed associations:
+----------------------------------------------
+
+ /* multiple-master IOMMU */
+ iommu {
+ /*
+ * Masters are statically associated with this IOMMU and share
+ * the same address translations because the IOMMU does not
+ * have sufficient information to distinguish between masters.
+ *
+ * Consequently address translation is always on or off for
+ * all masters at any given point in time.
+ */
+ #iommu-cells = <0>;
+ };
+
+ /* static association with IOMMU */
+ master@1 {
+ reg = <1>;
+ iommus = <&{/iommu}>;
+ };
+
+ /* static association with IOMMU */
+ master@2 {
+ reg = <2>;
+ iommus = <&{/iommu}>;
+ };
+
+Multiple-master IOMMU:
+----------------------
+
+ iommu {
+ /* the specifier represents the ID of the master */
+ #iommu-cells = <1>;
+ };
+
+ master@1 {
+ /* device has master ID 42 in the IOMMU */
+ iommus = <&{/iommu} 42>;
+ };
+
+ master@2 {
+ /* device has master IDs 23 and 24 in the IOMMU */
+ iommus = <&{/iommu} 23>, <&{/iommu} 24>;
+ };
+
+Multiple-master IOMMU with configurable DMA window:
+---------------------------------------------------
+
+ / {
+ iommu {
+ /*
+ * One cell for the master ID and one cell for the
+ * address of the DMA window. The length of the DMA
+ * window is encoded in two cells.
+ *
+ * The DMA window is the range addressable by the
+ * master (i.e. the I/O virtual address space).
+ */
+ #iommu-cells = <4>;
+ };
+
+ master {
+ /* master ID 42, 4 GiB DMA window starting at 0 */
+ iommus = <&{/iommu} 42 0 0x1 0x0>;
+ };
+ };
diff --git a/doc/device-tree-bindings/serial/msm-geni-serial.txt b/doc/device-tree-bindings/serial/msm-geni-serial.txt
new file mode 100644
index 0000000000..9eadc2561b
--- /dev/null
+++ b/doc/device-tree-bindings/serial/msm-geni-serial.txt
@@ -0,0 +1,6 @@
+Qualcomm GENI UART
+
+Required properties:
+- compatible: must be "qcom,msm-geni-uart"
+- reg: start address and size of the registers
+- clock: interface clock (must accept baudrate as a frequency)
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 417d6f88c2..b26ca8cf70 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig"
+
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 4cbc40787d..4e7cf28440 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -102,6 +102,7 @@ obj-y += mtd/
obj-y += pwm/
obj-y += reset/
obj-y += input/
+obj-y += iommu/
# SOC specific infrastructure drivers.
obj-y += smem/
obj-y += thermal/
diff --git a/drivers/core/device.c b/drivers/core/device.c
index d7a778a241..efd07176e3 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -28,6 +28,7 @@
#include <dm/uclass.h>
#include <dm/uclass-internal.h>
#include <dm/util.h>
+#include <iommu.h>
#include <linux/err.h>
#include <linux/list.h>
#include <power-domain.h>
@@ -543,6 +544,13 @@ int device_probe(struct udevice *dev)
goto fail;
}
+ if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
+ (device_get_uclass_id(dev) != UCLASS_IOMMU)) {
+ ret = dev_iommu_enable(dev);
+ if (ret)
+ goto fail;
+ }
+
ret = device_get_dma_constraints(dev);
if (ret)
goto fail;
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index e1ff84c1c0..a3c3cd7824 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -120,6 +120,7 @@ static const struct udevice_id msm_gpio_ids[] = {
{ .compatible = "qcom,msm8916-pinctrl" },
{ .compatible = "qcom,apq8016-pinctrl" },
{ .compatible = "qcom,ipq4019-pinctrl" },
+ { .compatible = "qcom,sdm845-pinctrl" },
{ }
};
diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/pm8916_gpio.c
index 40b0f2578b..7ad95784a8 100644
--- a/drivers/gpio/pm8916_gpio.c
+++ b/drivers/gpio/pm8916_gpio.c
@@ -202,6 +202,7 @@ static int pm8916_gpio_of_to_plat(struct udevice *dev)
static const struct udevice_id pm8916_gpio_ids[] = {
{ .compatible = "qcom,pm8916-gpio" },
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
+ { .compatible = "qcom,pm8998-gpio" },
{ }
};
@@ -266,7 +267,7 @@ static int pm8941_pwrkey_probe(struct udevice *dev)
return log_msg_ret("bad type", -ENXIO);
reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
- if (reg != 0x1)
+ if ((reg & 0x5) == 0)
return log_msg_ret("bad subtype", -ENXIO);
return 0;
@@ -287,11 +288,12 @@ static int pm8941_pwrkey_of_to_plat(struct udevice *dev)
static const struct udevice_id pm8941_pwrkey_ids[] = {
{ .compatible = "qcom,pm8916-pwrkey" },
{ .compatible = "qcom,pm8994-pwrkey" },
+ { .compatible = "qcom,pm8998-pwrkey" },
{ }
};
-U_BOOT_DRIVER(pwrkey_pm8941) = {
- .name = "pwrkey_pm8916",
+U_BOOT_DRIVER(pwrkey_pm89xx) = {
+ .name = "pwrkey_pm89xx",
.id = UCLASS_GPIO,
.of_match = pm8941_pwrkey_ids,
.of_to_plat = pm8941_pwrkey_of_to_plat,
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 76f35ac5d9..06ed585f3d 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -357,6 +357,7 @@ static const struct udevice_id exynos_gpio_ids[] = {
{ .compatible = "samsung,exynos4x12-pinctrl" },
{ .compatible = "samsung,exynos5250-pinctrl" },
{ .compatible = "samsung,exynos5420-pinctrl" },
+ { .compatible = "samsung,exynos78x0-gpio" },
{ }
};
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
new file mode 100644
index 0000000000..dabc1f900d
--- /dev/null
+++ b/drivers/iommu/Kconfig
@@ -0,0 +1,27 @@
+#
+# IOMMU devices
+#
+
+menu "IOMMU device drivers"
+
+config IOMMU
+ bool "Enable Driver Model for IOMMU drivers"
+ depends on DM
+ help
+ Enable driver model for IOMMU devices. An IOMMU maps device
+ virtiual memory addresses to physical addresses. Devices
+ that sit behind an IOMMU can typically only access physical
+ memory if the IOMMU has been programmed to allow access to
+ that memory.
+
+config APPLE_DART
+ bool "Apple DART support"
+ depends on IOMMU && ARCH_APPLE
+ default y
+ help
+ Enable support for the DART on Apple SoCs. The DART is Apple's
+ IOMMU implementation. The driver performs the necessary
+ configuration to put the DART into bypass mode such that it can
+ be used transparently by U-Boot.
+
+endmenu
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
new file mode 100644
index 0000000000..e3e0900e17
--- /dev/null
+++ b/drivers/iommu/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-$(CONFIG_IOMMU) += iommu-uclass.o
+
+obj-$(CONFIG_APPLE_DART) += apple_dart.o
+obj-$(CONFIG_SANDBOX) += sandbox_iommu.o
diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c
new file mode 100644
index 0000000000..ff8c5fa62c
--- /dev/null
+++ b/drivers/iommu/apple_dart.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <asm/io.h>
+
+#define DART_PARAMS2 0x0004
+#define DART_PARAMS2_BYPASS_SUPPORT BIT(0)
+#define DART_TLB_OP 0x0020
+#define DART_TLB_OP_OPMASK (0xfff << 20)
+#define DART_TLB_OP_FLUSH (0x001 << 20)
+#define DART_TLB_OP_BUSY BIT(2)
+#define DART_TLB_OP_SIDMASK 0x0034
+#define DART_ERROR_STATUS 0x0040
+#define DART_TCR(sid) (0x0100 + 4 * (sid))
+#define DART_TCR_TRANSLATE_ENABLE BIT(7)
+#define DART_TCR_BYPASS_DART BIT(8)
+#define DART_TCR_BYPASS_DAPF BIT(12)
+#define DART_TTBR(sid, idx) (0x0200 + 16 * (sid) + 4 * (idx))
+#define DART_TTBR_VALID BIT(31)
+#define DART_TTBR_SHIFT 12
+
+static int apple_dart_probe(struct udevice *dev)
+{
+ void *base;
+ int sid, i;
+
+ base = dev_read_addr_ptr(dev);
+ if (!base)
+ return -EINVAL;
+
+ u32 params2 = readl(base + DART_PARAMS2);
+ if (params2 & DART_PARAMS2_BYPASS_SUPPORT) {
+ for (sid = 0; sid < 16; sid++) {
+ writel(DART_TCR_BYPASS_DART | DART_TCR_BYPASS_DAPF,
+ base + DART_TCR(sid));
+ for (i = 0; i < 4; i++)
+ writel(0, base + DART_TTBR(sid, i));
+ }
+ }
+
+ return 0;
+}
+
+static const struct udevice_id apple_dart_ids[] = {
+ { .compatible = "apple,t8103-dart" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(apple_dart) = {
+ .name = "apple_dart",
+ .id = UCLASS_IOMMU,
+ .of_match = apple_dart_ids,
+ .probe = apple_dart_probe
+};
diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c
new file mode 100644
index 0000000000..ed917b3c3e
--- /dev/null
+++ b/drivers/iommu/iommu-uclass.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#define LOG_CATEGORY UCLASS_IOMMU
+
+#include <common.h>
+#include <dm.h>
+
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA))
+int dev_iommu_enable(struct udevice *dev)
+{
+ struct ofnode_phandle_args args;
+ struct udevice *dev_iommu;
+ int i, count, ret = 0;
+
+ count = dev_count_phandle_with_args(dev, "iommus",
+ "#iommu-cells", 0);
+ for (i = 0; i < count; i++) {
+ ret = dev_read_phandle_with_args(dev, "iommus",
+ "#iommu-cells", 0, i, &args);
+ if (ret) {
+ debug("%s: dev_read_phandle_with_args failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = uclass_get_device_by_ofnode(UCLASS_IOMMU, args.node,
+ &dev_iommu);
+ if (ret) {
+ debug("%s: uclass_get_device_by_ofnode failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+UCLASS_DRIVER(iommu) = {
+ .id = UCLASS_IOMMU,
+ .name = "iommu",
+};
diff --git a/drivers/iommu/sandbox_iommu.c b/drivers/iommu/sandbox_iommu.c
new file mode 100644
index 0000000000..c8161a40ae
--- /dev/null
+++ b/drivers/iommu/sandbox_iommu.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+
+static const struct udevice_id sandbox_iommu_ids[] = {
+ { .compatible = "sandbox,iommu" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(sandbox_iommu) = {
+ .name = "sandbox_iommu",
+ .id = UCLASS_IOMMU,
+ .of_match = sandbox_iommu_ids,
+};
diff --git a/drivers/pinctrl/exynos/Kconfig b/drivers/pinctrl/exynos/Kconfig
index 84b6aaae09..a60f49869b 100644
--- a/drivers/pinctrl/exynos/Kconfig
+++ b/drivers/pinctrl/exynos/Kconfig
@@ -8,3 +8,11 @@ config PINCTRL_EXYNOS7420
help
Support pin multiplexing and pin configuration control on
Samsung's Exynos7420 SoC.
+
+config PINCTRL_EXYNOS78x0
+ bool "Samsung Exynos78x0 pinctrl driver"
+ depends on ARCH_EXYNOS && PINCTRL_FULL
+ select PINCTRL_EXYNOS
+ help
+ Support pin multiplexing and pin configuration control on
+ Samsung's Exynos78x0 SoC.
diff --git a/drivers/pinctrl/exynos/Makefile b/drivers/pinctrl/exynos/Makefile
index 6a14a474bf..07db970ca9 100644
--- a/drivers/pinctrl/exynos/Makefile
+++ b/drivers/pinctrl/exynos/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
obj-$(CONFIG_PINCTRL_EXYNOS7420) += pinctrl-exynos7420.o
+obj-$(CONFIG_PINCTRL_EXYNOS78x0) += pinctrl-exynos78x0.o
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.c b/drivers/pinctrl/exynos/pinctrl-exynos.c
index 2640c8fcef..898185479b 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.c
@@ -5,6 +5,7 @@
* Thomas Abraham <thomas.ab@samsung.com>
*/
+#include <log.h>
#include <common.h>
#include <dm.h>
#include <errno.h>
@@ -38,9 +39,9 @@ static unsigned long pin_to_bank_base(struct udevice *dev, const char *pin_name,
u32 *pin)
{
struct exynos_pinctrl_priv *priv = dev_get_priv(dev);
- const struct samsung_pin_ctrl *pin_ctrl = priv->pin_ctrl;
- const struct samsung_pin_bank_data *bank_data = pin_ctrl->pin_banks;
- u32 nr_banks = pin_ctrl->nr_banks, idx = 0;
+ const struct samsung_pin_ctrl *pin_ctrl_array = priv->pin_ctrl;
+ const struct samsung_pin_bank_data *bank_data;
+ u32 nr_banks, pin_ctrl_idx = 0, idx = 0, bank_base;
char bank[10];
/*
@@ -55,11 +56,26 @@ static unsigned long pin_to_bank_base(struct udevice *dev, const char *pin_name,
*pin = pin_name[++idx] - '0';
/* lookup the pin bank data using the pin bank name */
- for (idx = 0; idx < nr_banks; idx++)
- if (!strcmp(bank, bank_data[idx].name))
+ while (true) {
+ const struct samsung_pin_ctrl *pin_ctrl = &pin_ctrl_array[pin_ctrl_idx];
+
+ nr_banks = pin_ctrl->nr_banks;
+ if (!nr_banks)
break;
- return priv->base + bank_data[idx].offset;
+ bank_data = pin_ctrl->pin_banks;
+ for (idx = 0; idx < nr_banks; idx++) {
+ debug("pinctrl[%d] bank_data[%d] name is: %s\n",
+ pin_ctrl_idx, idx, bank_data[idx].name);
+ if (!strcmp(bank, bank_data[idx].name)) {
+ bank_base = priv->base + bank_data[idx].offset;
+ break;
+ }
+ }
+ pin_ctrl_idx++;
+ }
+
+ return bank_base;
}
/**
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos78x0.c b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c
new file mode 100644
index 0000000000..01e9a4fede
--- /dev/null
+++ b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Exynos78x0 pinctrl driver.
+ *
+ * Copyright (c) 2020 Dzmitry Sankouski (dsankouski@gmail.com)
+ *
+ * based on drivers/pinctrl/exynos/pinctrl-exynos7420.c :
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <fdtdec.h>
+#include <asm/arch/pinmux.h>
+#include "pinctrl-exynos.h"
+
+static struct pinctrl_ops exynos78x0_pinctrl_ops = {
+ .set_state = exynos_pinctrl_set_state
+};
+
+/* pin banks of exynos78x0 pin-controller 0 (ALIVE) */
+static struct samsung_pin_bank_data exynos78x0_pin_banks0[] = {
+ EXYNOS_PIN_BANK(6, 0x000, "etc0"),
+ EXYNOS_PIN_BANK(3, 0x020, "etc1"),
+ EXYNOS_PIN_BANK(8, 0x040, "gpa0"),
+ EXYNOS_PIN_BANK(8, 0x060, "gpa1"),
+ EXYNOS_PIN_BANK(8, 0x080, "gpa2"),
+ EXYNOS_PIN_BANK(5, 0x0a0, "gpa3"),
+ EXYNOS_PIN_BANK(2, 0x0c0, "gpq0"),
+};
+
+/* pin banks of exynos78x0 pin-controller 1 (CCORE) */
+static struct samsung_pin_bank_data exynos78x0_pin_banks1[] = {
+ EXYNOS_PIN_BANK(2, 0x000, "gpm0"),
+};
+
+/* pin banks of exynos78x0 pin-controller 2 (DISPAUD) */
+static struct samsung_pin_bank_data exynos78x0_pin_banks2[] = {
+ EXYNOS_PIN_BANK(4, 0x000, "gpz0"),
+ EXYNOS_PIN_BANK(6, 0x020, "gpz1"),
+ EXYNOS_PIN_BANK(4, 0x040, "gpz2"),
+};
+
+/* pin banks of exynos78x0 pin-controller 4 (FSYS) */
+static struct samsung_pin_bank_data exynos78x0_pin_banks4[] = {
+ EXYNOS_PIN_BANK(3, 0x000, "gpr0"),
+ EXYNOS_PIN_BANK(8, 0x020, "gpr1"),
+ EXYNOS_PIN_BANK(2, 0x040, "gpr2"),
+ EXYNOS_PIN_BANK(4, 0x060, "gpr3"),
+ EXYNOS_PIN_BANK(6, 0x080, "gpr4"),
+};
+
+/* pin banks of exynos78x0 pin-controller 6 (TOP) */
+static struct samsung_pin_bank_data exynos78x0_pin_banks6[] = {
+ EXYNOS_PIN_BANK(4, 0x000, "gpb0"),
+ EXYNOS_PIN_BANK(3, 0x020, "gpc0"),
+ EXYNOS_PIN_BANK(4, 0x040, "gpc1"),
+ EXYNOS_PIN_BANK(4, 0x060, "gpc4"),
+ EXYNOS_PIN_BANK(2, 0x080, "gpc5"),
+ EXYNOS_PIN_BANK(4, 0x0a0, "gpc6"),
+ EXYNOS_PIN_BANK(2, 0x0c0, "gpc8"),
+ EXYNOS_PIN_BANK(2, 0x0e0, "gpc9"),
+ EXYNOS_PIN_BANK(7, 0x100, "gpd1"),
+ EXYNOS_PIN_BANK(6, 0x120, "gpd2"),
+ EXYNOS_PIN_BANK(8, 0x140, "gpd3"),
+ EXYNOS_PIN_BANK(7, 0x160, "gpd4"),
+ EXYNOS_PIN_BANK(5, 0x180, "gpd5"),
+ EXYNOS_PIN_BANK(3, 0x1a0, "gpe0"),
+ EXYNOS_PIN_BANK(4, 0x1c0, "gpf0"),
+ EXYNOS_PIN_BANK(2, 0x1e0, "gpf1"),
+ EXYNOS_PIN_BANK(2, 0x200, "gpf2"),
+ EXYNOS_PIN_BANK(4, 0x220, "gpf3"),
+ EXYNOS_PIN_BANK(5, 0x240, "gpf4"),
+};
+
+struct samsung_pin_ctrl exynos78x0_pin_ctrl[] = {
+ {
+ /* pin-controller instance 0 Alive data */
+ .pin_banks = exynos78x0_pin_banks0,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks0),
+ }, {
+ /* pin-controller instance 1 CCORE data */
+ .pin_banks = exynos78x0_pin_banks1,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks1),
+ }, {
+ /* pin-controller instance 2 DISPAUD data */
+ .pin_banks = exynos78x0_pin_banks2,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks2),
+ }, {
+ /* pin-controller instance 4 FSYS data */
+ .pin_banks = exynos78x0_pin_banks4,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks4),
+ }, {
+ /* pin-controller instance 6 TOP data */
+ .pin_banks = exynos78x0_pin_banks6,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks6),
+ },
+ {/* list terminator */}
+};
+
+static const struct udevice_id exynos78x0_pinctrl_ids[] = {
+ { .compatible = "samsung,exynos78x0-pinctrl",
+ .data = (ulong)exynos78x0_pin_ctrl },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_exynos78x0) = {
+ .name = "pinctrl_exynos78x0",
+ .id = UCLASS_PINCTRL,
+ .of_match = exynos78x0_pinctrl_ids,
+ .priv_auto = sizeof(struct exynos_pinctrl_priv),
+ .ops = &exynos78x0_pinctrl_ops,
+ .probe = exynos_pinctrl_probe,
+};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 122a39789c..6c8fdda9a0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -290,12 +290,20 @@ config DEBUG_SBI_CONSOLE
config DEBUG_UART_S5P
bool "Samsung S5P"
- depends on ARCH_EXYNOS || ARCH_S5PC1XX
+ depends on ARCH_APPLE || ARCH_EXYNOS || ARCH_S5PC1XX
help
Select this to enable a debug UART using the serial_s5p driver. You
will need to provide parameters to make this work. The driver will
be available until the real driver-model serial is running.
+config DEBUG_UART_MSM_GENI
+ bool "Qualcomm snapdragon"
+ depends on ARCH_SNAPDRAGON
+ help
+ Select this to enable a debug UART using the serial_msm driver. You
+ will need to provide parameters to make this work. The driver will
+ be available until the real driver-model serial is running.
+
config DEBUG_UART_MESON
bool "Amlogic Meson"
depends on MESON_SERIAL
@@ -737,7 +745,7 @@ config ROCKCHIP_SERIAL
config S5P_SERIAL
bool "Support for Samsung S5P UART"
- depends on ARCH_EXYNOS || ARCH_S5PC1XX
+ depends on ARCH_APPLE || ARCH_EXYNOS || ARCH_S5PC1XX
default y
help
Select this to enable Samsung S5P UART support.
@@ -801,6 +809,16 @@ config MSM_SERIAL
for example APQ8016 and MSM8916.
Single baudrate is supported in current implementation (115200).
+config MSM_GENI_SERIAL
+ bool "Qualcomm on-chip GENI UART"
+ help
+ Support UART based on Generic Interface (GENI) Serial Engine (SE),
+ used on Qualcomm Snapdragon SoCs. Should support all qualcomm SOCs
+ with Qualcomm Universal Peripheral (QUP) Wrapper cores,
+ i.e. newer ones, starting from SDM845.
+ Driver works in FIFO mode.
+ Multiple baudrates supported.
+
config OCTEON_SERIAL_BOOTCMD
bool "MIPS Octeon PCI remote bootcmd input"
depends on ARCH_OCTEON
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 4edd2aa945..8168af640f 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_PIC32_SERIAL) += serial_pic32.o
obj-$(CONFIG_BCM283X_MU_SERIAL) += serial_bcm283x_mu.o
obj-$(CONFIG_BCM283X_PL011_SERIAL) += serial_bcm283x_pl011.o
obj-$(CONFIG_MSM_SERIAL) += serial_msm.o
+obj-$(CONFIG_MSM_GENI_SERIAL) += serial_msm_geni.o
obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o
obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o
obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o
diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
new file mode 100644
index 0000000000..3e255a99dc
--- /dev/null
+++ b/drivers/serial/serial_msm_geni.c
@@ -0,0 +1,613 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm GENI serial engine UART driver
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ * Based on Linux driver.
+ */
+
+#include <asm/io.h>
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <errno.h>
+#include <linux/compiler.h>
+#include <log.h>
+#include <linux/delay.h>
+#include <malloc.h>
+#include <serial.h>
+#include <watchdog.h>
+#include <linux/bug.h>
+
+#define UART_OVERSAMPLING 32
+#define STALE_TIMEOUT 160
+
+#define USEC_PER_SEC 1000000L
+
+/* Registers*/
+#define GENI_FORCE_DEFAULT_REG 0x20
+#define GENI_SER_M_CLK_CFG 0x48
+#define GENI_SER_S_CLK_CFG 0x4C
+#define SE_HW_PARAM_0 0xE24
+#define SE_GENI_STATUS 0x40
+#define SE_GENI_S_CMD0 0x630
+#define SE_GENI_S_CMD_CTRL_REG 0x634
+#define SE_GENI_S_IRQ_CLEAR 0x648
+#define SE_GENI_S_IRQ_STATUS 0x640
+#define SE_GENI_S_IRQ_EN 0x644
+#define SE_GENI_M_CMD0 0x600
+#define SE_GENI_M_CMD_CTRL_REG 0x604
+#define SE_GENI_M_IRQ_CLEAR 0x618
+#define SE_GENI_M_IRQ_STATUS 0x610
+#define SE_GENI_M_IRQ_EN 0x614
+#define SE_GENI_TX_FIFOn 0x700
+#define SE_GENI_RX_FIFOn 0x780
+#define SE_GENI_TX_FIFO_STATUS 0x800
+#define SE_GENI_RX_FIFO_STATUS 0x804
+#define SE_GENI_TX_WATERMARK_REG 0x80C
+#define SE_GENI_TX_PACKING_CFG0 0x260
+#define SE_GENI_TX_PACKING_CFG1 0x264
+#define SE_GENI_RX_PACKING_CFG0 0x284
+#define SE_GENI_RX_PACKING_CFG1 0x288
+#define SE_UART_RX_STALE_CNT 0x294
+#define SE_UART_TX_TRANS_LEN 0x270
+#define SE_UART_TX_STOP_BIT_LEN 0x26c
+#define SE_UART_TX_WORD_LEN 0x268
+#define SE_UART_RX_WORD_LEN 0x28c
+#define SE_UART_TX_TRANS_CFG 0x25c
+#define SE_UART_TX_PARITY_CFG 0x2a4
+#define SE_UART_RX_TRANS_CFG 0x280
+#define SE_UART_RX_PARITY_CFG 0x2a8
+
+#define M_TX_FIFO_WATERMARK_EN (BIT(30))
+#define DEF_TX_WM 2
+/* GENI_FORCE_DEFAULT_REG fields */
+#define FORCE_DEFAULT (BIT(0))
+
+#define S_CMD_ABORT_EN (BIT(5))
+
+#define UART_START_READ 0x1
+
+/* GENI_M_CMD_CTRL_REG */
+#define M_GENI_CMD_CANCEL (BIT(2))
+#define M_GENI_CMD_ABORT (BIT(1))
+#define M_GENI_DISABLE (BIT(0))
+
+#define M_CMD_ABORT_EN (BIT(5))
+#define M_CMD_DONE_EN (BIT(0))
+#define M_CMD_DONE_DISABLE_MASK (~M_CMD_DONE_EN)
+
+#define S_GENI_CMD_ABORT (BIT(1))
+
+/* GENI_S_CMD0 fields */
+#define S_OPCODE_MSK (GENMASK(31, 27))
+#define S_PARAMS_MSK (GENMASK(26, 0))
+
+/* GENI_STATUS fields */
+#define M_GENI_CMD_ACTIVE (BIT(0))
+#define S_GENI_CMD_ACTIVE (BIT(12))
+#define M_CMD_DONE_EN (BIT(0))
+#define S_CMD_DONE_EN (BIT(0))
+
+#define M_OPCODE_SHIFT 27
+#define S_OPCODE_SHIFT 27
+#define M_TX_FIFO_WATERMARK_EN (BIT(30))
+#define UART_START_TX 0x1
+#define UART_CTS_MASK (BIT(1))
+#define M_SEC_IRQ_EN (BIT(31))
+#define TX_FIFO_WC_MSK (GENMASK(27, 0))
+#define RX_FIFO_WC_MSK (GENMASK(24, 0))
+
+#define S_RX_FIFO_WATERMARK_EN (BIT(26))
+#define S_RX_FIFO_LAST_EN (BIT(27))
+#define M_RX_FIFO_WATERMARK_EN (BIT(26))
+#define M_RX_FIFO_LAST_EN (BIT(27))
+
+/* GENI_SER_M_CLK_CFG/GENI_SER_S_CLK_CFG */
+#define SER_CLK_EN (BIT(0))
+#define CLK_DIV_MSK (GENMASK(15, 4))
+#define CLK_DIV_SHFT 4
+
+/* SE_HW_PARAM_0 fields */
+#define TX_FIFO_WIDTH_MSK (GENMASK(29, 24))
+#define TX_FIFO_WIDTH_SHFT 24
+#define TX_FIFO_DEPTH_MSK (GENMASK(21, 16))
+#define TX_FIFO_DEPTH_SHFT 16
+
+/*
+ * Predefined packing configuration of the serial engine (CFG0, CFG1 regs)
+ * for uart mode.
+ *
+ * Defines following configuration:
+ * - Bits of data per transfer word 8
+ * - Number of words per fifo element 4
+ * - Transfer from MSB to LSB or vice-versa false
+ */
+#define UART_PACKING_CFG0 0xf
+#define UART_PACKING_CFG1 0x0
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct msm_serial_data {
+ phys_addr_t base;
+ u32 baud;
+};
+
+unsigned long root_freq[] = {7372800, 14745600, 19200000, 29491200,
+ 32000000, 48000000, 64000000, 80000000,
+ 96000000, 100000000};
+
+/**
+ * get_clk_cfg() - Get clock rate to apply on clock supplier.
+ * @clk_freq: Desired clock frequency after build-in divider.
+ *
+ * Return: frequency, supported by clock supplier, multiple of clk_freq.
+ */
+static int get_clk_cfg(unsigned long clk_freq)
+{
+ for (int i = 0; i < ARRAY_SIZE(root_freq); i++) {
+ if (!(root_freq[i] % clk_freq))
+ return root_freq[i];
+ }
+ return 0;
+}
+
+/**
+ * get_clk_div_rate() - Find clock supplier frequency, and calculate divisor.
+ * @baud: Baudrate.
+ * @sampling_rate: Clock ticks per character.
+ * @clk_div: Pointer to calculated divisor.
+ *
+ * This function searches for suitable frequency for clock supplier,
+ * calculates divisor for internal divider, based on found frequency,
+ * and stores divisor under clk_div pointer.
+ *
+ * Return: frequency, supported by clock supplier, multiple of clk_freq.
+ */
+static int get_clk_div_rate(u32 baud,
+ u64 sampling_rate, u32 *clk_div)
+{
+ unsigned long ser_clk;
+ unsigned long desired_clk;
+
+ desired_clk = baud * sampling_rate;
+ ser_clk = get_clk_cfg(desired_clk);
+ if (!ser_clk) {
+ pr_err("%s: Can't find matching DFS entry for baud %d\n",
+ __func__, baud);
+ return ser_clk;
+ }
+
+ *clk_div = ser_clk / desired_clk;
+ return ser_clk;
+}
+
+static int geni_serial_set_clock_rate(struct udevice *dev, u64 rate)
+{
+ struct clk *clk;
+ int ret;
+
+ clk = devm_clk_get(dev, "se-clk");
+ if (!clk)
+ return -EINVAL;
+
+ ret = clk_set_rate(clk, rate);
+ return ret;
+}
+
+/**
+ * geni_se_get_tx_fifo_depth() - Get the TX fifo depth of the serial engine
+ * @base: Pointer to the concerned serial engine.
+ *
+ * This function is used to get the depth i.e. number of elements in the
+ * TX fifo of the serial engine.
+ *
+ * Return: TX fifo depth in units of FIFO words.
+ */
+static inline u32 geni_se_get_tx_fifo_depth(long base)
+{
+ u32 tx_fifo_depth;
+
+ tx_fifo_depth = ((readl(base + SE_HW_PARAM_0) & TX_FIFO_DEPTH_MSK) >>
+ TX_FIFO_DEPTH_SHFT);
+ return tx_fifo_depth;
+}
+
+/**
+ * geni_se_get_tx_fifo_width() - Get the TX fifo width of the serial engine
+ * @base: Pointer to the concerned serial engine.
+ *
+ * This function is used to get the width i.e. word size per element in the
+ * TX fifo of the serial engine.
+ *
+ * Return: TX fifo width in bits
+ */
+static inline u32 geni_se_get_tx_fifo_width(long base)
+{
+ u32 tx_fifo_width;
+
+ tx_fifo_width = ((readl(base + SE_HW_PARAM_0) & TX_FIFO_WIDTH_MSK) >>
+ TX_FIFO_WIDTH_SHFT);
+ return tx_fifo_width;
+}
+
+static inline void geni_serial_baud(phys_addr_t base_address, u32 clk_div,
+ int baud)
+{
+ u32 s_clk_cfg = 0;
+
+ s_clk_cfg |= SER_CLK_EN;
+ s_clk_cfg |= (clk_div << CLK_DIV_SHFT);
+
+ writel(s_clk_cfg, base_address + GENI_SER_M_CLK_CFG);
+ writel(s_clk_cfg, base_address + GENI_SER_S_CLK_CFG);
+}
+
+int msm_serial_setbrg(struct udevice *dev, int baud)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ priv->baud = baud;
+ u32 clk_div;
+ u64 clk_rate;
+
+ clk_rate = get_clk_div_rate(baud, UART_OVERSAMPLING, &clk_div);
+ geni_serial_set_clock_rate(dev, clk_rate);
+ geni_serial_baud(priv->base, clk_div, baud);
+
+ return 0;
+}
+
+/**
+ * qcom_geni_serial_poll_bit() - Poll reg bit until desired value or timeout.
+ * @base: Pointer to the concerned serial engine.
+ * @offset: Offset to register address.
+ * @field: AND bitmask for desired bit.
+ * @set: Desired bit value.
+ *
+ * This function is used to get the width i.e. word size per element in the
+ * TX fifo of the serial engine.
+ *
+ * Return: true, when register bit equals desired value, false, when timeout
+ * reached.
+ */
+static bool qcom_geni_serial_poll_bit(const struct udevice *dev, int offset,
+ int field, bool set)
+{
+ u32 reg;
+ struct msm_serial_data *priv = dev_get_priv(dev);
+ unsigned int baud;
+ unsigned int tx_fifo_depth;
+ unsigned int tx_fifo_width;
+ unsigned int fifo_bits;
+ unsigned long timeout_us = 10000;
+
+ baud = 115200;
+
+ if (priv) {
+ baud = priv->baud;
+ if (!baud)
+ baud = 115200;
+ tx_fifo_depth = geni_se_get_tx_fifo_depth(priv->base);
+ tx_fifo_width = geni_se_get_tx_fifo_width(priv->base);
+ fifo_bits = tx_fifo_depth * tx_fifo_width;
+ /*
+ * Total polling iterations based on FIFO worth of bytes to be
+ * sent at current baud. Add a little fluff to the wait.
+ */
+ timeout_us = ((fifo_bits * USEC_PER_SEC) / baud) + 500;
+ }
+
+ timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10;
+ while (timeout_us) {
+ reg = readl(priv->base + offset);
+ if ((bool)(reg & field) == set)
+ return true;
+ udelay(10);
+ timeout_us -= 10;
+ }
+ return false;
+}
+
+static void qcom_geni_serial_setup_tx(u64 base, u32 xmit_size)
+{
+ u32 m_cmd;
+
+ writel(xmit_size, base + SE_UART_TX_TRANS_LEN);
+ m_cmd = UART_START_TX << M_OPCODE_SHIFT;
+ writel(m_cmd, base + SE_GENI_M_CMD0);
+}
+
+static inline void qcom_geni_serial_poll_tx_done(const struct udevice *dev)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+ int done = 0;
+ u32 irq_clear = M_CMD_DONE_EN;
+
+ done = qcom_geni_serial_poll_bit(dev, SE_GENI_M_IRQ_STATUS,
+ M_CMD_DONE_EN, true);
+ if (!done) {
+ writel(M_GENI_CMD_ABORT, priv->base + SE_GENI_M_CMD_CTRL_REG);
+ irq_clear |= M_CMD_ABORT_EN;
+ qcom_geni_serial_poll_bit(dev, SE_GENI_M_IRQ_STATUS,
+ M_CMD_ABORT_EN, true);
+ }
+ writel(irq_clear, priv->base + SE_GENI_M_IRQ_CLEAR);
+}
+
+static u32 qcom_geni_serial_tx_empty(u64 base)
+{
+ return !readl(base + SE_GENI_TX_FIFO_STATUS);
+}
+
+/**
+ * geni_se_setup_s_cmd() - Setup the secondary sequencer
+ * @se: Pointer to the concerned serial engine.
+ * @cmd: Command/Operation to setup in the secondary sequencer.
+ * @params: Parameter for the sequencer command.
+ *
+ * This function is used to configure the secondary sequencer with the
+ * command and its associated parameters.
+ */
+static inline void geni_se_setup_s_cmd(u64 base, u32 cmd, u32 params)
+{
+ u32 s_cmd;
+
+ s_cmd = readl(base + SE_GENI_S_CMD0);
+ s_cmd &= ~(S_OPCODE_MSK | S_PARAMS_MSK);
+ s_cmd |= (cmd << S_OPCODE_SHIFT);
+ s_cmd |= (params & S_PARAMS_MSK);
+ writel(s_cmd, base + SE_GENI_S_CMD0);
+}
+
+static void qcom_geni_serial_start_tx(u64 base)
+{
+ u32 irq_en;
+ u32 status;
+
+ status = readl(base + SE_GENI_STATUS);
+ if (status & M_GENI_CMD_ACTIVE)
+ return;
+
+ if (!qcom_geni_serial_tx_empty(base))
+ return;
+
+ irq_en = readl(base + SE_GENI_M_IRQ_EN);
+ irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
+
+ writel(DEF_TX_WM, base + SE_GENI_TX_WATERMARK_REG);
+ writel(irq_en, base + SE_GENI_M_IRQ_EN);
+}
+
+static void qcom_geni_serial_start_rx(struct udevice *dev)
+{
+ u32 status;
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ status = readl(priv->base + SE_GENI_STATUS);
+
+ geni_se_setup_s_cmd(priv->base, UART_START_READ, 0);
+
+ setbits_le32(priv->base + SE_GENI_S_IRQ_EN, S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
+ setbits_le32(priv->base + SE_GENI_M_IRQ_EN, M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
+}
+
+static void qcom_geni_serial_abort_rx(struct udevice *dev)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ u32 irq_clear = S_CMD_DONE_EN | S_CMD_ABORT_EN;
+
+ writel(S_GENI_CMD_ABORT, priv->base + SE_GENI_S_CMD_CTRL_REG);
+ qcom_geni_serial_poll_bit(dev, SE_GENI_S_CMD_CTRL_REG,
+ S_GENI_CMD_ABORT, false);
+ writel(irq_clear, priv->base + SE_GENI_S_IRQ_CLEAR);
+ writel(FORCE_DEFAULT, priv->base + GENI_FORCE_DEFAULT_REG);
+}
+
+static void msm_geni_serial_setup_rx(struct udevice *dev)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ qcom_geni_serial_abort_rx(dev);
+
+ writel(UART_PACKING_CFG0, priv->base + SE_GENI_RX_PACKING_CFG0);
+ writel(UART_PACKING_CFG1, priv->base + SE_GENI_RX_PACKING_CFG1);
+
+ geni_se_setup_s_cmd(priv->base, UART_START_READ, 0);
+
+ setbits_le32(priv->base + SE_GENI_S_IRQ_EN, S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
+ setbits_le32(priv->base + SE_GENI_M_IRQ_EN, M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
+}
+
+static int msm_serial_putc(struct udevice *dev, const char ch)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ writel(DEF_TX_WM, priv->base + SE_GENI_TX_WATERMARK_REG);
+ qcom_geni_serial_setup_tx(priv->base, 1);
+
+ qcom_geni_serial_poll_bit(dev, SE_GENI_M_IRQ_STATUS,
+ M_TX_FIFO_WATERMARK_EN, true);
+
+ writel(ch, priv->base + SE_GENI_TX_FIFOn);
+ writel(M_TX_FIFO_WATERMARK_EN, priv->base + SE_GENI_M_IRQ_CLEAR);
+
+ qcom_geni_serial_poll_tx_done(dev);
+
+ return 0;
+}
+
+static int msm_serial_getc(struct udevice *dev)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+ u32 rx_fifo;
+ u32 m_irq_status;
+ u32 s_irq_status;
+
+ writel(1 << S_OPCODE_SHIFT, priv->base + SE_GENI_S_CMD0);
+
+ qcom_geni_serial_poll_bit(dev, SE_GENI_M_IRQ_STATUS, M_SEC_IRQ_EN,
+ true);
+
+ m_irq_status = readl(priv->base + SE_GENI_M_IRQ_STATUS);
+ s_irq_status = readl(priv->base + SE_GENI_S_IRQ_STATUS);
+ writel(m_irq_status, priv->base + SE_GENI_M_IRQ_CLEAR);
+ writel(s_irq_status, priv->base + SE_GENI_S_IRQ_CLEAR);
+ qcom_geni_serial_poll_bit(dev, SE_GENI_RX_FIFO_STATUS, RX_FIFO_WC_MSK,
+ true);
+
+ if (!readl(priv->base + SE_GENI_RX_FIFO_STATUS))
+ return 0;
+
+ rx_fifo = readl(priv->base + SE_GENI_RX_FIFOn);
+ return rx_fifo & 0xff;
+}
+
+static int msm_serial_pending(struct udevice *dev, bool input)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ if (input)
+ return readl(priv->base + SE_GENI_RX_FIFO_STATUS) &
+ RX_FIFO_WC_MSK;
+ else
+ return readl(priv->base + SE_GENI_TX_FIFO_STATUS) &
+ TX_FIFO_WC_MSK;
+
+ return 0;
+}
+
+static const struct dm_serial_ops msm_serial_ops = {
+ .putc = msm_serial_putc,
+ .pending = msm_serial_pending,
+ .getc = msm_serial_getc,
+ .setbrg = msm_serial_setbrg,
+};
+
+static inline void geni_serial_init(struct udevice *dev)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+ phys_addr_t base_address = priv->base;
+ u32 tx_trans_cfg;
+ u32 tx_parity_cfg = 0; /* Disable Tx Parity */
+ u32 rx_trans_cfg = 0;
+ u32 rx_parity_cfg = 0; /* Disable Rx Parity */
+ u32 stop_bit_len = 0; /* Default stop bit length - 1 bit */
+ u32 bits_per_char;
+
+ /*
+ * Ignore Flow control.
+ * n = 8.
+ */
+ tx_trans_cfg = UART_CTS_MASK;
+ bits_per_char = BITS_PER_BYTE;
+
+ /*
+ * Make an unconditional cancel on the main sequencer to reset
+ * it else we could end up in data loss scenarios.
+ */
+ qcom_geni_serial_poll_tx_done(dev);
+ qcom_geni_serial_abort_rx(dev);
+
+ writel(UART_PACKING_CFG0, base_address + SE_GENI_TX_PACKING_CFG0);
+ writel(UART_PACKING_CFG1, base_address + SE_GENI_TX_PACKING_CFG1);
+ writel(UART_PACKING_CFG0, base_address + SE_GENI_RX_PACKING_CFG0);
+ writel(UART_PACKING_CFG1, base_address + SE_GENI_RX_PACKING_CFG1);
+
+ writel(tx_trans_cfg, base_address + SE_UART_TX_TRANS_CFG);
+ writel(tx_parity_cfg, base_address + SE_UART_TX_PARITY_CFG);
+ writel(rx_trans_cfg, base_address + SE_UART_RX_TRANS_CFG);
+ writel(rx_parity_cfg, base_address + SE_UART_RX_PARITY_CFG);
+ writel(bits_per_char, base_address + SE_UART_TX_WORD_LEN);
+ writel(bits_per_char, base_address + SE_UART_RX_WORD_LEN);
+ writel(stop_bit_len, base_address + SE_UART_TX_STOP_BIT_LEN);
+}
+
+static int msm_serial_probe(struct udevice *dev)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ /* No need to reinitialize the UART after relocation */
+ if (gd->flags & GD_FLG_RELOC)
+ return 0;
+
+ geni_serial_init(dev);
+ msm_geni_serial_setup_rx(dev);
+ qcom_geni_serial_start_rx(dev);
+ qcom_geni_serial_start_tx(priv->base);
+
+ return 0;
+}
+
+static int msm_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct msm_serial_data *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr(dev);
+ if (priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct udevice_id msm_serial_ids[] = {
+ {.compatible = "qcom,msm-geni-uart"}, {}};
+
+U_BOOT_DRIVER(serial_msm_geni) = {
+ .name = "serial_msm_geni",
+ .id = UCLASS_SERIAL,
+ .of_match = msm_serial_ids,
+ .of_to_plat = msm_serial_ofdata_to_platdata,
+ .priv_auto = sizeof(struct msm_serial_data),
+ .probe = msm_serial_probe,
+ .ops = &msm_serial_ops,
+};
+
+#ifdef CONFIG_DEBUG_UART_MSM_GENI
+
+static struct msm_serial_data init_serial_data = {
+ .base = CONFIG_DEBUG_UART_BASE
+};
+
+/* Serial dumb device, to reuse driver code */
+static struct udevice init_dev = {
+ .priv_ = &init_serial_data,
+};
+
+#include <debug_uart.h>
+
+#define CLK_DIV (CONFIG_DEBUG_UART_CLOCK / \
+ (CONFIG_BAUDRATE * UART_OVERSAMPLING))
+#if (CONFIG_DEBUG_UART_CLOCK % (CONFIG_BAUDRATE * UART_OVERSAMPLING) > 0)
+#error Clocks cannot be set at early debug. Change CONFIG_BAUDRATE
+#endif
+
+static inline void _debug_uart_init(void)
+{
+ phys_addr_t base = CONFIG_DEBUG_UART_BASE;
+
+ geni_serial_init(&init_dev);
+ geni_serial_baud(base, CLK_DIV, CONFIG_BAUDRATE);
+ qcom_geni_serial_start_tx(base);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+ phys_addr_t base = CONFIG_DEBUG_UART_BASE;
+
+ writel(DEF_TX_WM, base + SE_GENI_TX_WATERMARK_REG);
+ qcom_geni_serial_setup_tx(base, 1);
+ qcom_geni_serial_poll_bit(&init_dev, SE_GENI_M_IRQ_STATUS,
+ M_TX_FIFO_WATERMARK_EN, true);
+
+ writel(ch, base + SE_GENI_TX_FIFOn);
+ writel(M_TX_FIFO_WATERMARK_EN, base + SE_GENI_M_IRQ_CLEAR);
+ qcom_geni_serial_poll_tx_done(&init_dev);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 6d09952a5d..de420d2d94 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -14,24 +14,45 @@
#include <asm/global_data.h>
#include <linux/compiler.h>
#include <asm/io.h>
+#if !CONFIG_IS_ENABLED(ARCH_APPLE)
#include <asm/arch/clk.h>
+#endif
#include <asm/arch/uart.h>
#include <serial.h>
#include <clk.h>
DECLARE_GLOBAL_DATA_PTR;
-#define RX_FIFO_COUNT_SHIFT 0
-#define RX_FIFO_COUNT_MASK (0xff << RX_FIFO_COUNT_SHIFT)
-#define RX_FIFO_FULL (1 << 8)
-#define TX_FIFO_COUNT_SHIFT 16
-#define TX_FIFO_COUNT_MASK (0xff << TX_FIFO_COUNT_SHIFT)
-#define TX_FIFO_FULL (1 << 24)
+enum {
+ PORT_S5P = 0,
+ PORT_S5L
+};
+
+#define S5L_RX_FIFO_COUNT_SHIFT 0
+#define S5L_RX_FIFO_COUNT_MASK (0xf << S5L_RX_FIFO_COUNT_SHIFT)
+#define S5L_RX_FIFO_FULL (1 << 8)
+#define S5L_TX_FIFO_COUNT_SHIFT 4
+#define S5L_TX_FIFO_COUNT_MASK (0xf << S5L_TX_FIFO_COUNT_SHIFT)
+#define S5L_TX_FIFO_FULL (1 << 9)
+
+#define S5P_RX_FIFO_COUNT_SHIFT 0
+#define S5P_RX_FIFO_COUNT_MASK (0xff << S5P_RX_FIFO_COUNT_SHIFT)
+#define S5P_RX_FIFO_FULL (1 << 8)
+#define S5P_TX_FIFO_COUNT_SHIFT 16
+#define S5P_TX_FIFO_COUNT_MASK (0xff << S5P_TX_FIFO_COUNT_SHIFT)
+#define S5P_TX_FIFO_FULL (1 << 24)
/* Information about a serial port */
struct s5p_serial_plat {
struct s5p_uart *reg; /* address of registers in physical memory */
+ u8 reg_width; /* register width */
u8 port_id; /* uart port number */
+ u8 rx_fifo_count_shift;
+ u8 tx_fifo_count_shift;
+ u32 rx_fifo_count_mask;
+ u32 tx_fifo_count_mask;
+ u32 rx_fifo_full;
+ u32 tx_fifo_full;
};
/*
@@ -71,8 +92,8 @@ static void __maybe_unused s5p_serial_init(struct s5p_uart *uart)
writel(0x245, &uart->ucon);
}
-static void __maybe_unused s5p_serial_baud(struct s5p_uart *uart, uint uclk,
- int baudrate)
+static void __maybe_unused s5p_serial_baud(struct s5p_uart *uart, u8 reg_width,
+ uint uclk, int baudrate)
{
u32 val;
@@ -82,6 +103,8 @@ static void __maybe_unused s5p_serial_baud(struct s5p_uart *uart, uint uclk,
if (s5p_uart_divslot())
writew(udivslot[val % 16], &uart->rest.slot);
+ else if (reg_width == 4)
+ writel(val % 16, &uart->rest.value);
else
writeb(val % 16, &uart->rest.value);
}
@@ -93,7 +116,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate)
struct s5p_uart *const uart = plat->reg;
u32 uclk;
-#ifdef CONFIG_CLK_EXYNOS
+#if CONFIG_IS_ENABLED(CLK_EXYNOS) || CONFIG_IS_ENABLED(ARCH_APPLE)
struct clk clk;
u32 ret;
@@ -105,7 +128,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate)
uclk = get_uart_clk(plat->port_id);
#endif
- s5p_serial_baud(uart, uclk, baudrate);
+ s5p_serial_baud(uart, plat->reg_width, uclk, baudrate);
return 0;
}
@@ -144,11 +167,14 @@ static int s5p_serial_getc(struct udevice *dev)
struct s5p_serial_plat *plat = dev_get_plat(dev);
struct s5p_uart *const uart = plat->reg;
- if (!(readl(&uart->ufstat) & RX_FIFO_COUNT_MASK))
+ if (!(readl(&uart->ufstat) & plat->rx_fifo_count_mask))
return -EAGAIN;
serial_err_check(uart, 0);
- return (int)(readb(&uart->urxh) & 0xff);
+ if (plat->reg_width == 4)
+ return (int)(readl(&uart->urxh) & 0xff);
+ else
+ return (int)(readb(&uart->urxh) & 0xff);
}
static int s5p_serial_putc(struct udevice *dev, const char ch)
@@ -156,10 +182,13 @@ static int s5p_serial_putc(struct udevice *dev, const char ch)
struct s5p_serial_plat *plat = dev_get_plat(dev);
struct s5p_uart *const uart = plat->reg;
- if (readl(&uart->ufstat) & TX_FIFO_FULL)
+ if (readl(&uart->ufstat) & plat->tx_fifo_full)
return -EAGAIN;
- writeb(ch, &uart->utxh);
+ if (plat->reg_width == 4)
+ writel(ch, &uart->utxh);
+ else
+ writeb(ch, &uart->utxh);
serial_err_check(uart, 1);
return 0;
@@ -171,15 +200,19 @@ static int s5p_serial_pending(struct udevice *dev, bool input)
struct s5p_uart *const uart = plat->reg;
uint32_t ufstat = readl(&uart->ufstat);
- if (input)
- return (ufstat & RX_FIFO_COUNT_MASK) >> RX_FIFO_COUNT_SHIFT;
- else
- return (ufstat & TX_FIFO_COUNT_MASK) >> TX_FIFO_COUNT_SHIFT;
+ if (input) {
+ return (ufstat & plat->rx_fifo_count_mask) >>
+ plat->rx_fifo_count_shift;
+ } else {
+ return (ufstat & plat->tx_fifo_count_mask) >>
+ plat->tx_fifo_count_shift;
+ }
}
static int s5p_serial_of_to_plat(struct udevice *dev)
{
struct s5p_serial_plat *plat = dev_get_plat(dev);
+ const ulong port_type = dev_get_driver_data(dev);
fdt_addr_t addr;
addr = dev_read_addr(dev);
@@ -187,8 +220,26 @@ static int s5p_serial_of_to_plat(struct udevice *dev)
return -EINVAL;
plat->reg = (struct s5p_uart *)addr;
+ plat->reg_width = dev_read_u32_default(dev, "reg-io-width", 1);
plat->port_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"id", dev_seq(dev));
+
+ if (port_type == PORT_S5L) {
+ plat->rx_fifo_count_shift = S5L_RX_FIFO_COUNT_SHIFT;
+ plat->rx_fifo_count_mask = S5L_RX_FIFO_COUNT_MASK;
+ plat->rx_fifo_full = S5L_RX_FIFO_FULL;
+ plat->tx_fifo_count_shift = S5L_TX_FIFO_COUNT_SHIFT;
+ plat->tx_fifo_count_mask = S5L_TX_FIFO_COUNT_MASK;
+ plat->tx_fifo_full = S5L_TX_FIFO_FULL;
+ } else {
+ plat->rx_fifo_count_shift = S5P_RX_FIFO_COUNT_SHIFT;
+ plat->rx_fifo_count_mask = S5P_RX_FIFO_COUNT_MASK;
+ plat->rx_fifo_full = S5P_RX_FIFO_FULL;
+ plat->tx_fifo_count_shift = S5P_TX_FIFO_COUNT_SHIFT;
+ plat->tx_fifo_count_mask = S5P_TX_FIFO_COUNT_MASK;
+ plat->tx_fifo_full = S5P_TX_FIFO_FULL;
+ }
+
return 0;
}
@@ -200,7 +251,8 @@ static const struct dm_serial_ops s5p_serial_ops = {
};
static const struct udevice_id s5p_serial_ids[] = {
- { .compatible = "samsung,exynos4210-uart" },
+ { .compatible = "samsung,exynos4210-uart", .data = PORT_S5P },
+ { .compatible = "apple,s5l-uart", .data = PORT_S5L },
{ }
};
@@ -221,19 +273,30 @@ U_BOOT_DRIVER(serial_s5p) = {
static inline void _debug_uart_init(void)
{
+ if (IS_ENABLED(CONFIG_DEBUG_UART_SKIP_INIT))
+ return;
+
struct s5p_uart *uart = (struct s5p_uart *)CONFIG_DEBUG_UART_BASE;
s5p_serial_init(uart);
- s5p_serial_baud(uart, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
+#if CONFIG_IS_ENABLED(ARCH_APPLE)
+ s5p_serial_baud(uart, 4, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
+#else
+ s5p_serial_baud(uart, 1, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
+#endif
}
static inline void _debug_uart_putc(int ch)
{
struct s5p_uart *uart = (struct s5p_uart *)CONFIG_DEBUG_UART_BASE;
- while (readl(&uart->ufstat) & TX_FIFO_FULL);
-
+#if CONFIG_IS_ENABLED(ARCH_APPLE)
+ while (readl(&uart->ufstat) & S5L_TX_FIFO_FULL);
+ writel(ch, &uart->utxh);
+#else
+ while (readl(&uart->ufstat) & S5P_TX_FIFO_FULL);
writeb(ch, &uart->utxh);
+#endif
}
DEBUG_UART_FUNCS
diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
index 5a335e50aa..27a035c0a5 100644
--- a/drivers/spmi/spmi-msm.c
+++ b/drivers/spmi/spmi-msm.c
@@ -19,39 +19,63 @@
DECLARE_GLOBAL_DATA_PTR;
/* PMIC Arbiter configuration registers */
-#define PMIC_ARB_VERSION 0x0000
-#define PMIC_ARB_VERSION_V2_MIN 0x20010000
-
-#define ARB_CHANNEL_OFFSET(n) (0x4 * (n))
-#define SPMI_CH_OFFSET(chnl) ((chnl) * 0x8000)
-
-#define SPMI_REG_CMD0 0x0
-#define SPMI_REG_CONFIG 0x4
-#define SPMI_REG_STATUS 0x8
-#define SPMI_REG_WDATA 0x10
-#define SPMI_REG_RDATA 0x18
-
-#define SPMI_CMD_OPCODE_SHIFT 27
-#define SPMI_CMD_SLAVE_ID_SHIFT 20
-#define SPMI_CMD_ADDR_SHIFT 12
-#define SPMI_CMD_ADDR_OFFSET_SHIFT 4
-#define SPMI_CMD_BYTE_CNT_SHIFT 0
-
-#define SPMI_CMD_EXT_REG_WRITE_LONG 0x00
-#define SPMI_CMD_EXT_REG_READ_LONG 0x01
-
-#define SPMI_STATUS_DONE 0x1
+#define PMIC_ARB_VERSION 0x0000
+#define PMIC_ARB_VERSION_V2_MIN 0x20010000
+#define PMIC_ARB_VERSION_V3_MIN 0x30000000
+#define PMIC_ARB_VERSION_V5_MIN 0x50000000
+
+#define APID_MAP_OFFSET_V1_V2_V3 (0x800)
+#define APID_MAP_OFFSET_V5 (0x900)
+#define ARB_CHANNEL_OFFSET(n) (0x4 * (n))
+#define SPMI_CH_OFFSET(chnl) ((chnl) * 0x8000)
+#define SPMI_V5_OBS_CH_OFFSET(chnl) ((chnl) * 0x80)
+#define SPMI_V5_RW_CH_OFFSET(chnl) ((chnl) * 0x10000)
+
+#define SPMI_REG_CMD0 0x0
+#define SPMI_REG_CONFIG 0x4
+#define SPMI_REG_STATUS 0x8
+#define SPMI_REG_WDATA 0x10
+#define SPMI_REG_RDATA 0x18
+
+#define SPMI_CMD_OPCODE_SHIFT 27
+#define SPMI_CMD_SLAVE_ID_SHIFT 20
+#define SPMI_CMD_ADDR_SHIFT 12
+#define SPMI_CMD_ADDR_OFFSET_SHIFT 4
+#define SPMI_CMD_BYTE_CNT_SHIFT 0
+
+#define SPMI_CMD_EXT_REG_WRITE_LONG 0x00
+#define SPMI_CMD_EXT_REG_READ_LONG 0x01
+
+#define SPMI_STATUS_DONE 0x1
+
+#define SPMI_MAX_CHANNELS 128
+#define SPMI_MAX_SLAVES 16
+#define SPMI_MAX_PERIPH 256
+
+enum arb_ver {
+ V1 = 1,
+ V2,
+ V3,
+ V5 = 5
+};
-#define SPMI_MAX_CHANNELS 128
-#define SPMI_MAX_SLAVES 16
-#define SPMI_MAX_PERIPH 256
+/*
+ * PMIC arbiter version 5 uses different register offsets for read/write vs
+ * observer channels.
+ */
+enum pmic_arb_channel {
+ PMIC_ARB_CHANNEL_RW,
+ PMIC_ARB_CHANNEL_OBS,
+};
struct msm_spmi_priv {
- phys_addr_t arb_chnl; /* ARB channel mapping base */
+ phys_addr_t arb_chnl; /* ARB channel mapping base */
phys_addr_t spmi_core; /* SPMI core */
- phys_addr_t spmi_obs; /* SPMI observer */
+ phys_addr_t spmi_obs; /* SPMI observer */
/* SPMI channel map */
uint8_t channel_map[SPMI_MAX_SLAVES][SPMI_MAX_PERIPH];
+ /* SPMI bus arbiter version */
+ u32 arb_ver;
};
static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
@@ -59,6 +83,7 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
{
struct msm_spmi_priv *priv = dev_get_priv(dev);
unsigned channel;
+ unsigned int ch_offset;
uint32_t reg = 0;
if (usid >= SPMI_MAX_SLAVES)
@@ -69,8 +94,8 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
channel = priv->channel_map[usid][pid];
/* Disable IRQ mode for the current channel*/
- writel(0x0, priv->spmi_core + SPMI_CH_OFFSET(channel) +
- SPMI_REG_CONFIG);
+ writel(0x0,
+ priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG);
/* Write single byte */
writel(val, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_WDATA);
@@ -82,6 +107,11 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
reg |= (off << SPMI_CMD_ADDR_OFFSET_SHIFT);
reg |= 1; /* byte count */
+ if (priv->arb_ver == V5)
+ ch_offset = SPMI_V5_RW_CH_OFFSET(channel);
+ else
+ ch_offset = SPMI_CH_OFFSET(channel);
+
/* Send write command */
writel(reg, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0);
@@ -104,6 +134,7 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
{
struct msm_spmi_priv *priv = dev_get_priv(dev);
unsigned channel;
+ unsigned int ch_offset;
uint32_t reg = 0;
if (usid >= SPMI_MAX_SLAVES)
@@ -113,8 +144,13 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
channel = priv->channel_map[usid][pid];
+ if (priv->arb_ver == V5)
+ ch_offset = SPMI_V5_OBS_CH_OFFSET(channel);
+ else
+ ch_offset = SPMI_CH_OFFSET(channel);
+
/* Disable IRQ mode for the current channel*/
- writel(0x0, priv->spmi_obs + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG);
+ writel(0x0, priv->spmi_obs + ch_offset + SPMI_REG_CONFIG);
/* Prepare read command */
reg |= SPMI_CMD_EXT_REG_READ_LONG << SPMI_CMD_OPCODE_SHIFT;
@@ -124,13 +160,12 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
reg |= 1; /* byte count */
/* Request read */
- writel(reg, priv->spmi_obs + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0);
+ writel(reg, priv->spmi_obs + ch_offset + SPMI_REG_CMD0);
/* Wait till CMD DONE status */
reg = 0;
while (!reg) {
- reg = readl(priv->spmi_obs + SPMI_CH_OFFSET(channel) +
- SPMI_REG_STATUS);
+ reg = readl(priv->spmi_obs + ch_offset + SPMI_REG_STATUS);
}
if (reg ^ SPMI_STATUS_DONE) {
@@ -139,8 +174,8 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
}
/* Read the data */
- return readl(priv->spmi_obs + SPMI_CH_OFFSET(channel) +
- SPMI_REG_RDATA) & 0xFF;
+ return readl(priv->spmi_obs + ch_offset +
+ SPMI_REG_RDATA) & 0xFF;
}
static struct dm_spmi_ops msm_spmi_ops = {
@@ -150,31 +185,50 @@ static struct dm_spmi_ops msm_spmi_ops = {
static int msm_spmi_probe(struct udevice *dev)
{
- struct udevice *parent = dev->parent;
struct msm_spmi_priv *priv = dev_get_priv(dev);
- int node = dev_of_offset(dev);
+ phys_addr_t config_addr;
u32 hw_ver;
- bool is_v1;
+ u32 version;
int i;
+ int err;
+
+ config_addr = dev_read_addr_index(dev, 0);
+ priv->spmi_core = dev_read_addr_index(dev, 1);
+ priv->spmi_obs = dev_read_addr_index(dev, 2);
+
+ hw_ver = readl(config_addr + PMIC_ARB_VERSION);
+
+ if (hw_ver < PMIC_ARB_VERSION_V3_MIN) {
+ priv->arb_ver = V2;
+ version = 2;
+ priv->arb_chnl = config_addr + APID_MAP_OFFSET_V1_V2_V3;
+ } else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) {
+ priv->arb_ver = V3;
+ version = 3;
+ priv->arb_chnl = config_addr + APID_MAP_OFFSET_V1_V2_V3;
+ } else {
+ priv->arb_ver = V5;
+ version = 5;
+ priv->arb_chnl = config_addr + APID_MAP_OFFSET_V5;
+
+ if (err) {
+ dev_err(dev, "could not read APID->PPID mapping table, rc= %d\n", err);
+ return -1;
+ }
+ }
- priv->arb_chnl = dev_read_addr(dev);
- priv->spmi_core = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
- dev_of_offset(parent), node, "reg", 1, NULL, false);
- priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
- dev_of_offset(parent), node, "reg", 2, NULL, false);
-
- hw_ver = readl(priv->arb_chnl + PMIC_ARB_VERSION - 0x800);
- is_v1 = (hw_ver < PMIC_ARB_VERSION_V2_MIN);
-
- dev_dbg(dev, "PMIC Arb Version-%d (0x%x)\n", (is_v1 ? 1 : 2), hw_ver);
+ dev_dbg(dev, "PMIC Arb Version-%d (0x%x)\n", version, hw_ver);
if (priv->arb_chnl == FDT_ADDR_T_NONE ||
priv->spmi_core == FDT_ADDR_T_NONE ||
priv->spmi_obs == FDT_ADDR_T_NONE)
return -EINVAL;
+ dev_dbg(dev, "priv->arb_chnl address (%llu)\n", priv->arb_chnl);
+ dev_dbg(dev, "priv->spmi_core address (%llu)\n", priv->spmi_core);
+ dev_dbg(dev, "priv->spmi_obs address (%llu)\n", priv->spmi_obs);
/* Scan peripherals connected to each SPMI channel */
- for (i = 0; i < SPMI_MAX_PERIPH ; i++) {
+ for (i = 0; i < SPMI_MAX_PERIPH; i++) {
uint32_t periph = readl(priv->arb_chnl + ARB_CHANNEL_OFFSET(i));
uint8_t slave_id = (periph & 0xf0000) >> 16;
uint8_t pid = (periph & 0xff00) >> 8;
@@ -195,5 +249,5 @@ U_BOOT_DRIVER(msm_spmi) = {
.of_match = msm_spmi_ids,
.ops = &msm_spmi_ops,
.probe = msm_spmi_probe,
- .priv_auto = sizeof(struct msm_spmi_priv),
+ .priv_auto = sizeof(struct msm_spmi_priv),
};
diff --git a/include/configs/apple.h b/include/configs/apple.h
new file mode 100644
index 0000000000..b1f6043174
--- /dev/null
+++ b/include/configs/apple.h
@@ -0,0 +1,36 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_SDRAM_BASE 0x880000000
+
+#define CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE CONFIG_SYS_TEXT_BASE
+
+/* Environment */
+#define ENV_DEVICE_SETTINGS \
+ "stdin=serial,usbkbd\0" \
+ "stdout=serial,vidconsole\0" \
+ "stderr=serial,vidconsole\0"
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+ "fdt_addr_r=0x960100000\0" \
+ "kernel_addr_r=0x960200000\0"
+
+#if CONFIG_IS_ENABLED(CMD_USB)
+ #define BOOT_TARGET_USB(func) func(USB, usb, 0)
+#else
+ #define BOOT_TARGET_USB(func)
+#endif
+
+#define BOOT_TARGET_DEVICES(func) \
+ BOOT_TARGET_USB(func)
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ ENV_DEVICE_SETTINGS \
+ ENV_MEM_LAYOUT_SETTINGS \
+ BOOTENV
+
+#endif
diff --git a/include/configs/exynos78x0-common.h b/include/configs/exynos78x0-common.h
new file mode 100644
index 0000000000..478a0c42b1
--- /dev/null
+++ b/include/configs/exynos78x0-common.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration settings for the EXYNOS 78x0 based boards.
+ *
+ * Copyright (c) 2020 Dzmitry Sankouski (dsankouski@gmail.com)
+ * based on include/exynos7420-common.h
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ */
+
+#ifndef __CONFIG_EXYNOS78x0_COMMON_H
+#define __CONFIG_EXYNOS78x0_COMMON_H
+
+/* High Level Configuration Options */
+#define CONFIG_SAMSUNG /* in a SAMSUNG core */
+#define CONFIG_S5P
+
+#include <asm/arch/cpu.h> /* get chip and board defs */
+#include <linux/sizes.h>
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE 1024 /* Print Buffer Size */
+
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+/* Timer input clock frequency */
+#define COUNTER_FREQUENCY 26000000
+
+/* Device Tree */
+#define CONFIG_DEVICE_TREE_LIST "EXYNOS78x0-a5y17lte"
+
+#define CPU_RELEASE_ADDR secondary_boot_addr
+
+#define CONFIG_SYS_BAUDRATE_TABLE \
+ {9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600}
+
+#define CONFIG_BOARD_COMMON
+
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - GENERATED_GBL_DATA_SIZE)
+/* DRAM Memory Banks */
+#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */
+#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE
+#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE)
+#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_8_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_9 (CONFIG_SYS_SDRAM_BASE + (8 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_9_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_10 (CONFIG_SYS_SDRAM_BASE + (9 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_10_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_11 (CONFIG_SYS_SDRAM_BASE + (10 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_11_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_12 (CONFIG_SYS_SDRAM_BASE + (11 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_12_SIZE SDRAM_BANK_SIZE
+
+#define CONFIG_DEBUG_UART_CLOCK 132710400
+
+#define CONFIG_PREBOOT \
+"echo Read pressed buttons status;" \
+"KEY_VOLUMEUP=gpa20;" \
+"KEY_HOME=gpa17;" \
+"KEY_VOLUMEDOWN=gpa21;" \
+"KEY_POWER=gpa00;" \
+"PRESSED=0;" \
+"RELEASED=1;" \
+"if gpio input $KEY_VOLUMEUP; then setenv VOLUME_UP $PRESSED; " \
+"else setenv VOLUME_UP $RELEASED; fi;" \
+"if gpio input $KEY_VOLUMEDOWN; then setenv VOLUME_DOWN $PRESSED; " \
+"else setenv VOLUME_DOWN $RELEASED; fi;" \
+"if gpio input $KEY_HOME; then setenv HOME $PRESSED; else setenv HOME $RELEASED; fi;" \
+"if gpio input $KEY_POWER; then setenv POWER $PRESSED; else setenv POWER $RELEASED; fi;"
+
+#ifndef MEM_LAYOUT_ENV_SETTINGS
+#define MEM_LAYOUT_ENV_SETTINGS \
+ "bootm_size=0x10000000\0" \
+ "bootm_low=0x40000000\0"
+#endif
+
+#ifndef EXYNOS_DEVICE_SETTINGS
+#define EXYNOS_DEVICE_SETTINGS \
+ "stdin=serial\0" \
+ "stdout=serial\0" \
+ "stderr=serial\0"
+#endif
+
+#ifndef EXYNOS_FDTFILE_SETTING
+#define EXYNOS_FDTFILE_SETTING
+#endif
+
+#define EXTRA_ENV_SETTINGS \
+ EXYNOS_DEVICE_SETTINGS \
+ EXYNOS_FDTFILE_SETTING \
+ MEM_LAYOUT_ENV_SETTINGS
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ EXTRA_ENV_SETTINGS
+
+#endif /* __CONFIG_EXYNOS78x0_COMMON_H */
diff --git a/include/configs/sdm845.h b/include/configs/sdm845.h
new file mode 100644
index 0000000000..af9ba197d4
--- /dev/null
+++ b/include/configs/sdm845.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration file for boards, based on Qualcomm SDM845 chip
+ *
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ */
+
+#ifndef __CONFIGS_SDM845_H
+#define __CONFIGS_SDM845_H
+
+#include <linux/sizes.h>
+#include <asm/arch/sysmap-sdm845.h>
+
+#define CONFIG_SYS_BAUDRATE_TABLE { 115200, 230400, 460800, 921600 }
+
+/* Generic Timer Definitions */
+#define COUNTER_FREQUENCY 19000000
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_BOOTM_LEN SZ_64M
+
+/* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE 512
+#define CONFIG_SYS_MAXARGS 64
+
+#endif
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 3768432b68..fd139b9b2a 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -62,6 +62,7 @@ enum uclass_id {
UCLASS_I2C_MUX, /* I2C multiplexer */
UCLASS_I2S, /* I2S bus */
UCLASS_IDE, /* IDE device */
+ UCLASS_IOMMU, /* IOMMU */
UCLASS_IRQ, /* Interrupt controller */
UCLASS_KEYBOARD, /* Keyboard input device */
UCLASS_LED, /* Light-emitting diode (LED) */
diff --git a/include/dt-bindings/interrupt-controller/apple-aic.h b/include/dt-bindings/interrupt-controller/apple-aic.h
new file mode 100644
index 0000000000..9ac56a7e6d
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/apple-aic.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define AIC_IRQ 0
+#define AIC_FIQ 1
+
+#define AIC_TMR_HV_PHYS 0
+#define AIC_TMR_HV_VIRT 1
+#define AIC_TMR_GUEST_PHYS 2
+#define AIC_TMR_GUEST_VIRT 3
+
+#endif
diff --git a/include/dt-bindings/pinctrl/apple.h b/include/dt-bindings/pinctrl/apple.h
new file mode 100644
index 0000000000..ea0a6f4665
--- /dev/null
+++ b/include/dt-bindings/pinctrl/apple.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR MIT */
+/*
+ * This header provides constants for Apple pinctrl bindings.
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_APPLE_H
+#define _DT_BINDINGS_PINCTRL_APPLE_H
+
+#define APPLE_PINMUX(pin, func) ((pin) | ((func) << 16))
+#define APPLE_PIN(pinmux) ((pinmux) & 0xffff)
+#define APPLE_FUNC(pinmux) ((pinmux) >> 16)
+
+#endif /* _DT_BINDINGS_PINCTRL_APPLE_H */
diff --git a/include/dt-bindings/spmi/spmi.h b/include/dt-bindings/spmi/spmi.h
new file mode 100644
index 0000000000..ad4a43481d
--- /dev/null
+++ b/include/dt-bindings/spmi/spmi.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ */
+#ifndef __DT_BINDINGS_SPMI_H
+#define __DT_BINDINGS_SPMI_H
+
+#define SPMI_USID 0
+#define SPMI_GSID 1
+
+#endif
diff --git a/include/iommu.h b/include/iommu.h
new file mode 100644
index 0000000000..6c46adf449
--- /dev/null
+++ b/include/iommu.h
@@ -0,0 +1,16 @@
+#ifndef _IOMMU_H
+#define _IOMMU_H
+
+struct udevice;
+
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \
+ CONFIG_IS_ENABLED(IOMMU)
+int dev_iommu_enable(struct udevice *dev);
+#else
+static inline int dev_iommu_enable(struct udevice *dev)
+{
+ return 0;
+}
+#endif
+
+#endif
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 55162e9499..7de013f636 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_DM_I2C) += i2c.o
obj-$(CONFIG_SOUND) += i2s.o
obj-y += irq.o
obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o
+obj-$(CONFIG_IOMMU) += iommu.o
obj-$(CONFIG_LED) += led.o
obj-$(CONFIG_DM_MAILBOX) += mailbox.o
obj-$(CONFIG_DM_MDIO) += mdio.o
diff --git a/test/dm/iommu.c b/test/dm/iommu.c
new file mode 100644
index 0000000000..94174a7482
--- /dev/null
+++ b/test/dm/iommu.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <iommu.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int dm_test_iommu(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+
+ ut_assertok(uclass_find_device(UCLASS_IOMMU, 0, &dev));
+ ut_assert(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED));
+
+ /* Probing USB probes the IOMMU through the "iommus" property */
+ ut_assertok(uclass_probe_all(UCLASS_USB));
+ ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
+
+ return 0;
+}
+
+DM_TEST(dm_test_iommu, UT_TESTF_SCAN_FDT);