summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig5
-rw-r--r--arch/arm/Kconfig16
-rw-r--r--arch/arm/config.mk4
-rw-r--r--arch/arm/cpu/arm11/cpu.c17
-rw-r--r--arch/arm/cpu/arm926ejs/cache.c17
-rw-r--r--arch/arm/cpu/armv7/Kconfig2
-rw-r--r--arch/arm/cpu/armv7/Makefile2
-rw-r--r--arch/arm/cpu/armv7/am33xx/config.mk1
-rw-r--r--arch/arm/cpu/armv7/am33xx/ddr.c24
-rw-r--r--arch/arm/cpu/armv7/cache_v7.c48
-rw-r--r--arch/arm/cpu/armv7/ls102xa/psci.S156
-rw-r--r--arch/arm/cpu/armv7/mx7/psci-mx7.c2
-rw-r--r--arch/arm/cpu/armv7/mx7/psci.S31
-rw-r--r--arch/arm/cpu/armv7/nonsec_virt.S7
-rw-r--r--arch/arm/cpu/armv7/omap-common/Makefile2
-rw-r--r--arch/arm/cpu/armv7/omap-common/config_secure.mk75
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c3
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c3
-rw-r--r--arch/arm/cpu/armv7/omap-common/lowlevel_init.S45
-rw-r--r--arch/arm/cpu/armv7/omap-common/mem-common.c156
-rw-r--r--arch/arm/cpu/armv7/omap-common/sec-common.c139
-rw-r--r--arch/arm/cpu/armv7/omap3/spl_id_nand.c57
-rw-r--r--arch/arm/cpu/armv7/omap5/config.mk3
-rw-r--r--arch/arm/cpu/armv7/psci-common.c39
-rw-r--r--arch/arm/cpu/armv7/psci.S133
-rw-r--r--arch/arm/cpu/armv7/sunxi/Makefile1
-rw-r--r--arch/arm/cpu/armv7/sunxi/psci.c9
-rw-r--r--arch/arm/cpu/armv7/sunxi/psci_head.S66
-rw-r--r--arch/arm/cpu/armv7/virt-dt.c63
-rw-r--r--arch/arm/cpu/armv7m/config.mk2
-rw-r--r--arch/arm/cpu/armv8/Kconfig18
-rw-r--r--arch/arm/cpu/armv8/Makefile5
-rw-r--r--arch/arm/cpu/armv8/cache_v8.c112
-rw-r--r--arch/arm/cpu/armv8/cpu-dt.c31
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/Makefile5
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/cpu.c404
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch32
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc42
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fdt.c33
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c19
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c25
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c99
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/ppa.c48
-rw-r--r--arch/arm/cpu/armv8/s32v234/cpu.c12
-rw-r--r--arch/arm/cpu/armv8/sec_firmware.c270
-rw-r--r--arch/arm/cpu/armv8/sec_firmware_asm.S53
-rw-r--r--arch/arm/cpu/armv8/spin_table.c63
-rw-r--r--arch/arm/cpu/armv8/spin_table_v8.S23
-rw-r--r--arch/arm/cpu/armv8/start.S27
-rw-r--r--arch/arm/cpu/armv8/zynqmp/clk.c16
-rw-r--r--arch/arm/cpu/armv8/zynqmp/cpu.c21
-rw-r--r--arch/arm/cpu/armv8/zynqmp/mp.c2
-rw-r--r--arch/arm/cpu/u-boot.lds60
-rw-r--r--arch/arm/dts/Makefile9
-rw-r--r--arch/arm/dts/dra7-evm.dts6
-rw-r--r--arch/arm/dts/dra72-evm.dts6
-rw-r--r--arch/arm/dts/exynos4210-origen.dts2
-rw-r--r--arch/arm/dts/exynos4210-trats.dts4
-rw-r--r--arch/arm/dts/exynos4210-universal_c210.dts4
-rw-r--r--arch/arm/dts/exynos4412-odroid.dts4
-rw-r--r--arch/arm/dts/exynos4412-trats2.dts6
-rw-r--r--arch/arm/dts/k2e-evm.dts3
-rw-r--r--arch/arm/dts/k2g-evm.dts69
-rw-r--r--arch/arm/dts/k2g.dtsi61
-rw-r--r--arch/arm/dts/k2hk-evm.dts3
-rw-r--r--arch/arm/dts/k2l-evm.dts3
-rw-r--r--arch/arm/dts/keystone.dtsi3
-rw-r--r--arch/arm/dts/rk3288-evb.dts59
-rw-r--r--arch/arm/dts/rk3288-evb.dtsi379
-rw-r--r--arch/arm/dts/rk3288-firefly.dts3
-rw-r--r--arch/arm/dts/rk3288.dtsi1
-rw-r--r--arch/arm/dts/rk3399-evb.dts104
-rw-r--r--arch/arm/dts/rk3399.dtsi1028
-rw-r--r--arch/arm/dts/sun50i-a64-pine64-plus.dts13
-rw-r--r--arch/arm/dts/sun50i-a64.dtsi33
-rw-r--r--arch/arm/dts/sun5i-a10s.dtsi14
-rw-r--r--arch/arm/dts/sun5i-a13-olinuxino.dts15
-rw-r--r--arch/arm/dts/sun5i-r8-chip.dts15
-rw-r--r--arch/arm/dts/sun5i.dtsi49
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-2.dts13
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-lite.dts178
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-pc-plus.dts87
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-pc.dts12
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-plus.dts127
-rw-r--r--arch/arm/dts/sun8i-h3.dtsi39
-rw-r--r--arch/arm/dts/tegra186-p2771-0000-a02.dts8
-rw-r--r--arch/arm/dts/tegra186-p2771-0000-b00.dts8
-rw-r--r--arch/arm/dts/tegra186-p2771-0000.dtsi (renamed from arch/arm/dts/tegra186-p2771-0000.dts)2
-rw-r--r--arch/arm/dts/tegra186.dtsi2
-rw-r--r--arch/arm/dts/uniphier-proxstream2-gentil.dts8
-rw-r--r--arch/arm/dts/uniphier-proxstream2-vodka.dts8
-rw-r--r--arch/arm/imx-common/ddrmc-vf610.c2
-rw-r--r--arch/arm/include/asm/arch-am33xx/sys_proto.h3
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/config.h82
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/cpu.h312
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h3
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h9
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h5
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/ppa.h16
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/soc.h2
-rw-r--r--arch/arm/include/asm/arch-ls102xa/config.h9
-rw-r--r--arch/arm/include/asm/arch-omap3/sys_proto.h7
-rw-r--r--arch/arm/include/asm/arch-omap4/i2c.h6
-rw-r--r--arch/arm/include/asm/arch-omap5/i2c.h6
-rw-r--r--arch/arm/include/asm/arch-rockchip/clock.h4
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram.h14
-rw-r--r--arch/arm/include/asm/arch-stm32f7/fmc.h75
-rw-r--r--arch/arm/include/asm/arch-stm32f7/stm32.h46
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun4i.h5
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun6i.h4
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sun4i.h3
-rw-r--r--arch/arm/include/asm/arch-sunxi/gpio.h3
-rw-r--r--arch/arm/include/asm/arch-sunxi/mmc.h1
-rw-r--r--arch/arm/include/asm/arch-sunxi/spl.h9
-rw-r--r--arch/arm/include/asm/arch-tegra/board.h2
-rw-r--r--arch/arm/include/asm/arch-tegra/clock.h2
-rw-r--r--arch/arm/include/asm/arch-tegra/ivc.h179
-rw-r--r--arch/arm/include/asm/arch-tegra124/display.h2
-rw-r--r--arch/arm/include/asm/arch-zynqmp/clk.h1
-rw-r--r--arch/arm/include/asm/armv7.h2
-rw-r--r--arch/arm/include/asm/armv7m.h11
-rw-r--r--arch/arm/include/asm/armv8/mmu.h5
-rw-r--r--arch/arm/include/asm/armv8/sec_firmware.h22
-rw-r--r--arch/arm/include/asm/cache.h2
-rw-r--r--arch/arm/include/asm/fsl_secure_boot.h68
-rw-r--r--arch/arm/include/asm/global_data.h15
-rw-r--r--arch/arm/include/asm/io.h34
-rw-r--r--arch/arm/include/asm/omap_common.h6
-rw-r--r--arch/arm/include/asm/omap_sec_common.h30
-rw-r--r--arch/arm/include/asm/psci.h31
-rw-r--r--arch/arm/include/asm/secure.h3
-rw-r--r--arch/arm/include/asm/spin_table.h14
-rw-r--r--arch/arm/include/asm/types.h1
-rw-r--r--arch/arm/lib/Makefile4
-rw-r--r--arch/arm/lib/bootm-fdt.c9
-rw-r--r--arch/arm/lib/bootm.c32
-rw-r--r--arch/arm/lib/cache.c22
-rw-r--r--arch/arm/lib/crt0_64.S3
-rw-r--r--arch/arm/lib/psci-dt.c123
-rw-r--r--arch/arm/lib/sections.c2
-rw-r--r--arch/arm/lib/spl.c26
-rw-r--r--arch/arm/lib/zimage.c40
-rw-r--r--arch/arm/mach-exynos/include/mach/dwmmc.h1
-rw-r--r--arch/arm/mach-exynos/mmu-arm64.c9
-rw-r--r--arch/arm/mach-keystone/init.c2
-rw-r--r--arch/arm/mach-meson/board.c6
-rw-r--r--arch/arm/mach-rockchip/Kconfig63
-rw-r--r--arch/arm/mach-rockchip/Makefile8
-rw-r--r--arch/arm/mach-rockchip/board.c107
-rw-r--r--arch/arm/mach-rockchip/rk3036/Kconfig4
-rw-r--r--arch/arm/mach-rockchip/rk3036/Makefile1
-rw-r--r--arch/arm/mach-rockchip/rk3288-board-spl.c33
-rw-r--r--arch/arm/mach-rockchip/rk3288/Kconfig10
-rw-r--r--arch/arm/mach-rockchip/rk3288/Makefile1
-rw-r--r--arch/arm/mach-rockchip/rk3288/clk_rk3288.c17
-rw-r--r--arch/arm/mach-rockchip/rk3288/sdram_rk3288.c148
-rw-r--r--arch/arm/mach-rockchip/rk3288/syscon_rk3288.c38
-rw-r--r--arch/arm/mach-rockchip/rk3399/Kconfig23
-rw-r--r--arch/arm/mach-rockchip/rk3399/Makefile7
-rw-r--r--arch/arm/mach-rockchip/rk3399/rk3399.c30
-rw-r--r--arch/arm/mach-rockchip/save_boot_param.S (renamed from arch/arm/mach-rockchip/rk3036/save_boot_param.S)2
-rw-r--r--arch/arm/mach-snapdragon/sysmap-apq8016.c6
-rw-r--r--arch/arm/mach-stm32/stm32f7/Makefile2
-rw-r--r--arch/arm/mach-stm32/stm32f7/clock.c228
-rw-r--r--arch/arm/mach-stm32/stm32f7/soc.c76
-rw-r--r--arch/arm/mach-sunxi/board.c35
-rw-r--r--arch/arm/mach-tegra/Kconfig9
-rw-r--r--arch/arm/mach-tegra/Makefile13
-rw-r--r--arch/arm/mach-tegra/arm64-mmu.c6
-rw-r--r--arch/arm/mach-tegra/board186.c12
-rw-r--r--arch/arm/mach-tegra/clock.c2
-rw-r--r--arch/arm/mach-tegra/ivc.c553
-rw-r--r--arch/arm/mach-tegra/psci.S16
-rw-r--r--arch/arm/mach-tegra/tegra186/Makefile5
-rw-r--r--arch/arm/mach-tegra/tegra186/nvtboot_ll.S20
-rw-r--r--arch/arm/mach-tegra/tegra186/nvtboot_mem.c88
-rw-r--r--arch/arm/mach-uniphier/Kconfig1
-rw-r--r--arch/arm/mach-uniphier/arm32/Makefile2
-rw-r--r--arch/arm/mach-uniphier/arm32/cache-uniphier.c165
-rw-r--r--arch/arm/mach-uniphier/arm32/cache_uniphier.c156
-rw-r--r--arch/arm/mach-uniphier/arm32/late_lowlevel_init.S4
-rw-r--r--arch/arm/mach-uniphier/arm32/lowlevel_init.S18
-rw-r--r--arch/arm/mach-uniphier/arm32/ssc-regs.h101
-rw-r--r--arch/arm/mach-uniphier/arm64/arm-cci500.c9
-rw-r--r--arch/arm/mach-uniphier/arm64/mem_map.c6
-rw-r--r--arch/arm/mach-uniphier/arm64/smp_kick_cpus.c9
-rw-r--r--arch/arm/mach-uniphier/arm64/timer.c9
-rw-r--r--arch/arm/mach-uniphier/boards.c24
-rw-r--r--arch/arm/mach-uniphier/clk/clk-pxs2.c7
-rw-r--r--arch/arm/mach-uniphier/dram/cmd_ddrphy.c13
-rw-r--r--arch/arm/mach-uniphier/dram/umc-ld4.c6
-rw-r--r--arch/arm/mach-uniphier/dram/umc-pro4.c6
-rw-r--r--arch/arm/mach-uniphier/dram/umc-sld8.c6
-rw-r--r--arch/arm/mach-uniphier/init.h8
-rw-r--r--arch/arm/mach-uniphier/sc-regs.h8
-rw-r--r--arch/nds32/include/asm/io.h34
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu_init.c4
-rw-r--r--arch/powerpc/cpu/mpc85xx/mp.c2
-rw-r--r--arch/powerpc/cpu/mpc85xx/start.S12
-rw-r--r--arch/powerpc/cpu/mpc86xx/config.mk2
-rw-r--r--arch/powerpc/cpu/mpc8xxx/fsl_pamu.c8
-rw-r--r--arch/powerpc/cpu/mpc8xxx/pamu_table.c8
-rw-r--r--arch/powerpc/cpu/ppc4xx/start.S2
-rw-r--r--arch/powerpc/include/asm/arch-mpc85xx/gpio.h6
-rw-r--r--arch/powerpc/include/asm/fsl_secure_boot.h45
-rw-r--r--arch/powerpc/include/asm/status_led.h2
-rw-r--r--arch/sandbox/Kconfig7
-rw-r--r--arch/sandbox/config.mk5
-rw-r--r--arch/sandbox/cpu/Makefile1
-rw-r--r--arch/sandbox/cpu/cpu.c6
-rw-r--r--arch/sandbox/cpu/os.c51
-rw-r--r--arch/sandbox/cpu/spl.c68
-rw-r--r--arch/sandbox/cpu/start.c2
-rw-r--r--arch/sandbox/cpu/u-boot-spl.lds24
-rw-r--r--arch/sandbox/dts/sandbox.dts31
-rw-r--r--arch/sandbox/include/asm/spl.h23
-rw-r--r--arch/sandbox/lib/Makefile2
-rw-r--r--arch/sandbox/lib/bootm.c2
-rw-r--r--arch/sh/include/asm/io.h33
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/cpu/baytrail/Kconfig11
-rw-r--r--arch/x86/cpu/baytrail/acpi.c26
-rw-r--r--arch/x86/cpu/ivybridge/lpc.c6
-rw-r--r--arch/x86/cpu/ivybridge/sdram.c5
-rw-r--r--arch/x86/cpu/quark/acpi.c7
-rw-r--r--arch/x86/dts/Makefile3
-rw-r--r--arch/x86/dts/baytrail_som-db5800-som-6867.dts289
-rw-r--r--arch/x86/include/asm/acpi/global_nvs.h19
-rw-r--r--arch/x86/include/asm/acpi_table.h4
-rw-r--r--arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl15
-rw-r--r--arch/x86/include/asm/arch-baytrail/acpi/lpc.asl19
-rw-r--r--arch/x86/include/asm/arch-baytrail/acpi/platform.asl3
-rw-r--r--arch/x86/include/asm/arch-baytrail/global_nvs.h21
-rw-r--r--arch/x86/include/asm/arch-quark/acpi/global_nvs.asl14
-rw-r--r--arch/x86/include/asm/arch-quark/acpi/platform.asl3
-rw-r--r--arch/x86/include/asm/arch-quark/global_nvs.h20
-rw-r--r--arch/x86/lib/acpi_table.c22
-rw-r--r--arch/x86/lib/fsp/fsp_support.c2
238 files changed, 7448 insertions, 1787 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 566f044308..92d4b97701 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1,6 +1,9 @@
config CREATE_ARCH_SYMLINK
bool
+config HAVE_ARCH_IOREMAP
+ bool
+
choice
prompt "Architecture select"
default SANDBOX
@@ -33,6 +36,7 @@ config MICROBLAZE
config MIPS
bool "MIPS architecture"
+ select HAVE_ARCH_IOREMAP
select HAVE_PRIVATE_LIBGCC
select SUPPORT_OF_CONTROL
@@ -63,6 +67,7 @@ config SANDBOX
select DM_I2C
select DM_SPI
select DM_GPIO
+ select DM_MMC
config SH
bool "SuperH architecture"
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3237a74f72..4a62d4b108 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -669,6 +669,8 @@ config ARCH_ZYNQMP
select OF_CONTROL
select DM_SERIAL
select SUPPORT_SPL
+ select CLK
+ select SPL_CLK
config TEGRA
bool "NVIDIA Tegra"
@@ -838,11 +840,19 @@ config STM32
config ARCH_ROCKCHIP
bool "Support Rockchip SoCs"
- select SUPPORT_SPL
- select SPL
select OF_CONTROL
- select CPU_V7
+ select BLK
select DM
+ select SPL_DM if SPL
+ select SYS_MALLOC_F
+ select SPL_SYS_MALLOC_SIMPLE if SPL
+ select DM_GPIO
+ select DM_I2C
+ select DM_MMC
+ select DM_MMC_OPS
+ select DM_SERIAL
+ select DM_SPI
+ select DM_SPI_FLASH
config TARGET_THUNDERX_88XX
bool "Support ThunderX 88xx"
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 9a5a9747c4..8f8586295e 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -120,8 +120,8 @@ endif
ifdef CONFIG_ARM64
OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
else
-OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j \
- .got -j .got.plt -j .u_boot_list -j .rel.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
+ -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn
endif
ifdef CONFIG_OF_EMBED
diff --git a/arch/arm/cpu/arm11/cpu.c b/arch/arm/cpu/arm11/cpu.c
index 1e4c2142b1..7244c2e7d7 100644
--- a/arch/arm/cpu/arm11/cpu.c
+++ b/arch/arm/cpu/arm11/cpu.c
@@ -69,23 +69,6 @@ void flush_dcache_all(void)
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
}
-static int check_cache_range(unsigned long start, unsigned long stop)
-{
- int ok = 1;
-
- if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (!ok)
- debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
- start, stop);
-
- return ok;
-}
-
void invalidate_dcache_range(unsigned long start, unsigned long stop)
{
if (!check_cache_range(start, stop))
diff --git a/arch/arm/cpu/arm926ejs/cache.c b/arch/arm/cpu/arm926ejs/cache.c
index 2839c863e8..2119382ab2 100644
--- a/arch/arm/cpu/arm926ejs/cache.c
+++ b/arch/arm/cpu/arm926ejs/cache.c
@@ -29,23 +29,6 @@ void flush_dcache_all(void)
);
}
-static int check_cache_range(unsigned long start, unsigned long stop)
-{
- int ok = 1;
-
- if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (!ok)
- debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
- start, stop);
-
- return ok;
-}
-
void invalidate_dcache_range(unsigned long start, unsigned long stop)
{
if (!check_cache_range(start, stop))
diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index afeaac84de..bd6108eec0 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -21,7 +21,7 @@ config ARMV7_BOOT_SEC_DEFAULT
Say Y here to boot in secure mode by default even if non-secure mode
is supported. This option is useful to boot kernels which do not
suppport booting in non-secure mode. Only set this if you need it.
- This can be overriden at run-time by setting the bootm_boot_mode env.
+ This can be overridden at run-time by setting the bootm_boot_mode env.
variable to "sec" or "nonsec".
config ARMV7_VIRT
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index ddd8d12d51..0d4bfbc55b 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -19,7 +19,7 @@ endif
endif
obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o
-obj-$(CONFIG_ARMV7_PSCI) += psci.o
+obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o
obj-$(CONFIG_IPROC) += iproc-common/
obj-$(CONFIG_KONA) += kona-common/
diff --git a/arch/arm/cpu/armv7/am33xx/config.mk b/arch/arm/cpu/armv7/am33xx/config.mk
index 6d95d327b4..d4eb21ca14 100644
--- a/arch/arm/cpu/armv7/am33xx/config.mk
+++ b/arch/arm/cpu/armv7/am33xx/config.mk
@@ -26,6 +26,7 @@ endif
else
ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER
+ALL-$(CONFIG_SPL_LOAD_FIT) += u-boot_HS.img
endif
ALL-y += u-boot.img
endif
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c
index 888cf1f732..6acf30c5db 100644
--- a/arch/arm/cpu/armv7/am33xx/ddr.c
+++ b/arch/arm/cpu/armv7/am33xx/ddr.c
@@ -120,12 +120,15 @@ void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+
+ /* Wait 1ms because of L3 timeout error */
+ udelay(1000);
+
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
/* Perform hardware leveling for DDR3 */
if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
- udelay(1000);
writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
@@ -289,19 +292,14 @@ static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr)
void config_ddr_phy(const struct emif_regs *regs, int nr)
{
/*
- * Disable initialization and refreshes for now until we
- * finish programming EMIF regs.
- * Also set time between rising edge of DDR_RESET to rising
- * edge of DDR_CKE to > 500us per memory spec.
+ * Disable initialization and refreshes for now until we finish
+ * programming EMIF regs and set time between rising edge of
+ * DDR_RESET to rising edge of DDR_CKE to > 500us per memory spec.
+ * We currently hardcode a value based on a max expected frequency
+ * of 400MHz.
*/
-#ifndef CONFIG_AM43XX
- setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
- EMIF_REG_INITREF_DIS_MASK);
-#endif
- if (regs->zq_config)
- /* Set time between rising edge of DDR_RESET to rising
- * edge of DDR_CKE to > 500us per memory spec. */
- writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
+ writel(EMIF_REG_INITREF_DIS_MASK | 0x3100,
+ &emif_reg[nr]->emif_sdram_ref_ctrl);
writel(regs->emif_ddr_phy_ctlr_1,
&emif_reg[nr]->emif_ddr_phy_ctrl_1);
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index dc309dac90..52f18565db 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -19,23 +19,6 @@
void v7_flush_dcache_all(void);
void v7_invalidate_dcache_all(void);
-static int check_cache_range(unsigned long start, unsigned long stop)
-{
- int ok = 1;
-
- if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (!ok)
- debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
- start, stop);
-
- return ok;
-}
-
static u32 get_ccsidr(void)
{
u32 ccsidr;
@@ -61,27 +44,8 @@ static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len)
{
u32 mva;
- /*
- * If start address is not aligned to cache-line do not
- * invalidate the first cache-line
- */
- if (start & (line_len - 1)) {
- printf("ERROR: %s - start address is not aligned - 0x%08x\n",
- __func__, start);
- /* move to next cache line */
- start = (start + line_len - 1) & ~(line_len - 1);
- }
-
- /*
- * If stop address is not aligned to cache-line do not
- * invalidate the last cache-line
- */
- if (stop & (line_len - 1)) {
- printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
- __func__, stop);
- /* align to the beginning of this cache line */
- stop &= ~(line_len - 1);
- }
+ if (!check_cache_range(start, stop))
+ return;
for (mva = start; mva < stop; mva = mva + line_len) {
/* DCIMVAC - Invalidate data cache by MVA to PoC */
@@ -195,6 +159,14 @@ void flush_dcache_all(void)
{
}
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
void arm_init_before_mmu(void)
{
}
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S
index cf5cd48bcb..8f386800f6 100644
--- a/arch/arm/cpu/armv7/ls102xa/psci.S
+++ b/arch/arm/cpu/armv7/ls102xa/psci.S
@@ -12,33 +12,118 @@
#include <asm/arch-armv7/generictimer.h>
#include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C
+
#define SCFG_CORE0_SFT_RST 0x130
#define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4
-#define DCFG_CCSR_SCRATCHRW1 0x200
+#define DCFG_CCSR_RSTCR 0x0B0
+#define DCFG_CCSR_RSTCR_RESET_REQ 0x2
+#define DCFG_CCSR_BRR 0x0E4
+#define DCFG_CCSR_SCRATCHRW1 0x200
+
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0
+#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0
+#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0
+#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
+ .align 5
+
#define ONE_MS (GENERIC_TIMER_CLK / 1000)
#define RESET_WAIT (30 * ONE_MS)
+.globl psci_version
+psci_version:
+ movw r0, #0
+ movt r0, #1
+
+ bx lr
+
+_ls102x_psci_supported_table:
+ .word ARM_PSCI_0_2_FN_PSCI_VERSION
+ .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_SUSPEND
+ .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_OFF
+ .word PSCI_FN_CPU_OFF_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_ON
+ .word PSCI_FN_CPU_ON_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_AFFINITY_INFO
+ .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_SYSTEM_OFF
+ .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_SYSTEM_RESET
+ .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
+ .word 0
+ .word ARM_PSCI_RET_NI
+
+.globl psci_features
+psci_features:
+ adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
+ cmp r3, #0
+ beq out_psci_features
+ cmp r1, r3
+ addne r2, r2, #8
+ bne 1b
+
+out_psci_features:
+ ldr r0, [r2, #4]
+ bx lr
+
+@ r0: return value ARM_PSCI_RET_SUCCESS or ARM_PSCI_RET_INVAL
+@ r1: input target CPU ID in MPIDR format, original value in r1 may be dropped
+@ r4: output validated CPU ID if ARM_PSCI_RET_SUCCESS returns, meaningless for
+@ ARM_PSCI_RET_INVAL,suppose caller saves r4 before calling
+LENTRY(psci_check_target_cpu_id)
+ @ Get the real CPU number
+ and r4, r1, #0xff
+ mov r0, #ARM_PSCI_RET_INVAL
+
+ @ Bit[31:24], bits must be zero.
+ tst r1, #0xff000000
+ bxne lr
+
+ @ Affinity level 2 - Cluster: only one cluster in LS1021xa.
+ tst r1, #0xff0000
+ bxne lr
+
+ @ Affinity level 1 - Processors: should be in 0xf00 format.
+ lsr r1, r1, #8
+ teq r1, #0xf
+ bxne lr
+
+ @ Affinity level 0 - CPU: only 0, 1 are valid in LS1021xa.
+ cmp r4, #2
+ bxge lr
+
+ mov r0, #ARM_PSCI_RET_SUCCESS
+ bx lr
+ENDPROC(psci_check_target_cpu_id)
+
@ r1 = target CPU
@ r2 = target PC
.globl psci_cpu_on
psci_cpu_on:
- push {lr}
+ push {r4, r5, r6, lr}
@ Clear and Get the correct CPU number
@ r1 = 0xf01
- and r1, r1, #0xff
+ bl psci_check_target_cpu_id
+ cmp r0, #ARM_PSCI_RET_INVAL
+ beq out_psci_cpu_on
- mov r0, r1
- bl psci_get_cpu_stack_top
- str r2, [r0]
- dsb
+ mov r0, r4
+ mov r1, r2
+ bl psci_save_target_pc
+ mov r1, r4
@ Get DCFG base address
movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
@@ -101,7 +186,8 @@ holdoff_release:
@ Return
mov r0, #ARM_PSCI_RET_SUCCESS
- pop {lr}
+out_psci_cpu_on:
+ pop {r4, r5, r6, lr}
bx lr
.globl psci_cpu_off
@@ -111,16 +197,50 @@ psci_cpu_off:
1: wfi
b 1b
-.globl psci_arch_init
-psci_arch_init:
- mov r6, lr
+.globl psci_affinity_info
+psci_affinity_info:
+ push {lr}
+
+ mov r0, #ARM_PSCI_RET_INVAL
+
+ @ Verify Affinity level
+ cmp r2, #0
+ bne out_affinity_info
+
+ bl psci_check_target_cpu_id
+ cmp r0, #ARM_PSCI_RET_INVAL
+ beq out_affinity_info
+ mov r1, r4
+
+ @ Get RCPM base address
+ movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff)
+ movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16)
+
+ mov r0, #PSCI_AFFINITY_LEVEL_ON
+
+ @ Detect target CPU state
+ ldr r2, [r4, #RCPM_TWAITSR]
+ rev r2, r2
+ lsr r2, r2, r1
+ ands r2, r2, #1
+ beq out_affinity_info
+
+ mov r0, #PSCI_AFFINITY_LEVEL_OFF
- bl psci_get_cpu_id
- bl psci_get_cpu_stack_top
- mov sp, r0
+out_affinity_info:
+ pop {pc}
+
+.globl psci_system_reset
+psci_system_reset:
+ @ Get DCFG base address
+ movw r1, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
+ movt r1, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
- bx r6
+ mov r2, #DCFG_CCSR_RSTCR_RESET_REQ
+ rev r2, r2
+ str r2, [r1, #DCFG_CCSR_RSTCR]
+
+1: wfi
+ b 1b
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c
index 9a330476cf..502552d171 100644
--- a/arch/arm/cpu/armv7/mx7/psci-mx7.c
+++ b/arch/arm/cpu/armv7/mx7/psci-mx7.c
@@ -1,9 +1,9 @@
#include <asm/io.h>
#include <asm/psci.h>
+#include <asm/secure.h>
#include <asm/arch/imx-regs.h>
#include <common.h>
-#define __secure __attribute__((section("._secure.text")))
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S
index 34c6ab33f0..96e88d6184 100644
--- a/arch/arm/cpu/armv7/mx7/psci.S
+++ b/arch/arm/cpu/armv7/mx7/psci.S
@@ -9,35 +9,22 @@
.arch_extension sec
- @ r1 = target CPU
- @ r2 = target PC
-
-.globl psci_arch_init
-psci_arch_init:
- mov r6, lr
-
- bl psci_get_cpu_id
- bl psci_get_cpu_stack_top
- mov sp, r0
-
- bx r6
-
- @ r1 = target CPU
- @ r2 = target PC
-
.globl psci_cpu_on
psci_cpu_on:
- push {lr}
+ push {r4, r5, lr}
+ mov r4, r0
+ mov r5, r1
mov r0, r1
- bl psci_get_cpu_stack_top
- str r2, [r0]
- dsb
+ mov r1, r2
+ bl psci_save_target_pc
+ mov r0, r4
+ mov r1, r5
ldr r2, =psci_cpu_entry
bl imx_cpu_on
- pop {pc}
+ pop {r4, r5, pc}
.globl psci_cpu_off
psci_cpu_off:
@@ -49,6 +36,4 @@ psci_cpu_off:
1: wfi
b 1b
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index b7563edbe6..95ce9387b8 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -49,8 +49,13 @@ _secure_monitor:
mcr p15, 0, r5, c12, c0, 1
isb
- @ Obtain a secure stack, and configure the PSCI backend
+ @ Obtain a secure stack
+ bl psci_stack_setup
+
+ @ Configure the PSCI backend
+ push {r0, r1, r2, ip}
bl psci_arch_init
+ pop {r0, r1, r2, ip}
#endif
#ifdef CONFIG_ARM_ERRATA_773022
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 87a7ac03f9..3172bae105 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -36,3 +36,5 @@ obj-y += boot-common.o
obj-y += lowlevel_init.o
obj-y += mem-common.o
+
+obj-$(CONFIG_TI_SECURE_DEVICE) += sec-common.o
diff --git a/arch/arm/cpu/armv7/omap-common/config_secure.mk b/arch/arm/cpu/armv7/omap-common/config_secure.mk
index c7bb101be8..1122439e38 100644
--- a/arch/arm/cpu/armv7/omap-common/config_secure.mk
+++ b/arch/arm/cpu/armv7/omap-common/config_secure.mk
@@ -12,8 +12,8 @@ cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
$(if $(KBUILD_VERBOSE:1=), >/dev/null)
else
cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
- $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
- $(if $(KBUILD_VERBOSE:1=), >/dev/null)
+ $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
+ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
endif
else
cmd_mkomapsecimg = echo "WARNING:" \
@@ -25,14 +25,33 @@ cmd_mkomapsecimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
"variable must be defined for TI secure devices. $@ was NOT created!"
endif
+ifdef CONFIG_SPL_LOAD_FIT
+quiet_cmd_omapsecureimg = SECURE $@
+ifneq ($(TI_SECURE_DEV_PKG),)
+ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh),)
+cmd_omapsecureimg = $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh \
+ $< $@ \
+ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
+else
+cmd_omapsecureimg = echo "WARNING:" \
+ "$(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh not found." \
+ "$@ was NOT created!"; cp $< $@
+endif
+else
+cmd_omapsecureimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
+ "variable must be defined for TI secure devices." \
+ "$@ was NOT created!"; cp $< $@
+endif
+endif
+
+
# Standard X-LOADER target (QPSI, NOR flash)
u-boot-spl_HS_X-LOADER: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For MLO targets (SD card boot) the final file name
-# that is copied to the SD card fAT partition must
-# be MLO, so we make a copy of the output file to a
-# new file with that name
+# For MLO targets (SD card boot) the final file name that is copied to the SD
+# card FAT partition must be MLO, so we make a copy of the output file to a new
+# file with that name
u-boot-spl_HS_MLO: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
@if [ -f $@ ]; then \
@@ -51,16 +70,44 @@ u-boot-spl_HS_ULO: $(obj)/u-boot-spl.bin
u-boot-spl_HS_ISSW: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For SPI flash on AM335x and AM43xx, these
-# require special byte swap handling so we use
-# the SPI_X-LOADER target instead of X-LOADER
-# and let the create-boot-image.sh script handle
-# that
+# For SPI flash on AM335x and AM43xx, these require special byte swap handling
+# so we use the SPI_X-LOADER target instead of X-LOADER and let the
+# create-boot-image.sh script handle that
u-boot-spl_HS_SPI_X-LOADER: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For supporting single stage XiP QSPI on AM43xx, the
-# image is a full u-boot file, not an SPL. In this case
-# the mkomapsecimg command looks for a u-boot-HS_* prefix
+# For supporting single stage XiP QSPI on AM43xx, the image is a full u-boot
+# file, not an SPL. In this case the mkomapsecimg command looks for a
+# u-boot-HS_* prefix
u-boot_HS_XIP_X-LOADER: $(obj)/u-boot.bin
$(call if_changed,mkomapsecimg)
+
+# For supporting the SPL loading and interpreting of FIT images whose
+# components are pre-processed before being integrated into the FIT image in
+# order to secure them in some way
+ifdef CONFIG_SPL_LOAD_FIT
+
+MKIMAGEFLAGS_u-boot_HS.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \
+ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
+ -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \
+ $(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+
+OF_LIST_TARGETS = $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+$(OF_LIST_TARGETS): dtbs
+
+%_HS.dtb: %.dtb
+ $(call if_changed,omapsecureimg)
+ $(Q)if [ -f $@ ]; then \
+ cp -f $@ $<; \
+ fi
+
+u-boot-nodtb_HS.bin: u-boot-nodtb.bin
+ $(call if_changed,omapsecureimg)
+
+u-boot_HS.img: u-boot-nodtb_HS.bin u-boot.img $(patsubst %.dtb,%_HS.dtb,$(OF_LIST_TARGETS))
+ $(call if_changed,mkimage)
+ $(Q)if [ -f $@ ]; then \
+ cp -f $@ u-boot.img; \
+ fi
+
+endif
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 9a9c764b4d..2b790105b0 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -37,7 +37,8 @@ void set_lpmode_selfrefresh(u32 base)
void force_emif_self_refresh()
{
set_lpmode_selfrefresh(EMIF1_BASE);
- set_lpmode_selfrefresh(EMIF2_BASE);
+ if (!is_dra72x())
+ set_lpmode_selfrefresh(EMIF2_BASE);
}
inline u32 emif_num(u32 base)
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 2f9693f28e..f317293988 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -147,8 +147,7 @@ void early_system_init(void)
hw_data_init();
#ifdef CONFIG_SPL_BUILD
- if (warm_reset() &&
- (is_omap44xx() || (omap_revision() == OMAP5430_ES1_0)))
+ if (warm_reset())
force_emif_self_refresh();
#endif
watchdog_init();
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index 528313584f..66a3b3d26c 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -16,9 +16,10 @@
#include <asm/arch/spl.h>
#include <linux/linkage.h>
+.arch_extension sec
+
#ifdef CONFIG_SPL
ENTRY(save_boot_params)
-
ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS
str r0, [r1]
b save_boot_params_ret
@@ -26,14 +27,40 @@ ENDPROC(save_boot_params)
#endif
ENTRY(omap_smc1)
- PUSH {r4-r12, lr} @ save registers - ROM code may pollute
+ push {r4-r12, lr} @ save registers - ROM code may pollute
@ our registers
- MOV r12, r0 @ Service
- MOV r0, r1 @ Argument
- DSB
- DMB
- .word 0xe1600070 @ SMC #0 - hand assembled for GCC versions
- @ call ROM Code API for the service requested
+ mov r12, r0 @ Service
+ mov r0, r1 @ Argument
- POP {r4-r12, pc}
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+ @ call ROM Code API for the service requested
+ pop {r4-r12, pc}
ENDPROC(omap_smc1)
+
+ENTRY(omap_smc_sec)
+ push {r4-r12, lr} @ save registers - ROM code may pollute
+ @ our registers
+ mov r6, #0xFF @ Indicate new Task call
+ mov r12, #0x00 @ Secure Service ID in R12
+
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+
+ b omap_smc_sec_end @ exit at end of the service execution
+ nop
+
+ @ In case of IRQ happening in Secure, then ARM will branch here.
+ @ At that moment, IRQ will be pending and ARM will jump to Non Secure
+ @ IRQ handler
+ mov r12, #0xFE
+
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+
+omap_smc_sec_end:
+ pop {r4-r12, pc}
+ENDPROC(omap_smc_sec)
diff --git a/arch/arm/cpu/armv7/omap-common/mem-common.c b/arch/arm/cpu/armv7/omap-common/mem-common.c
index fc4290c3c4..d72e82e028 100644
--- a/arch/arm/cpu/armv7/omap-common/mem-common.c
+++ b/arch/arm/cpu/armv7/omap-common/mem-common.c
@@ -20,8 +20,19 @@
#include <asm/arch/sys_proto.h>
#include <command.h>
#include <linux/mtd/omap_gpmc.h>
+#include <jffs2/load_kernel.h>
-struct gpmc *gpmc_cfg;
+const struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
+
+#if defined(CONFIG_NOR)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NOR;
+#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
+#elif defined(CONFIG_CMD_ONENAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
+#else
+char gpmc_cs0_flash = -1;
+#endif
#if defined(CONFIG_OMAP34XX)
/********************************************************
@@ -50,8 +61,8 @@ u32 mem_ok(u32 cs)
}
#endif
-void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
- u32 size)
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs,
+ u32 base, u32 size)
{
writel(0, &cs->config7);
sdelay(1000);
@@ -68,6 +79,81 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
sdelay(2000);
}
+void set_gpmc_cs0(int flash_type)
+{
+ const u32 *gpmc_regs;
+ u32 base, size;
+#if defined(CONFIG_NOR)
+ const u32 gpmc_regs_nor[GPMC_MAX_REG] = {
+ STNOR_GPMC_CONFIG1,
+ STNOR_GPMC_CONFIG2,
+ STNOR_GPMC_CONFIG3,
+ STNOR_GPMC_CONFIG4,
+ STNOR_GPMC_CONFIG5,
+ STNOR_GPMC_CONFIG6,
+ STNOR_GPMC_CONFIG7
+ };
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+ const u32 gpmc_regs_nand[GPMC_MAX_REG] = {
+ M_NAND_GPMC_CONFIG1,
+ M_NAND_GPMC_CONFIG2,
+ M_NAND_GPMC_CONFIG3,
+ M_NAND_GPMC_CONFIG4,
+ M_NAND_GPMC_CONFIG5,
+ M_NAND_GPMC_CONFIG6,
+ 0
+ };
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+ const u32 gpmc_regs_onenand[GPMC_MAX_REG] = {
+ ONENAND_GPMC_CONFIG1,
+ ONENAND_GPMC_CONFIG2,
+ ONENAND_GPMC_CONFIG3,
+ ONENAND_GPMC_CONFIG4,
+ ONENAND_GPMC_CONFIG5,
+ ONENAND_GPMC_CONFIG6,
+ 0
+ };
+#endif
+
+ switch (flash_type) {
+#if defined(CONFIG_NOR)
+ case MTD_DEV_TYPE_NOR:
+ gpmc_regs = gpmc_regs_nor;
+ base = CONFIG_SYS_FLASH_BASE;
+ size = (CONFIG_SYS_FLASH_SIZE > 0x08000000) ? GPMC_SIZE_256M :
+ ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M :
+ ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M :
+ ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M :
+ GPMC_SIZE_16M)));
+ break;
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+ case MTD_DEV_TYPE_NAND:
+ gpmc_regs = gpmc_regs_nand;
+ base = CONFIG_SYS_NAND_BASE;
+ size = GPMC_SIZE_16M;
+ break;
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+ case MTD_DEV_TYPE_ONENAND:
+ gpmc_regs = gpmc_regs_onenand;
+ base = CONFIG_SYS_ONENAND_BASE;
+ size = GPMC_SIZE_128M;
+ break;
+#endif
+ default:
+ /* disable the GPMC0 config set by ROM code */
+ writel(0, &gpmc_cfg->cs[0].config7);
+ sdelay(1000);
+ return;
+ }
+
+ /* enable chip-select specific configurations */
+ enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
+}
+
/*****************************************************
* gpmc_init(): init gpmc bus
* Init GPMC for x16, MuxMode (SDRAM in x32).
@@ -75,70 +161,14 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
*****************************************************/
void gpmc_init(void)
{
- /* putting a blanket check on GPMC based on ZeBu for now */
- gpmc_cfg = (struct gpmc *)GPMC_BASE;
-#if defined(CONFIG_NOR)
-/* configure GPMC for NOR */
- const u32 gpmc_regs[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
- STNOR_GPMC_CONFIG2,
- STNOR_GPMC_CONFIG3,
- STNOR_GPMC_CONFIG4,
- STNOR_GPMC_CONFIG5,
- STNOR_GPMC_CONFIG6,
- STNOR_GPMC_CONFIG7
- };
- u32 base = CONFIG_SYS_FLASH_BASE;
- u32 size = (CONFIG_SYS_FLASH_SIZE > 0x08000000) ? GPMC_SIZE_256M :
- /* > 64MB */ ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M :
- /* > 32MB */ ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M :
- /* > 16MB */ ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M :
- /* min 16MB */ GPMC_SIZE_16M)));
-#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
-/* configure GPMC for NAND */
- const u32 gpmc_regs[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1,
- M_NAND_GPMC_CONFIG2,
- M_NAND_GPMC_CONFIG3,
- M_NAND_GPMC_CONFIG4,
- M_NAND_GPMC_CONFIG5,
- M_NAND_GPMC_CONFIG6,
- 0
- };
- u32 base = CONFIG_SYS_NAND_BASE;
- u32 size = GPMC_SIZE_16M;
-
-#elif defined(CONFIG_CMD_ONENAND)
- const u32 gpmc_regs[GPMC_MAX_REG] = { ONENAND_GPMC_CONFIG1,
- ONENAND_GPMC_CONFIG2,
- ONENAND_GPMC_CONFIG3,
- ONENAND_GPMC_CONFIG4,
- ONENAND_GPMC_CONFIG5,
- ONENAND_GPMC_CONFIG6,
- 0
- };
- u32 size = GPMC_SIZE_128M;
- u32 base = CONFIG_SYS_ONENAND_BASE;
-#else
- const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };
- u32 size = 0;
- u32 base = 0;
-#endif
/* global settings */
writel(0x00000008, &gpmc_cfg->sysconfig);
writel(0x00000000, &gpmc_cfg->irqstatus);
writel(0x00000000, &gpmc_cfg->irqenable);
/* disable timeout, set a safe reset value */
writel(0x00001ff0, &gpmc_cfg->timeout_control);
-#ifdef CONFIG_NOR
- writel(0x00000200, &gpmc_cfg->config);
-#else
- writel(0x00000012, &gpmc_cfg->config);
-#endif
- /*
- * Disable the GPMC0 config set by ROM code
- */
- writel(0, &gpmc_cfg->cs[0].config7);
- sdelay(1000);
- /* enable chip-select specific configurations */
- if (base != 0)
- enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
+ writel(gpmc_cs0_flash == MTD_DEV_TYPE_NOR ?
+ 0x00000200 : 0x00000012, &gpmc_cfg->config);
+
+ set_gpmc_cs0(gpmc_cs0_flash);
}
diff --git a/arch/arm/cpu/armv7/omap-common/sec-common.c b/arch/arm/cpu/armv7/omap-common/sec-common.c
new file mode 100644
index 0000000000..246a2393da
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap-common/sec-common.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * Common security related functions for OMAP devices
+ *
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Daniel Allred <d-allred@ti.com>
+ * Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <stdarg.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+/* Index for signature verify ROM API */
+#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX (0x0000000E)
+
+static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN);
+
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
+{
+ int i;
+ u32 num_args;
+ va_list ap;
+
+ va_start(ap, flag);
+
+ num_args = va_arg(ap, u32);
+
+ if (num_args > 4)
+ return 1;
+
+ /* Copy args to aligned args structure */
+ for (i = 0; i < num_args; i++)
+ secure_rom_call_args[i + 1] = va_arg(ap, u32);
+
+ secure_rom_call_args[0] = num_args;
+
+ va_end(ap);
+
+ /* if data cache is enabled, flush the aligned args structure */
+ flush_dcache_range(
+ (unsigned int)&secure_rom_call_args[0],
+ (unsigned int)&secure_rom_call_args[0] +
+ roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN));
+
+ return omap_smc_sec(service, proc_id, flag, secure_rom_call_args);
+}
+
+static u32 find_sig_start(char *image, size_t size)
+{
+ char *image_end = image + size;
+ char *sig_start_magic = "CERT_";
+ int magic_str_len = strlen(sig_start_magic);
+ char *ch;
+
+ while (--image_end > image) {
+ if (*image_end == '_') {
+ ch = image_end - magic_str_len + 1;
+ if (!strncmp(ch, sig_start_magic, magic_str_len))
+ return (u32)ch;
+ }
+ }
+ return 0;
+}
+
+int secure_boot_verify_image(void **image, size_t *size)
+{
+ int result = 1;
+ u32 cert_addr, sig_addr;
+ size_t cert_size;
+
+ /* Perform cache writeback on input buffer */
+ flush_dcache_range(
+ (u32)*image,
+ (u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
+
+ cert_addr = (uint32_t)*image;
+ sig_addr = find_sig_start((char *)*image, *size);
+
+ if (sig_addr == 0) {
+ printf("No signature found in image!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ *size = sig_addr - cert_addr; /* Subtract out the signature size */
+ cert_size = *size;
+
+ /* Check if image load address is 32-bit aligned */
+ if (!IS_ALIGNED(cert_addr, 4)) {
+ printf("Image is not 4-byte aligned!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ /* Image size also should be multiple of 4 */
+ if (!IS_ALIGNED(cert_size, 4)) {
+ printf("Image size is not 4-byte aligned!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ /* Call ROM HAL API to verify certificate signature */
+ debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__,
+ cert_addr, cert_size, sig_addr);
+
+ result = secure_rom_call(
+ API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0,
+ 4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF);
+auth_exit:
+ if (result != 0) {
+ printf("Authentication failed!\n");
+ printf("Return Value = %08X\n", result);
+ hang();
+ }
+
+ /*
+ * Output notification of successful authentication as well the name of
+ * the signing certificate used to re-assure the user that the secure
+ * code is being processed as expected. However suppress any such log
+ * output in case of building for SPL and booting via YMODEM. This is
+ * done to avoid disturbing the YMODEM serial protocol transactions.
+ */
+ if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
+ IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
+ spl_boot_device() == BOOT_DEVICE_UART))
+ printf("Authentication passed: %s\n", (char *)sig_addr);
+
+ return result;
+}
diff --git a/arch/arm/cpu/armv7/omap3/spl_id_nand.c b/arch/arm/cpu/armv7/omap3/spl_id_nand.c
index db6de0911b..0e2f0a2f6d 100644
--- a/arch/arm/cpu/armv7/omap3/spl_id_nand.c
+++ b/arch/arm/cpu/armv7/omap3/spl_id_nand.c
@@ -13,62 +13,45 @@
*/
#include <common.h>
+#include <jffs2/load_kernel.h>
#include <linux/mtd/nand.h>
+#include <linux/mtd/omap_gpmc.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mem.h>
-static struct gpmc *gpmc_config = (struct gpmc *)GPMC_BASE;
-
-/* nand_command: Send a flash command to the flash chip */
-static void nand_command(u8 command)
-{
- writeb(command, &gpmc_config->cs[0].nand_cmd);
-
- if (command == NAND_CMD_RESET) {
- unsigned char ret_val;
- writeb(NAND_CMD_STATUS, &gpmc_config->cs[0].nand_cmd);
- do {
- /* Wait until ready */
- ret_val = readl(&gpmc_config->cs[0].nand_dat);
- } while ((ret_val & NAND_STATUS_READY) != NAND_STATUS_READY);
- }
-}
-
/*
* Many boards will want to know the results of the NAND_CMD_READID command
* in order to decide what to do about DDR initialization. This function
* allows us to do that very early and to pass those results back to the
* board so it can make whatever decisions need to be made.
*/
-void identify_nand_chip(int *mfr, int *id)
+int identify_nand_chip(int *mfr, int *id)
{
- /* Make sure that we have setup GPMC for NAND correctly. */
- writel(M_NAND_GPMC_CONFIG1, &gpmc_config->cs[0].config1);
- writel(M_NAND_GPMC_CONFIG2, &gpmc_config->cs[0].config2);
- writel(M_NAND_GPMC_CONFIG3, &gpmc_config->cs[0].config3);
- writel(M_NAND_GPMC_CONFIG4, &gpmc_config->cs[0].config4);
- writel(M_NAND_GPMC_CONFIG5, &gpmc_config->cs[0].config5);
- writel(M_NAND_GPMC_CONFIG6, &gpmc_config->cs[0].config6);
+ int loops = 1000;
- /*
- * Enable the config. The CS size goes in bits 11:8. We set
- * bit 6 to enable the CS and the base address goes into bits 5:0.
- */
- writel((GPMC_SIZE_128M << 8) | (GPMC_CS_ENABLE << 6) |
- ((NAND_BASE >> 24) & GPMC_BASEADDR_MASK),
- &gpmc_config->cs[0].config7);
+ /* Make sure that we have setup GPMC for NAND correctly. */
+ set_gpmc_cs0(MTD_DEV_TYPE_NAND);
sdelay(2000);
/* Issue a RESET and then READID */
- nand_command(NAND_CMD_RESET);
- nand_command(NAND_CMD_READID);
+ writeb(NAND_CMD_RESET, &gpmc_cfg->cs[0].nand_cmd);
+ writeb(NAND_CMD_STATUS, &gpmc_cfg->cs[0].nand_cmd);
+ while ((readl(&gpmc_cfg->cs[0].nand_dat) & NAND_STATUS_READY)
+ != NAND_STATUS_READY) {
+ sdelay(100);
+ if (--loops == 0)
+ return 1;
+ }
+ writeb(NAND_CMD_READID, &gpmc_cfg->cs[0].nand_cmd);
/* Set the address to read to 0x0 */
- writeb(0x0, &gpmc_config->cs[0].nand_adr);
+ writeb(0x0, &gpmc_cfg->cs[0].nand_adr);
/* Read off the manufacturer and device id. */
- *mfr = readb(&gpmc_config->cs[0].nand_dat);
- *id = readb(&gpmc_config->cs[0].nand_dat);
+ *mfr = readb(&gpmc_cfg->cs[0].nand_dat);
+ *id = readb(&gpmc_cfg->cs[0].nand_dat);
+
+ return 0;
}
diff --git a/arch/arm/cpu/armv7/omap5/config.mk b/arch/arm/cpu/armv7/omap5/config.mk
index a7e55a5e24..286ca8688d 100644
--- a/arch/arm/cpu/armv7/omap5/config.mk
+++ b/arch/arm/cpu/armv7/omap5/config.mk
@@ -15,5 +15,8 @@ else
ALL-y += MLO
endif
else
+ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
+ALL-$(CONFIG_SPL_LOAD_FIT) += u-boot_HS.img
+endif
ALL-y += u-boot.img
endif
diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c
new file mode 100644
index 0000000000..d14b693747
--- /dev/null
+++ b/arch/arm/cpu/armv7/psci-common.c
@@ -0,0 +1,39 @@
+/*
+ * Common PSCI functions
+ *
+ * Copyright (C) 2016 Chen-Yu Tsai
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <asm/armv7.h>
+#include <asm/macro.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <linux/linkage.h>
+
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+
+void __secure psci_save_target_pc(int cpu, u32 pc)
+{
+ psci_target_pc[cpu] = pc;
+ DSB;
+}
+
+u32 __secure psci_get_target_pc(int cpu)
+{
+ return psci_target_pc[cpu];
+}
+
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S
index ab408378fc..f80f6e20d1 100644
--- a/arch/arm/cpu/armv7/psci.S
+++ b/arch/arm/cpu/armv7/psci.S
@@ -46,20 +46,62 @@ ENTRY(default_psci_vector)
ENDPROC(default_psci_vector)
.weak default_psci_vector
+ENTRY(psci_version)
ENTRY(psci_cpu_suspend)
ENTRY(psci_cpu_off)
ENTRY(psci_cpu_on)
+ENTRY(psci_affinity_info)
ENTRY(psci_migrate)
+ENTRY(psci_migrate_info_type)
+ENTRY(psci_migrate_info_up_cpu)
+ENTRY(psci_system_off)
+ENTRY(psci_system_reset)
+ENTRY(psci_features)
+ENTRY(psci_cpu_freeze)
+ENTRY(psci_cpu_default_suspend)
+ENTRY(psci_node_hw_state)
+ENTRY(psci_system_suspend)
+ENTRY(psci_set_suspend_mode)
+ENTRY(psi_stat_residency)
+ENTRY(psci_stat_count)
mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented)
mov pc, lr
+ENDPROC(psci_stat_count)
+ENDPROC(psi_stat_residency)
+ENDPROC(psci_set_suspend_mode)
+ENDPROC(psci_system_suspend)
+ENDPROC(psci_node_hw_state)
+ENDPROC(psci_cpu_default_suspend)
+ENDPROC(psci_cpu_freeze)
+ENDPROC(psci_features)
+ENDPROC(psci_system_reset)
+ENDPROC(psci_system_off)
+ENDPROC(psci_migrate_info_up_cpu)
+ENDPROC(psci_migrate_info_type)
ENDPROC(psci_migrate)
+ENDPROC(psci_affinity_info)
ENDPROC(psci_cpu_on)
ENDPROC(psci_cpu_off)
ENDPROC(psci_cpu_suspend)
+ENDPROC(psci_version)
+.weak psci_version
.weak psci_cpu_suspend
.weak psci_cpu_off
.weak psci_cpu_on
+.weak psci_affinity_info
.weak psci_migrate
+.weak psci_migrate_info_type
+.weak psci_migrate_info_up_cpu
+.weak psci_system_off
+.weak psci_system_reset
+.weak psci_features
+.weak psci_cpu_freeze
+.weak psci_cpu_default_suspend
+.weak psci_node_hw_state
+.weak psci_system_suspend
+.weak psci_set_suspend_mode
+.weak psi_stat_residency
+.weak psci_stat_count
_psci_table:
.word ARM_PSCI_FN_CPU_SUSPEND
@@ -70,6 +112,42 @@ _psci_table:
.word psci_cpu_on
.word ARM_PSCI_FN_MIGRATE
.word psci_migrate
+ .word ARM_PSCI_0_2_FN_PSCI_VERSION
+ .word psci_version
+ .word ARM_PSCI_0_2_FN_CPU_SUSPEND
+ .word psci_cpu_suspend
+ .word ARM_PSCI_0_2_FN_CPU_OFF
+ .word psci_cpu_off
+ .word ARM_PSCI_0_2_FN_CPU_ON
+ .word psci_cpu_on
+ .word ARM_PSCI_0_2_FN_AFFINITY_INFO
+ .word psci_affinity_info
+ .word ARM_PSCI_0_2_FN_MIGRATE
+ .word psci_migrate
+ .word ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE
+ .word psci_migrate_info_type
+ .word ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU
+ .word psci_migrate_info_up_cpu
+ .word ARM_PSCI_0_2_FN_SYSTEM_OFF
+ .word psci_system_off
+ .word ARM_PSCI_0_2_FN_SYSTEM_RESET
+ .word psci_system_reset
+ .word ARM_PSCI_1_0_FN_PSCI_FEATURES
+ .word psci_features
+ .word ARM_PSCI_1_0_FN_CPU_FREEZE
+ .word psci_cpu_freeze
+ .word ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND
+ .word psci_cpu_default_suspend
+ .word ARM_PSCI_1_0_FN_NODE_HW_STATE
+ .word psci_node_hw_state
+ .word ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
+ .word psci_system_suspend
+ .word ARM_PSCI_1_0_FN_SET_SUSPEND_MODE
+ .word psci_set_suspend_mode
+ .word ARM_PSCI_1_0_FN_STAT_RESIDENCY
+ .word psi_stat_residency
+ .word ARM_PSCI_1_0_FN_STAT_COUNT
+ .word psci_stat_count
.word 0
.word 0
@@ -196,29 +274,56 @@ ENTRY(psci_cpu_off_common)
bx lr
ENDPROC(psci_cpu_off_common)
-@ expects CPU ID in r0 and returns stack top in r0
-ENTRY(psci_get_cpu_stack_top)
- mov r3, #0x400 @ 1kB of stack per CPU
- mul r0, r0, r3
-
- ldr r3, =psci_text_end @ end of monitor text
- add r3, r3, #0x2000 @ Skip two pages
- lsr r3, r3, #12 @ Align to start of page
- lsl r3, r3, #12
- sub r3, r3, #4 @ reserve 1 word for target PC
- sub r0, r3, r0 @ here's our stack!
-
+@ The stacks are allocated in reverse order, i.e.
+@ the stack for CPU0 has the highest memory address.
+@
+@ -------------------- __secure_stack_end
+@ | CPU0 target PC |
+@ |------------------|
+@ | |
+@ | CPU0 stack |
+@ | |
+@ |------------------| __secure_stack_end - 1KB
+@ | . |
+@ | . |
+@ | . |
+@ | . |
+@ -------------------- __secure_stack_start
+@
+@ This expects CPU ID in r0 and returns stack top in r0
+LENTRY(psci_get_cpu_stack_top)
+ @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
+ ldr r3, =__secure_stack_end
+ sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT
+ sub r0, r0, #4 @ Save space for target PC
bx lr
ENDPROC(psci_get_cpu_stack_top)
+@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
+@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
+@ this function.
+ENTRY(psci_stack_setup)
+ mov r6, lr
+ mov r7, r0
+ bl psci_get_cpu_id @ CPU ID => r0
+ bl psci_get_cpu_stack_top @ stack top => r0
+ mov sp, r0
+ mov r0, r7
+ bx r6
+ENDPROC(psci_stack_setup)
+
+ENTRY(psci_arch_init)
+ mov pc, lr
+ENDPROC(psci_arch_init)
+.weak psci_arch_init
+
ENTRY(psci_cpu_entry)
bl psci_enable_smp
bl _nonsec_init
bl psci_get_cpu_id @ CPU ID => r0
- bl psci_get_cpu_stack_top @ stack top => r0
- ldr r0, [r0] @ target PC at stack top
+ bl psci_get_target_pc @ target PC => r0
b _do_nonsec_entry
ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index c208510168..b35b9df4a9 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ARMV7_PSCI) += psci.o
-obj-$(CONFIG_ARMV7_PSCI) += psci_head.o
endif
ifdef CONFIG_SPL_BUILD
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index a118e9d0c4..7ac84065f4 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -17,11 +17,11 @@
#include <asm/gic.h>
#include <asm/io.h>
#include <asm/psci.h>
+#include <asm/secure.h>
#include <asm/system.h>
#include <linux/bitops.h>
-#define __secure __attribute__ ((section ("._secure.text")))
#define __irq __attribute__ ((interrupt ("IRQ")))
#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
@@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc)
(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
u32 cpu = (mpidr & 0x3);
- /* store target PC at target CPU stack top */
- writel(pc, psci_get_cpu_stack_top(cpu));
- DSB;
+ /* store target PC */
+ psci_save_target_pc(cpu, pc);
/* Set secondary core power on PC */
writel((u32)&psci_cpu_entry, &cpucfg->priv0);
@@ -250,7 +249,7 @@ void __secure psci_cpu_off(void)
wfi();
}
-void __secure sunxi_gic_init(void)
+void __secure psci_arch_init(void)
{
u32 reg;
diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S
deleted file mode 100644
index 8fa823d1df..0000000000
--- a/arch/arm/cpu/armv7/sunxi/psci_head.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2013 - ARM Ltd
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * Based on code by Carl van Schaik <carl@ok-labs.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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <linux/linkage.h>
-
-#include <asm/arch-armv7/generictimer.h>
-#include <asm/gic.h>
-#include <asm/macro.h>
-#include <asm/psci.h>
-#include <asm/arch/cpu.h>
-
-/*
- * Memory layout:
- *
- * SECURE_RAM to text_end :
- * ._secure_text section
- * text_end to ALIGN_PAGE(text_end):
- * nothing
- * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000)
- * 1kB of stack per CPU (4 CPUs max).
- */
-
- .pushsection ._secure.text, "ax"
-
- .arch_extension sec
-
-#define GICD_BASE (SUNXI_GIC400_BASE + 0x1000)
-#define GICC_BASE (SUNXI_GIC400_BASE + 0x2000)
-
-@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
-@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
-@ this function.
-ENTRY(psci_arch_init)
- mov r6, lr
- mov r7, r0
- bl psci_get_cpu_id @ CPU ID => r0
- bl psci_get_cpu_stack_top @ stack top => r0
- sub r0, r0, #4 @ Save space for target PC
- mov sp, r0
- mov r0, r7
- mov lr, r6
-
- push {r0, r1, r2, ip, lr}
- bl sunxi_gic_init
- pop {r0, r1, r2, ip, pc}
-ENDPROC(psci_arch_init)
-
-ENTRY(psci_text_end)
- .popsection
diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c
index 32c368f145..707dad4829 100644
--- a/arch/arm/cpu/armv7/virt-dt.c
+++ b/arch/arm/cpu/armv7/virt-dt.c
@@ -26,69 +26,6 @@
#include <asm/armv7.h>
#include <asm/psci.h>
-static int fdt_psci(void *fdt)
-{
-#ifdef CONFIG_ARMV7_PSCI
- int nodeoff;
- int tmp;
-
- nodeoff = fdt_path_offset(fdt, "/cpus");
- if (nodeoff < 0) {
- printf("couldn't find /cpus\n");
- return nodeoff;
- }
-
- /* add 'enable-method = "psci"' to each cpu node */
- for (tmp = fdt_first_subnode(fdt, nodeoff);
- tmp >= 0;
- tmp = fdt_next_subnode(fdt, tmp)) {
- const struct fdt_property *prop;
- int len;
-
- prop = fdt_get_property(fdt, tmp, "device_type", &len);
- if (!prop)
- continue;
- if (len < 4)
- continue;
- if (strcmp(prop->data, "cpu"))
- continue;
-
- fdt_setprop_string(fdt, tmp, "enable-method", "psci");
- }
-
- nodeoff = fdt_path_offset(fdt, "/psci");
- if (nodeoff < 0) {
- nodeoff = fdt_path_offset(fdt, "/");
- if (nodeoff < 0)
- return nodeoff;
-
- nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
- if (nodeoff < 0)
- return nodeoff;
- }
-
- tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci");
- if (tmp)
- return tmp;
- tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE);
- if (tmp)
- return tmp;
-#endif
- return 0;
-}
-
int armv7_apply_memory_carveout(u64 *start, u64 *size)
{
#ifdef CONFIG_ARMV7_SECURE_RESERVE_SIZE
diff --git a/arch/arm/cpu/armv7m/config.mk b/arch/arm/cpu/armv7m/config.mk
index 4a53006b6a..db4660e15d 100644
--- a/arch/arm/cpu/armv7m/config.mk
+++ b/arch/arm/cpu/armv7m/config.mk
@@ -5,4 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_CPPFLAGS += -march=armv7-m -mthumb
+PLATFORM_CPPFLAGS += -march=armv7-m -mthumb -mno-unaligned-access
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index 3d19bbfbe2..acf2460ede 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -3,4 +3,22 @@ if ARM64
config ARMV8_MULTIENTRY
boolean "Enable multiple CPUs to enter into U-Boot"
+config ARMV8_SPIN_TABLE
+ bool "Support spin-table enable method"
+ depends on ARMV8_MULTIENTRY && OF_LIBFDT
+ help
+ Say Y here to support "spin-table" enable method for booting Linux.
+
+ To use this feature, you must do:
+ - Specify enable-method = "spin-table" in each CPU node in the
+ Device Tree you are using to boot the kernel
+ - Let secondary CPUs in U-Boot (in a board specific manner)
+ before the master CPU jumps to the kernel
+
+ U-Boot automatically does:
+ - Set "cpu-release-addr" property of each CPU node
+ (overwrites it if already exists).
+ - Reserve the code for the spin-table and the release address
+ via a /memreserve/ region in the Device Tree.
+
endif
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index bf8644ccd2..dea14657d9 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -15,6 +15,11 @@ obj-y += cache.o
obj-y += tlb.o
obj-y += transition.o
obj-y += fwcall.o
+obj-y += cpu-dt.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
+endif
+obj-$(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o
obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/
obj-$(CONFIG_S32V234) += s32v234/
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 1615542a99..ac909a15ff 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -35,7 +35,7 @@ DECLARE_GLOBAL_DATA_PTR;
* off: FFF
*/
-static u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
+u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
{
u64 max_addr = 0;
u64 ips, va_bits;
@@ -44,7 +44,7 @@ static u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
/* Find the largest address we need to support */
for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
- max_addr = max(max_addr, mem_map[i].base + mem_map[i].size);
+ max_addr = max(max_addr, mem_map[i].virt + mem_map[i].size);
/* Calculate the maximum physical (and thus virtual) address */
if (max_addr > (1ULL << 44)) {
@@ -167,49 +167,6 @@ static void set_pte_table(u64 *pte, u64 *table)
*pte = PTE_TYPE_TABLE | (ulong)table;
}
-/* Add one mm_region map entry to the page tables */
-static void add_map(struct mm_region *map)
-{
- u64 *pte;
- u64 addr = map->base;
- u64 size = map->size;
- u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
- u64 blocksize;
- int level;
- u64 *new_table;
-
- while (size) {
- pte = find_pte(addr, 0);
- if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) {
- debug("Creating table for addr 0x%llx\n", addr);
- new_table = create_table();
- set_pte_table(pte, new_table);
- }
-
- for (level = 1; level < 4; level++) {
- pte = find_pte(addr, level);
- blocksize = 1ULL << level2shift(level);
- debug("Checking if pte fits for addr=%llx size=%llx "
- "blocksize=%llx\n", addr, size, blocksize);
- if (size >= blocksize && !(addr & (blocksize - 1))) {
- /* Page fits, create block PTE */
- debug("Setting PTE %p to block addr=%llx\n",
- pte, addr);
- *pte = addr | attrs;
- addr += blocksize;
- size -= blocksize;
- break;
- } else if ((pte_type(pte) == PTE_TYPE_FAULT)) {
- /* Page doesn't fit, create subpages */
- debug("Creating subtable for addr 0x%llx "
- "blksize=%llx\n", addr, blocksize);
- new_table = create_table();
- set_pte_table(pte, new_table);
- }
- }
- }
-}
-
/* Splits a block PTE into table with subpages spanning the old block */
static void split_block(u64 *pte, int level)
{
@@ -241,6 +198,58 @@ static void split_block(u64 *pte, int level)
set_pte_table(pte, new_table);
}
+/* Add one mm_region map entry to the page tables */
+static void add_map(struct mm_region *map)
+{
+ u64 *pte;
+ u64 virt = map->virt;
+ u64 phys = map->phys;
+ u64 size = map->size;
+ u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
+ u64 blocksize;
+ int level;
+ u64 *new_table;
+
+ while (size) {
+ pte = find_pte(virt, 0);
+ if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) {
+ debug("Creating table for virt 0x%llx\n", virt);
+ new_table = create_table();
+ set_pte_table(pte, new_table);
+ }
+
+ for (level = 1; level < 4; level++) {
+ pte = find_pte(virt, level);
+ if (!pte)
+ panic("pte not found\n");
+
+ blocksize = 1ULL << level2shift(level);
+ debug("Checking if pte fits for virt=%llx size=%llx blocksize=%llx\n",
+ virt, size, blocksize);
+ if (size >= blocksize && !(virt & (blocksize - 1))) {
+ /* Page fits, create block PTE */
+ debug("Setting PTE %p to block virt=%llx\n",
+ pte, virt);
+ *pte = phys | attrs;
+ virt += blocksize;
+ phys += blocksize;
+ size -= blocksize;
+ break;
+ } else if (pte_type(pte) == PTE_TYPE_FAULT) {
+ /* Page doesn't fit, create subpages */
+ debug("Creating subtable for virt 0x%llx blksize=%llx\n",
+ virt, blocksize);
+ new_table = create_table();
+ set_pte_table(pte, new_table);
+ } else if (pte_type(pte) == PTE_TYPE_BLOCK) {
+ debug("Split block into subtable for virt 0x%llx blksize=0x%llx\n",
+ virt, blocksize);
+ split_block(pte, level);
+ }
+ }
+ }
+}
+
enum pte_type {
PTE_INVAL,
PTE_BLOCK,
@@ -265,7 +274,7 @@ static int count_required_pts(u64 addr, int level, u64 maxaddr)
for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) {
struct mm_region *map = &mem_map[i];
- u64 start = map->base;
+ u64 start = map->virt;
u64 end = start + map->size;
/* Check if the PTE would overlap with the map */
@@ -349,10 +358,13 @@ __weak u64 get_page_table_size(void)
return size;
}
-static void setup_pgtables(void)
+void setup_pgtables(void)
{
int i;
+ if (!gd->arch.tlb_fillptr || !gd->arch.tlb_addr)
+ panic("Page table pointer not setup.");
+
/*
* Allocate the first level we're on with invalidate entries.
* If the starting level is 0 (va_bits >= 39), then this is our
@@ -363,9 +375,6 @@ static void setup_pgtables(void)
/* Now add all MMU table entries one after another to the table */
for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
add_map(&mem_map[i]);
-
- /* Create the same thing once more for our emergency page table */
- create_table();
}
static void setup_all_pgtables(void)
@@ -527,6 +536,9 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
debug("start=%lx size=%lx\n", (ulong)start, (ulong)size);
+ if (!gd->arch.tlb_emerg)
+ panic("Emergency page table not setup.");
+
/*
* We can not modify page tables that we're currently running on,
* so we first need to switch to the "emergency" page tables where
diff --git a/arch/arm/cpu/armv8/cpu-dt.c b/arch/arm/cpu/armv8/cpu-dt.c
new file mode 100644
index 0000000000..9ffb49c37c
--- /dev/null
+++ b/arch/arm/cpu/armv8/cpu-dt.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/psci.h>
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
+
+int psci_update_dt(void *fdt)
+{
+#ifdef CONFIG_MP
+#if defined(CONFIG_ARMV8_PSCI)
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+ /*
+ * If the PSCI in SEC Firmware didn't work, avoid to update the
+ * device node of PSCI. But still return 0 instead of an error
+ * number to support detecting PSCI dynamically and then switching
+ * the SMP boot method between PSCI and spin-table.
+ */
+ if (sec_firmware_support_psci_version() == 0xffffffff)
+ return 0;
+#endif
+ fdt_psci(fdt);
+#endif
+#endif
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile
index eb2cbc3f7e..8c1317faea 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile
@@ -10,6 +10,7 @@ obj-y += soc.o
obj-$(CONFIG_MP) += mp.o
obj-$(CONFIG_OF_LIBFDT) += fdt.o
obj-$(CONFIG_SPL) += spl.o
+obj-$(CONFIG_FSL_LS_PPA) += ppa.o
ifneq ($(CONFIG_FSL_LSCH3),)
obj-y += fsl_lsch3_speed.o
@@ -32,3 +33,7 @@ endif
ifneq ($(CONFIG_LS1012A),)
obj-$(CONFIG_SYS_HAS_SERDES) += ls1012a_serdes.o
endif
+
+ifneq ($(CONFIG_LS1046A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1046a_serdes.o
+endif
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 8062106e3e..e12b773550 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -23,16 +23,13 @@
#ifdef CONFIG_FSL_ESDHC
#include <fsl_esdhc.h>
#endif
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
DECLARE_GLOBAL_DATA_PTR;
-static struct mm_region layerscape_mem_map[] = {
- {
- /* List terminator */
- 0,
- }
-};
-struct mm_region *mem_map = layerscape_mem_map;
+struct mm_region *mem_map = early_map;
void cpu_name(char *name)
{
@@ -56,355 +53,106 @@ void cpu_name(char *name)
}
#ifndef CONFIG_SYS_DCACHE_OFF
-static void set_pgtable_section(u64 *page_table, u64 index, u64 section,
- u64 memory_type, u64 attribute)
-{
- u64 value;
-
- value = section | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
- value |= PMD_ATTRINDX(memory_type);
- value |= attribute;
- page_table[index] = value;
-}
-
-static void set_pgtable_table(u64 *page_table, u64 index, u64 *table_addr)
-{
- u64 value;
-
- value = (u64)table_addr | PTE_TYPE_TABLE;
- page_table[index] = value;
-}
-
-/*
- * Set the block entries according to the information of the table.
- */
-static int set_block_entry(const struct sys_mmu_table *list,
- struct table_info *table)
-{
- u64 block_size = 0, block_shift = 0;
- u64 block_addr, index;
- int j;
-
- if (table->entry_size == BLOCK_SIZE_L1) {
- block_size = BLOCK_SIZE_L1;
- block_shift = SECTION_SHIFT_L1;
- } else if (table->entry_size == BLOCK_SIZE_L2) {
- block_size = BLOCK_SIZE_L2;
- block_shift = SECTION_SHIFT_L2;
- } else {
- return -EINVAL;
- }
-
- block_addr = list->phys_addr;
- index = (list->virt_addr - table->table_base) >> block_shift;
-
- for (j = 0; j < (list->size >> block_shift); j++) {
- set_pgtable_section(table->ptr,
- index,
- block_addr,
- list->memory_type,
- list->attribute);
- block_addr += block_size;
- index++;
- }
-
- return 0;
-}
-
-/*
- * Find the corresponding table entry for the list.
- */
-static int find_table(const struct sys_mmu_table *list,
- struct table_info *table, u64 *level0_table)
-{
- u64 index = 0, level = 0;
- u64 *level_table = level0_table;
- u64 temp_base = 0, block_size = 0, block_shift = 0;
-
- while (level < 3) {
- if (level == 0) {
- block_size = BLOCK_SIZE_L0;
- block_shift = SECTION_SHIFT_L0;
- } else if (level == 1) {
- block_size = BLOCK_SIZE_L1;
- block_shift = SECTION_SHIFT_L1;
- } else if (level == 2) {
- block_size = BLOCK_SIZE_L2;
- block_shift = SECTION_SHIFT_L2;
- }
-
- index = 0;
- while (list->virt_addr >= temp_base) {
- index++;
- temp_base += block_size;
- }
-
- temp_base -= block_size;
-
- if ((level_table[index - 1] & PTE_TYPE_MASK) ==
- PTE_TYPE_TABLE) {
- level_table = (u64 *)(level_table[index - 1] &
- ~PTE_TYPE_MASK);
- level++;
- continue;
- } else {
- if (level == 0)
- return -EINVAL;
-
- if ((list->phys_addr + list->size) >
- (temp_base + block_size * NUM_OF_ENTRY))
- return -EINVAL;
-
- /*
- * Check the address and size of the list member is
- * aligned with the block size.
- */
- if (((list->phys_addr & (block_size - 1)) != 0) ||
- ((list->size & (block_size - 1)) != 0))
- return -EINVAL;
-
- table->ptr = level_table;
- table->table_base = temp_base -
- ((index - 1) << block_shift);
- table->entry_size = block_size;
-
- return 0;
- }
- }
- return -EINVAL;
-}
-
/*
* To start MMU before DDR is available, we create MMU table in SRAM.
* The base address of SRAM is CONFIG_SYS_FSL_OCRAM_BASE. We use three
* levels of translation tables here to cover 40-bit address space.
* We use 4KB granule size, with 40 bits physical address, T0SZ=24
- * Level 0 IA[39], table address @0
- * Level 1 IA[38:30], table address @0x1000, 0x2000
- * Level 2 IA[29:21], table address @0x3000, 0x4000
- * Address above 0x5000 is free for other purpose.
+ * Address above EARLY_PGTABLE_SIZE (0x5000) is free for other purpose.
+ * Note, the debug print in cache_v8.c is not usable for debugging
+ * these early MMU tables because UART is not yet available.
*/
static inline void early_mmu_setup(void)
{
- unsigned int el, i;
- u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE;
- u64 *level1_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000);
- u64 *level1_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000);
- u64 *level2_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
- u64 *level2_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000);
-
- struct table_info table = {level0_table, 0, BLOCK_SIZE_L0};
+ unsigned int el = current_el();
- /* Invalidate all table entries */
- memset(level0_table, 0, 0x5000);
+ /* global data is already setup, no allocation yet */
+ gd->arch.tlb_addr = CONFIG_SYS_FSL_OCRAM_BASE;
+ gd->arch.tlb_fillptr = gd->arch.tlb_addr;
+ gd->arch.tlb_size = EARLY_PGTABLE_SIZE;
- /* Fill in the table entries */
- set_pgtable_table(level0_table, 0, level1_table0);
- set_pgtable_table(level0_table, 1, level1_table1);
- set_pgtable_table(level1_table0, 0, level2_table0);
+ /* Create early page tables */
+ setup_pgtables();
-#ifdef CONFIG_FSL_LSCH3
- set_pgtable_table(level1_table0,
- CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1,
- level2_table1);
-#elif defined(CONFIG_FSL_LSCH2)
- set_pgtable_table(level1_table0, 1, level2_table1);
-#endif
- /* Find the table and fill in the block entries */
- for (i = 0; i < ARRAY_SIZE(early_mmu_table); i++) {
- if (find_table(&early_mmu_table[i],
- &table, level0_table) == 0) {
- /*
- * If find_table() returns error, it cannot be dealt
- * with here. Breakpoint can be added for debugging.
- */
- set_block_entry(&early_mmu_table[i], &table);
- /*
- * If set_block_entry() returns error, it cannot be
- * dealt with here too.
- */
- }
- }
-
- el = current_el();
-
- set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR,
+ /* point TTBR to the new table */
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
+ get_tcr(el, NULL, NULL) &
+ ~(TCR_ORGN_MASK | TCR_IRGN_MASK),
MEMORY_ATTRIBUTES);
- set_sctlr(get_sctlr() | CR_M);
-}
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-/*
- * Called from final mmu setup. The phys_addr is new, non-existing
- * address. A new sub table is created @level2_table_secure to cover
- * size of CONFIG_SYS_MEM_RESERVE_SECURE memory.
- */
-static inline int final_secure_ddr(u64 *level0_table,
- u64 *level2_table_secure,
- phys_addr_t phys_addr)
-{
- int ret = -EINVAL;
- struct table_info table = {};
- struct sys_mmu_table ddr_entry = {
- 0, 0, BLOCK_SIZE_L1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
- };
- u64 index;
-
- /* Need to create a new table */
- ddr_entry.virt_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
- ddr_entry.phys_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
- ret = find_table(&ddr_entry, &table, level0_table);
- if (ret)
- return ret;
- index = (ddr_entry.virt_addr - table.table_base) >> SECTION_SHIFT_L1;
- set_pgtable_table(table.ptr, index, level2_table_secure);
- table.ptr = level2_table_secure;
- table.table_base = ddr_entry.virt_addr;
- table.entry_size = BLOCK_SIZE_L2;
- ret = set_block_entry(&ddr_entry, &table);
- if (ret) {
- printf("MMU error: could not fill non-secure ddr block entries\n");
- return ret;
- }
- ddr_entry.virt_addr = phys_addr;
- ddr_entry.phys_addr = phys_addr;
- ddr_entry.size = CONFIG_SYS_MEM_RESERVE_SECURE;
- ddr_entry.attribute = PTE_BLOCK_OUTER_SHARE;
- ret = find_table(&ddr_entry, &table, level0_table);
- if (ret) {
- printf("MMU error: could not find secure ddr table\n");
- return ret;
- }
- ret = set_block_entry(&ddr_entry, &table);
- if (ret)
- printf("MMU error: could not set secure ddr block entry\n");
-
- return ret;
+ set_sctlr(get_sctlr() | CR_M);
}
-#endif
/*
* The final tables look similar to early tables, but different in detail.
* These tables are in DRAM. Sub tables are added to enable cache for
* QBMan and OCRAM.
*
- * Put the MMU table in secure memory if gd->secure_ram is valid.
- * OCRAM will be not used for this purpose so gd->secure_ram can't be 0.
- *
- * Level 1 table 0 contains 512 entries for each 1GB from 0 to 512GB.
- * Level 1 table 1 contains 512 entries for each 1GB from 512GB to 1TB.
- * Level 2 table 0 contains 512 entries for each 2MB from 0 to 1GB.
- *
- * For LSCH3:
- * Level 2 table 1 contains 512 entries for each 2MB from 32GB to 33GB.
- * For LSCH2:
- * Level 2 table 1 contains 512 entries for each 2MB from 1GB to 2GB.
- * Level 2 table 2 contains 512 entries for each 2MB from 20GB to 21GB.
+ * Put the MMU table in secure memory if gd->arch.secure_ram is valid.
+ * OCRAM will be not used for this purpose so gd->arch.secure_ram can't be 0.
*/
static inline void final_mmu_setup(void)
{
+ u64 tlb_addr_save = gd->arch.tlb_addr;
unsigned int el = current_el();
- unsigned int i;
- u64 *level0_table = (u64 *)gd->arch.tlb_addr;
- u64 *level1_table0;
- u64 *level1_table1;
- u64 *level2_table0;
- u64 *level2_table1;
-#ifdef CONFIG_FSL_LSCH2
- u64 *level2_table2;
-#endif
- struct table_info table = {NULL, 0, BLOCK_SIZE_L0};
-
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- u64 *level2_table_secure;
-
- if (el == 3) {
- /*
- * Only use gd->secure_ram if the address is recalculated
- * Align to 4KB for MMU table
- */
- if (gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED)
- level0_table = (u64 *)(gd->secure_ram & ~0xfff);
- else
- printf("MMU warning: gd->secure_ram is not maintained, disabled.\n");
- }
-#endif
- level1_table0 = level0_table + 512;
- level1_table1 = level1_table0 + 512;
- level2_table0 = level1_table1 + 512;
- level2_table1 = level2_table0 + 512;
-#ifdef CONFIG_FSL_LSCH2
- level2_table2 = level2_table1 + 512;
-#endif
- table.ptr = level0_table;
-
- /* Invalidate all table entries */
- memset(level0_table, 0, PGTABLE_SIZE);
-
- /* Fill in the table entries */
- set_pgtable_table(level0_table, 0, level1_table0);
- set_pgtable_table(level0_table, 1, level1_table1);
- set_pgtable_table(level1_table0, 0, level2_table0);
-#ifdef CONFIG_FSL_LSCH3
- set_pgtable_table(level1_table0,
- CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1,
- level2_table1);
-#elif defined(CONFIG_FSL_LSCH2)
- set_pgtable_table(level1_table0, 1, level2_table1);
- set_pgtable_table(level1_table0,
- CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1,
- level2_table2);
+ int index;
#endif
- /* Find the table and fill in the block entries */
- for (i = 0; i < ARRAY_SIZE(final_mmu_table); i++) {
- if (find_table(&final_mmu_table[i],
- &table, level0_table) == 0) {
- if (set_block_entry(&final_mmu_table[i],
- &table) != 0) {
- printf("MMU error: could not set block entry for %p\n",
- &final_mmu_table[i]);
- }
+ mem_map = final_map;
- } else {
- printf("MMU error: could not find the table for %p\n",
- &final_mmu_table[i]);
- }
- }
- /* Set the secure memory to secure in MMU */
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- if (el == 3 && gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
-#ifdef CONFIG_FSL_LSCH3
- level2_table_secure = level2_table1 + 512;
-#elif defined(CONFIG_FSL_LSCH2)
- level2_table_secure = level2_table2 + 512;
-#endif
- if (!final_secure_ddr(level0_table,
- level2_table_secure,
- gd->secure_ram & ~0x3)) {
- gd->secure_ram |= MEM_RESERVE_SECURE_SECURED;
- debug("Now MMU table is in secured memory at 0x%llx\n",
- gd->secure_ram & ~0x3);
+ if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
+ if (el == 3) {
+ /*
+ * Only use gd->arch.secure_ram if the address is
+ * recalculated. Align to 4KB for MMU table.
+ */
+ /* put page tables in secure ram */
+ index = ARRAY_SIZE(final_map) - 2;
+ gd->arch.tlb_addr = gd->arch.secure_ram & ~0xfff;
+ final_map[index].virt = gd->arch.secure_ram & ~0x3;
+ final_map[index].phys = final_map[index].virt;
+ final_map[index].size = CONFIG_SYS_MEM_RESERVE_SECURE;
+ final_map[index].attrs = PTE_BLOCK_OUTER_SHARE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_SECURED;
+ tlb_addr_save = gd->arch.tlb_addr;
} else {
- printf("MMU warning: Failed to secure DDR\n");
+ /* Use allocated (board_f.c) memory for TLB */
+ tlb_addr_save = gd->arch.tlb_allocated;
+ gd->arch.tlb_addr = tlb_addr_save;
}
}
#endif
+ /* Reset the fill ptr */
+ gd->arch.tlb_fillptr = tlb_addr_save;
+
+ /* Create normal system page tables */
+ setup_pgtables();
+
+ /* Create emergency page tables */
+ gd->arch.tlb_addr = gd->arch.tlb_fillptr;
+ gd->arch.tlb_emerg = gd->arch.tlb_addr;
+ setup_pgtables();
+ gd->arch.tlb_addr = tlb_addr_save;
+
/* flush new MMU table */
- flush_dcache_range((ulong)level0_table,
- (ulong)level0_table + gd->arch.tlb_size);
+ flush_dcache_range(gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
/* point TTBR to the new table */
- set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR_FINAL,
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL),
MEMORY_ATTRIBUTES);
/*
- * MMU is already enabled, just need to invalidate TLB to load the
+ * EL3 MMU is already enabled, just need to invalidate TLB to load the
* new table. The new table is compatible with the current table, if
* MMU somehow walks through the new table before invalidation TLB,
* it still works. So we don't need to turn off MMU here.
+ * When EL2 MMU table is created by calling this function, MMU needs
+ * to be enabled.
*/
+ set_sctlr(get_sctlr() | CR_M);
}
u64 get_page_table_size(void)
@@ -422,15 +170,21 @@ int arch_cpu_init(void)
return 0;
}
+void mmu_setup(void)
+{
+ final_mmu_setup();
+}
+
/*
- * This function is called from lib/board.c.
- * It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
- * There is no need to disable d-cache for this operation.
+ * This function is called from common/board_r.c.
+ * It recreates MMU table in main memory.
*/
void enable_caches(void)
{
- final_mmu_setup();
+ mmu_setup();
__asm_invalidate_tlb_all();
+ icache_enable();
+ dcache_enable();
}
#endif
@@ -558,7 +312,8 @@ int print_cpuinfo(void)
printf("CPU%d(%s):%-4s MHz ", core,
type == TY_ITYP_VER_A7 ? "A7 " :
(type == TY_ITYP_VER_A53 ? "A53" :
- (type == TY_ITYP_VER_A57 ? "A57" : " ")),
+ (type == TY_ITYP_VER_A57 ? "A57" :
+ (type == TY_ITYP_VER_A72 ? "A72" : " "))),
strmhz(buf, sysinfo.freq_processor[core]));
}
printf("\n Bus: %-4s MHz ",
@@ -616,6 +371,7 @@ int arch_early_init_r(void)
{
#ifdef CONFIG_MP
int rv = 1;
+ u32 psci_ver = 0xffffffff;
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
@@ -623,9 +379,15 @@ int arch_early_init_r(void)
#endif
#ifdef CONFIG_MP
- rv = fsl_layerscape_wake_seconday_cores();
- if (rv)
- printf("Did not wake secondary cores\n");
+#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI)
+ /* Check the psci version to determine if the psci is supported */
+ psci_ver = sec_firmware_support_psci_version();
+#endif
+ if (psci_ver == 0xffffffff) {
+ rv = fsl_layerscape_wake_seconday_cores();
+ if (rv)
+ printf("Did not wake secondary cores\n");
+ }
#endif
#ifdef CONFIG_SYS_HAS_SERDES
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
index da5e052569..7867c379d4 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
+++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
@@ -128,7 +128,7 @@ mcinitcmd: This environment variable is defined to initiate MC and DPL deploymen
during U-boot booting.However the MC, DPC and DPL can be applied from
console independently.
The variable needs to be set from the console once and then on
- rebooting the parameters set in the varible will automatically be
+ rebooting the parameters set in the variable will automatically be
executed. The commmand is demostrated taking an example of mc boot
using NOR Flash i.e. MC, DPL, and DPC is stored in the NOR flash:
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
index 8eee016f11..f7b949aca2 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
+++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
@@ -3,6 +3,7 @@ SoC overview
1. LS1043A
2. LS2080A
3. LS1012A
+ 4. LS1046A
LS1043A
---------
@@ -127,3 +128,44 @@ The LS1012A SoC includes the following function and features:
- Two WatchDog timers
- ARM generic timer
- QorIQ platform's trust architecture 2.1
+
+LS1046A
+--------
+The LS1046A integrated multicore processor combines four ARM Cortex-A72
+processor cores with datapath acceleration optimized for L2/3 packet
+processing, single pass security offload and robust traffic management
+and quality of service.
+
+The LS1046A SoC includes the following function and features:
+ - Four 64-bit ARM Cortex-A72 CPUs
+ - 2 MB unified L2 Cache
+ - One 64-bit DDR4 SDRAM memory controllers with ECC and interleaving
+ support
+ - Data Path Acceleration Architecture (DPAA) incorporating acceleration the
+ the following functions:
+ - Packet parsing, classification, and distribution (FMan)
+ - Queue management for scheduling, packet sequencing, and congestion
+ management (QMan)
+ - Hardware buffer management for buffer allocation and de-allocation (BMan)
+ - Cryptography acceleration (SEC)
+ - Two Configurable x4 SerDes
+ - Two PLLs per four-lane SerDes
+ - Support for 10G operation
+ - Ethernet interfaces by FMan
+ - Up to 2 x XFI supporting 10G interface (MAC 9, 10)
+ - Up to 1 x QSGMII (MAC 5, 6, 10, 1)
+ - Up to 4 x SGMII supporting 1000Mbps (MAC 5, 6, 9, 10)
+ - Up to 3 x SGMII supporting 2500Mbps (MAC 5, 9, 10)
+ - Up to 2 x RGMII supporting 1000Mbps (MAC 3, 4)
+ - High-speed peripheral interfaces
+ - Three PCIe 3.0 controllers, one supporting x4 operation
+ - One serial ATA (SATA 3.0) controllers
+ - Additional peripheral interfaces
+ - Three high-speed USB 3.0 controllers with integrated PHY
+ - Enhanced secure digital host controller (eSDXC/eMMC)
+ - Quad Serial Peripheral Interface (QSPI) Controller
+ - Serial peripheral interface (SPI) controller
+ - Four I2C controllers
+ - Two DUARTs
+ - Integrated flash controller (IFC) supporting NAND and NOR flash
+ - QorIQ platform's trust architecture 2.1
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index d17227ab2b..40d6a761e8 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -22,6 +22,9 @@
#endif
#include <fsl_sec.h>
#include <asm/arch-fsl-layerscape/soc.h>
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc)
{
@@ -38,7 +41,37 @@ void ft_fixup_cpu(void *blob)
int addr_cells;
u64 val, core_id;
size_t *boot_code_size = &(__secondary_boot_code_size);
+#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI)
+ int node;
+ u32 psci_ver;
+
+ /* Check the psci version to determine if the psci is supported */
+ psci_ver = sec_firmware_support_psci_version();
+ if (psci_ver == 0xffffffff) {
+ /* remove psci DT node */
+ node = fdt_path_offset(blob, "/psci");
+ if (node >= 0)
+ goto remove_psci_node;
+
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci");
+ if (node >= 0)
+ goto remove_psci_node;
+
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-0.2");
+ if (node >= 0)
+ goto remove_psci_node;
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-1.0");
+ if (node >= 0)
+ goto remove_psci_node;
+
+remove_psci_node:
+ if (node >= 0)
+ fdt_del_node(blob, node);
+ } else {
+ return;
+ }
+#endif
off = fdt_path_offset(blob, "/cpus");
if (off < 0) {
puts("couldn't find /cpus node\n");
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
index fe3444a91e..f73092ae3e 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
@@ -13,6 +13,9 @@
#ifdef CONFIG_SYS_FSL_SRDS_1
static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
int is_serdes_configured(enum srds_prtcl device)
{
@@ -21,6 +24,9 @@ int is_serdes_configured(enum srds_prtcl device)
#ifdef CONFIG_SYS_FSL_SRDS_1
ret |= serdes1_prtcl_map[device];
#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ ret |= serdes2_prtcl_map[device];
+#endif
return !!ret;
}
@@ -38,6 +44,12 @@ int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
break;
#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ case FSL_SRDS_2:
+ cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
+ break;
+#endif
default:
printf("invalid SerDes%d\n", sd);
break;
@@ -114,4 +126,11 @@ void fsl_serdes_init(void)
FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
serdes1_prtcl_map);
#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ serdes_init(FSL_SRDS_2,
+ CONFIG_SYS_FSL_SERDES_ADDR,
+ FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
+ FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,
+ serdes2_prtcl_map);
+#endif
}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
index d0dc58d181..8922197d43 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
@@ -107,6 +107,12 @@ void get_sys_info(struct sys_info *sys_info)
case 3:
sys_info->freq_fman[0] = freq_c_pll[0] / 3;
break;
+ case 4:
+ sys_info->freq_fman[0] = freq_c_pll[0] / 4;
+ break;
+ case 5:
+ sys_info->freq_fman[0] = sys_info->freq_systembus;
+ break;
case 6:
sys_info->freq_fman[0] = freq_c_pll[1] / 2;
break;
@@ -124,8 +130,23 @@ void get_sys_info(struct sys_info *sys_info)
#ifdef CONFIG_FSL_ESDHC
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
rcw_tmp = in_be32(&gur->rcwsr[15]);
- rcw_tmp = (rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT;
- sys_info->freq_sdhc = freq_c_pll[1] / rcw_tmp;
+ switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
+ case 1:
+ sys_info->freq_sdhc = freq_c_pll[1];
+ break;
+ case 2:
+ sys_info->freq_sdhc = freq_c_pll[1] / 2;
+ break;
+ case 3:
+ sys_info->freq_sdhc = freq_c_pll[1] / 3;
+ break;
+ case 6:
+ sys_info->freq_sdhc = freq_c_pll[0] / 2;
+ break;
+ default:
+ printf("Error: Unknown ESDHC clock select!\n");
+ break;
+ }
#else
sys_info->freq_sdhc = sys_info->freq_systembus;
#endif
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c
new file mode 100644
index 0000000000..1da6b7135f
--- /dev/null
+++ b/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_lsch2.h>
+
+struct serdes_config {
+ u32 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x3333, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x1133, {XFI_FM1_MAC9, XFI_FM1_MAC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x1333, {XFI_FM1_MAC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x2333, {SGMII_2500_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x2233, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
+ SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
+ {0x1040, {XFI_FM1_MAC9, NONE, QSGMII_FM1_A, NONE} },
+ {0x2040, {SGMII_2500_FM1_DTSEC9, NONE, QSGMII_FM1_A, NONE} },
+ {0x1163, {XFI_FM1_MAC9, XFI_FM1_MAC10, PCIE1, SGMII_FM1_DTSEC6} },
+ {0x2263, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10, PCIE1,
+ SGMII_FM1_DTSEC6} },
+ {0x3363, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6, PCIE1,
+ SGMII_FM1_DTSEC6} },
+ {0x2223, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
+ SGMII_2500_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
+ {}
+};
+
+static struct serdes_config serdes2_cfg_tbl[] = {
+ /* SerDes 2 */
+ {0x8888, {PCIE1, PCIE1, PCIE1, PCIE1} },
+ {0x5559, {PCIE1, PCIE2, PCIE3, SATA1} },
+ {0x5577, {PCIE1, PCIE2, PCIE3, PCIE3} },
+ {0x5506, {PCIE1, PCIE2, NONE, PCIE3} },
+ {0x0506, {NONE, PCIE2, NONE, PCIE3} },
+ {0x0559, {NONE, PCIE2, PCIE3, SATA1} },
+ {0x5A59, {PCIE1, SGMII_FM1_DTSEC2, PCIE3, SATA1} },
+ {0x5A06, {PCIE1, SGMII_FM1_DTSEC2, NONE, PCIE3} },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+ serdes2_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
new file mode 100644
index 0000000000..541b251bf4
--- /dev/null
+++ b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <config.h>
+#include <errno.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/arch/soc.h>
+#ifdef CONFIG_FSL_LSCH3
+#include <asm/arch/immap_lsch3.h>
+#elif defined(CONFIG_FSL_LSCH2)
+#include <asm/arch/immap_lsch2.h>
+#endif
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
+
+int ppa_init(void)
+{
+ const void *ppa_fit_addr;
+ u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
+ int ret;
+
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_NOR
+ ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
+#else
+#error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined"
+#endif
+
+#ifdef CONFIG_FSL_LSCH3
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ boot_loc_ptr_l = &gur->bootlocptrl;
+ boot_loc_ptr_h = &gur->bootlocptrh;
+#elif defined(CONFIG_FSL_LSCH2)
+ struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR);
+ boot_loc_ptr_l = &scfg->scratchrw[1];
+ boot_loc_ptr_h = &scfg->scratchrw[0];
+#endif
+
+ debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n",
+ boot_loc_ptr_l, boot_loc_ptr_h);
+ ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h);
+
+ return ret;
+}
diff --git a/arch/arm/cpu/armv8/s32v234/cpu.c b/arch/arm/cpu/armv8/s32v234/cpu.c
index dac12a2552..5c97e0eee4 100644
--- a/arch/arm/cpu/armv8/s32v234/cpu.c
+++ b/arch/arm/cpu/armv8/s32v234/cpu.c
@@ -32,24 +32,28 @@ u32 cpu_mask(void)
static struct mm_region s32v234_mem_map[] = {
{
- .base = S32V234_IRAM_BASE,
+ .virt = S32V234_IRAM_BASE,
+ .phys = S32V234_IRAM_BASE,
.size = S32V234_IRAM_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE
}, {
- .base = S32V234_DRAM_BASE1,
+ .virt = S32V234_DRAM_BASE1,
+ .phys = S32V234_DRAM_BASE1,
.size = S32V234_DRAM_SIZE1,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE
}, {
- .base = S32V234_PERIPH_BASE,
+ .virt = S32V234_PERIPH_BASE,
+ .phys = S32V234_PERIPH_BASE,
.size = S32V234_PERIPH_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
/* TODO: Do we need these? */
/* | PTE_BLOCK_PXN | PTE_BLOCK_UXN */
}, {
- .base = S32V234_DRAM_BASE2,
+ .virt = S32V234_DRAM_BASE2,
+ .phys = S32V234_DRAM_BASE2,
.size = S32V234_DRAM_SIZE2,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
PTE_BLOCK_OUTER_SHARE
diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c
new file mode 100644
index 0000000000..e21e199381
--- /dev/null
+++ b/arch/arm/cpu/armv8/sec_firmware.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/macro.h>
+#include <asm/armv8/sec_firmware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+extern void c_runtime_cpu_setup(void);
+
+#define SEC_FIRMWARE_LOADED 0x1
+#define SEC_FIRMWARE_RUNNING 0x2
+#define SEC_FIRMWARE_ADDR_MASK (~0x3)
+ /*
+ * Secure firmware load addr
+ * Flags used: 0x1 secure firmware has been loaded to secure memory
+ * 0x2 secure firmware is running
+ */
+ phys_addr_t sec_firmware_addr;
+
+static int sec_firmware_get_data(const void *sec_firmware_img,
+ const void **data, size_t *size)
+{
+ int conf_node_off, fw_node_off;
+ char *conf_node_name = NULL;
+ char *desc;
+ int ret;
+
+ conf_node_name = SEC_FIRMEWARE_FIT_CNF_NAME;
+
+ conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
+ if (conf_node_off < 0) {
+ printf("SEC Firmware: %s: no such config\n", conf_node_name);
+ return -ENOENT;
+ }
+
+ fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
+ SEC_FIRMWARE_FIT_IMAGE);
+ if (fw_node_off < 0) {
+ printf("SEC Firmware: No '%s' in config\n",
+ SEC_FIRMWARE_FIT_IMAGE);
+ return -ENOLINK;
+ }
+
+ /* Verify secure firmware image */
+ if (!(fit_image_verify(sec_firmware_img, fw_node_off))) {
+ printf("SEC Firmware: Bad firmware image (bad CRC)\n");
+ return -EINVAL;
+ }
+
+ if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) {
+ printf("SEC Firmware: Can't get %s subimage data/size",
+ SEC_FIRMWARE_FIT_IMAGE);
+ return -ENOENT;
+ }
+
+ ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc);
+ if (ret)
+ printf("SEC Firmware: Can't get description\n");
+ else
+ printf("%s\n", desc);
+
+ return ret;
+}
+
+/*
+ * SEC Firmware FIT image parser checks if the image is in FIT
+ * format, verifies integrity of the image and calculates raw
+ * image address and size values.
+ *
+ * Returns 0 on success and a negative errno on error task fail.
+ */
+static int sec_firmware_parse_image(const void *sec_firmware_img,
+ const void **raw_image_addr,
+ size_t *raw_image_size)
+{
+ int ret;
+
+ ret = sec_firmware_get_data(sec_firmware_img, raw_image_addr,
+ raw_image_size);
+ if (ret)
+ return ret;
+
+ debug("SEC Firmware: raw_image_addr = 0x%p, raw_image_size = 0x%lx\n",
+ *raw_image_addr, *raw_image_size);
+
+ return 0;
+}
+
+static int sec_firmware_copy_image(const char *title,
+ u64 image_addr, u32 image_size, u64 sec_firmware)
+{
+ debug("%s copied to address 0x%p\n", title, (void *)sec_firmware);
+ memcpy((void *)sec_firmware, (void *)image_addr, image_size);
+ flush_dcache_range(sec_firmware, sec_firmware + image_size);
+
+ return 0;
+}
+
+/*
+ * This function will parse the SEC Firmware image, and then load it
+ * to secure memory.
+ */
+static int sec_firmware_load_image(const void *sec_firmware_img)
+{
+ const void *raw_image_addr;
+ size_t raw_image_size = 0;
+ int ret;
+
+ /*
+ * The Excetpion Level must be EL3 to load and initialize
+ * the SEC Firmware.
+ */
+ if (current_el() != 3) {
+ ret = -EACCES;
+ goto out;
+ }
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ /*
+ * The SEC Firmware must be stored in secure memory.
+ * Append SEC Firmware to secure mmu table.
+ */
+ if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) +
+ gd->arch.tlb_size;
+#else
+#error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support"
+#endif
+
+ /* Align SEC Firmware base address to 4K */
+ sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff;
+ debug("SEC Firmware: Load address: 0x%llx\n",
+ sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
+
+ ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr,
+ &raw_image_size);
+ if (ret)
+ goto out;
+
+ /* TODO:
+ * Check if the end addr of SEC Firmware has been extend the secure
+ * memory.
+ */
+
+ /* Copy the secure firmware to secure memory */
+ ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr,
+ raw_image_size, sec_firmware_addr &
+ SEC_FIRMWARE_ADDR_MASK);
+ if (ret)
+ goto out;
+
+ sec_firmware_addr |= SEC_FIRMWARE_LOADED;
+ debug("SEC Firmware: Entry point: 0x%llx\n",
+ sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
+
+ return 0;
+
+out:
+ printf("SEC Firmware: error (%d)\n", ret);
+ sec_firmware_addr = 0;
+
+ return ret;
+}
+
+static int sec_firmware_entry(u32 *eret_hold_l, u32 *eret_hold_h)
+{
+ const void *entry = (void *)(sec_firmware_addr &
+ SEC_FIRMWARE_ADDR_MASK);
+
+ return _sec_firmware_entry(entry, eret_hold_l, eret_hold_h);
+}
+
+/* Check the secure firmware FIT image */
+__weak bool sec_firmware_is_valid(const void *sec_firmware_img)
+{
+ if (fdt_check_header(sec_firmware_img)) {
+ printf("SEC Firmware: Bad firmware image (not a FIT image)\n");
+ return false;
+ }
+
+ if (!fit_check_format(sec_firmware_img)) {
+ printf("SEC Firmware: Bad firmware image (bad FIT header)\n");
+ return false;
+ }
+
+ return true;
+}
+
+#ifdef CONFIG_ARMV8_PSCI
+/*
+ * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI
+ * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error
+ * number will be returned according to SMC Calling Conventions. But
+ * when getting the NOT_SUPPORTED error number, we cannot ensure if
+ * the PSCI version is v0.1 or other error occurred. So, PSCI v0.1
+ * won't be supported by this framework.
+ * And if the secure firmware isn't running, return NOT_SUPPORTED.
+ *
+ * The return value on success is PSCI version in format
+ * major[31:16]:minor[15:0].
+ */
+unsigned int sec_firmware_support_psci_version(void)
+{
+ if (sec_firmware_addr & SEC_FIRMWARE_RUNNING)
+ return _sec_firmware_support_psci_version();
+
+ return 0xffffffff;
+}
+#endif
+
+/*
+ * sec_firmware_init - Initialize the SEC Firmware
+ * @sec_firmware_img: the SEC Firmware image address
+ * @eret_hold_l: the address to hold exception return address low
+ * @eret_hold_h: the address to hold exception return address high
+ */
+int sec_firmware_init(const void *sec_firmware_img,
+ u32 *eret_hold_l,
+ u32 *eret_hold_h)
+{
+ int ret;
+
+ if (!sec_firmware_is_valid(sec_firmware_img))
+ return -EINVAL;
+
+ ret = sec_firmware_load_image(sec_firmware_img);
+ if (ret) {
+ printf("SEC Firmware: Failed to load image\n");
+ return ret;
+ } else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) {
+ ret = sec_firmware_entry(eret_hold_l, eret_hold_h);
+ if (ret) {
+ printf("SEC Firmware: Failed to initialize\n");
+ return ret;
+ }
+ }
+
+ debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n",
+ current_el());
+
+ /*
+ * The PE will be turned into target EL when returned from
+ * SEC Firmware.
+ */
+ if (current_el() != SEC_FIRMWARE_TARGET_EL)
+ return -EACCES;
+
+ sec_firmware_addr |= SEC_FIRMWARE_RUNNING;
+
+ /* Set exception table and enable caches if it isn't EL3 */
+ if (current_el() != 3) {
+ c_runtime_cpu_setup();
+ enable_caches();
+ }
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/sec_firmware_asm.S b/arch/arm/cpu/armv8/sec_firmware_asm.S
new file mode 100644
index 0000000000..0c6a46249a
--- /dev/null
+++ b/arch/arm/cpu/armv8/sec_firmware_asm.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/system.h>
+#include <asm/macro.h>
+
+WEAK(_sec_firmware_entry)
+ /*
+ * x0: Secure Firmware entry point
+ * x1: Exception return address Low
+ * x2: Exception return address High
+ */
+
+ /* Save stack pointer for EL2 */
+ mov x3, sp
+ msr sp_el2, x3
+
+ /* Set exception return address hold pointer */
+ adr x4, 1f
+ mov x3, x4
+#ifdef SEC_FIRMWARE_ERET_ADDR_REVERT
+ rev w3, w3
+#endif
+ str w3, [x1]
+ lsr x3, x4, #32
+#ifdef SEC_FIRMWARE_ERET_ADDR_REVERT
+ rev w3, w3
+#endif
+ str w3, [x2]
+
+ /* Call SEC monitor */
+ br x0
+
+1:
+ mov x0, #0
+ ret
+ENDPROC(_sec_firmware_entry)
+
+#ifdef CONFIG_ARMV8_PSCI
+ENTRY(_sec_firmware_support_psci_version)
+ mov x0, 0x84000000
+ mov x1, 0x0
+ mov x2, 0x0
+ mov x3, 0x0
+ smc #0
+ ret
+ENDPROC(_sec_firmware_support_psci_version)
+#endif
diff --git a/arch/arm/cpu/armv8/spin_table.c b/arch/arm/cpu/armv8/spin_table.c
new file mode 100644
index 0000000000..ec1c9b8ddb
--- /dev/null
+++ b/arch/arm/cpu/armv8/spin_table.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <asm/spin_table.h>
+
+int spin_table_update_dt(void *fdt)
+{
+ int cpus_offset, offset;
+ const char *prop;
+ int ret;
+ unsigned long rsv_addr = (unsigned long)&spin_table_reserve_begin;
+ unsigned long rsv_size = &spin_table_reserve_end -
+ &spin_table_reserve_begin;
+
+ cpus_offset = fdt_path_offset(fdt, "/cpus");
+ if (cpus_offset < 0)
+ return -ENODEV;
+
+ for (offset = fdt_first_subnode(fdt, cpus_offset);
+ offset >= 0;
+ offset = fdt_next_subnode(fdt, offset)) {
+ prop = fdt_getprop(fdt, offset, "device_type", NULL);
+ if (!prop || strcmp(prop, "cpu"))
+ continue;
+
+ /*
+ * In the first loop, we check if every CPU node specifies
+ * spin-table. Otherwise, just return successfully to not
+ * disturb other methods, like psci.
+ */
+ prop = fdt_getprop(fdt, offset, "enable-method", NULL);
+ if (!prop || strcmp(prop, "spin-table"))
+ return 0;
+ }
+
+ for (offset = fdt_first_subnode(fdt, cpus_offset);
+ offset >= 0;
+ offset = fdt_next_subnode(fdt, offset)) {
+ prop = fdt_getprop(fdt, offset, "device_type", NULL);
+ if (!prop || strcmp(prop, "cpu"))
+ continue;
+
+ ret = fdt_setprop_u64(fdt, offset, "cpu-release-addr",
+ (unsigned long)&spin_table_cpu_release_addr);
+ if (ret)
+ return -ENOSPC;
+ }
+
+ ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
+ if (ret)
+ return -ENOSPC;
+
+ printf(" Reserved memory region for spin-table: addr=%lx size=%lx\n",
+ rsv_addr, rsv_size);
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/spin_table_v8.S b/arch/arm/cpu/armv8/spin_table_v8.S
new file mode 100644
index 0000000000..d7f78a6a67
--- /dev/null
+++ b/arch/arm/cpu/armv8/spin_table_v8.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(spin_table_secondary_jump)
+.globl spin_table_reserve_begin
+spin_table_reserve_begin:
+0: wfe
+ ldr x0, spin_table_cpu_release_addr
+ cbz x0, 0b
+ br x0
+.globl spin_table_cpu_release_addr
+ .align 3
+spin_table_cpu_release_addr:
+ .quad 0
+.globl spin_table_reserve_end
+spin_table_reserve_end:
+ENDPROC(spin_table_secondary_jump)
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index dfce469206..19c771dba3 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -53,6 +53,11 @@ _bss_end_ofs:
.quad __bss_end - _start
reset:
+ /* Allow the board to save important registers */
+ b save_boot_params
+.globl save_boot_params_ret
+save_boot_params_ret:
+
#ifdef CONFIG_SYS_RESET_SCTRL
bl reset_sctrl
#endif
@@ -81,14 +86,6 @@ reset:
msr cpacr_el1, x0 /* Enable FP/SIMD */
0:
- /* Enalbe SMPEN bit for coherency.
- * This register is not architectural but at the moment
- * this bit should be set for A53/A57/A72.
- */
- mrs x0, S3_1_c15_c2_1 /* cpuactlr_el1 */
- orr x0, x0, #0x40
- msr S3_1_c15_c2_1, x0
-
/* Apply ARM core specific erratas */
bl apply_core_errata
@@ -102,7 +99,11 @@ reset:
/* Processor specific initialization */
bl lowlevel_init
-#ifdef CONFIG_ARMV8_MULTIENTRY
+#if CONFIG_IS_ENABLED(ARMV8_SPIN_TABLE)
+ branch_if_master x0, x1, master_cpu
+ b spin_table_secondary_jump
+ /* never return */
+#elif defined(CONFIG_ARMV8_MULTIENTRY)
branch_if_master x0, x1, master_cpu
/*
@@ -114,10 +115,8 @@ slave_cpu:
ldr x0, [x1]
cbz x0, slave_cpu
br x0 /* branch to the given address */
-master_cpu:
- /* On the master CPU */
#endif /* CONFIG_ARMV8_MULTIENTRY */
-
+master_cpu:
bl _main
#ifdef CONFIG_SYS_RESET_SCTRL
@@ -288,3 +287,7 @@ ENTRY(c_runtime_cpu_setup)
ret
ENDPROC(c_runtime_cpu_setup)
+
+WEAK(save_boot_params)
+ b save_boot_params_ret /* back to my caller */
+ENDPROC(save_boot_params)
diff --git a/arch/arm/cpu/armv8/zynqmp/clk.c b/arch/arm/cpu/armv8/zynqmp/clk.c
index 690c72dd66..f7e5ebfa63 100644
--- a/arch/arm/cpu/armv8/zynqmp/clk.c
+++ b/arch/arm/cpu/armv8/zynqmp/clk.c
@@ -12,22 +12,6 @@
DECLARE_GLOBAL_DATA_PTR;
-unsigned long get_uart_clk(int dev_id)
-{
- u32 ver = zynqmp_get_silicon_version();
-
- switch (ver) {
- case ZYNQMP_CSU_VERSION_VELOCE:
- return 48000;
- case ZYNQMP_CSU_VERSION_EP108:
- return 25000000;
- case ZYNQMP_CSU_VERSION_QEMU:
- return 133000000;
- }
-
- return 100000000;
-}
-
unsigned long zynqmp_get_system_timer_freq(void)
{
u32 ver = zynqmp_get_silicon_version();
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index 509f0aa387..b0f12955a1 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -18,40 +18,47 @@ DECLARE_GLOBAL_DATA_PTR;
static struct mm_region zynqmp_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0x70000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0xf8000000UL,
+ .virt = 0xf8000000UL,
+ .phys = 0xf8000000UL,
.size = 0x07e00000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0xffe00000UL,
+ .virt = 0xffe00000UL,
+ .phys = 0xffe00000UL,
.size = 0x00200000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x400000000UL,
+ .virt = 0x400000000UL,
+ .phys = 0x400000000UL,
.size = 0x200000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0x600000000UL,
+ .virt = 0x600000000UL,
+ .phys = 0x600000000UL,
.size = 0x800000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0xe00000000UL,
+ .virt = 0xe00000000UL,
+ .phys = 0xe00000000UL,
.size = 0xf200000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
diff --git a/arch/arm/cpu/armv8/zynqmp/mp.c b/arch/arm/cpu/armv8/zynqmp/mp.c
index 58312a79bc..e10fc3136c 100644
--- a/arch/arm/cpu/armv8/zynqmp/mp.c
+++ b/arch/arm/cpu/armv8/zynqmp/mp.c
@@ -128,7 +128,7 @@ static void enable_clock_r5(void)
writel(tmp, &crlapb_base->cpu_r5_ctrl);
/* Give some delay for clock
- * to propogate */
+ * to propagate */
udelay(0x500);
}
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
index 1769b6ea88..36c9fd0bd0 100644
--- a/arch/arm/cpu/u-boot.lds
+++ b/arch/arm/cpu/u-boot.lds
@@ -8,6 +8,7 @@
*/
#include <config.h>
+#include <asm/psci.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
@@ -48,34 +49,67 @@ SECTIONS
#ifdef CONFIG_ARMV7_NONSEC
+ /* Align the secure section only if we're going to use it in situ */
+ .__secure_start :
+#ifndef CONFIG_ARMV7_SECURE_BASE
+ ALIGN(CONSTANT(COMMONPAGESIZE))
+#endif
+ {
+ KEEP(*(.__secure_start))
+ }
+
#ifndef CONFIG_ARMV7_SECURE_BASE
#define CONFIG_ARMV7_SECURE_BASE
#define __ARMV7_PSCI_STACK_IN_RAM
#endif
- .__secure_start : {
- . = ALIGN(0x1000);
- *(.__secure_start)
- }
-
.secure_text CONFIG_ARMV7_SECURE_BASE :
AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
{
*(._secure.text)
}
- . = LOADADDR(.__secure_start) +
- SIZEOF(.__secure_start) +
- SIZEOF(.secure_text);
+ .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
+ {
+ *(._secure.data)
+ }
+ .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data),
+ CONSTANT(COMMONPAGESIZE)) (NOLOAD) :
#ifdef __ARMV7_PSCI_STACK_IN_RAM
- /* Align to page boundary and skip 2 pages */
- . = (. & ~ 0xfff) + 0x2000;
-#undef __ARMV7_PSCI_STACK_IN_RAM
+ AT(ADDR(.secure_stack))
+#else
+ AT(LOADADDR(.secure_data) + SIZEOF(.secure_data))
+#endif
+ {
+ KEEP(*(.__secure_stack_start))
+
+ /* Skip addreses for stack */
+ . = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE;
+
+ /* Align end of stack section to page boundary */
+ . = ALIGN(CONSTANT(COMMONPAGESIZE));
+
+ KEEP(*(.__secure_stack_end))
+
+#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE
+ /*
+ * We are not checking (__secure_end - __secure_start) here,
+ * as these are the load addresses, and do not include the
+ * stack section. Instead, use the end of the stack section
+ * and the start of the text section.
+ */
+ ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE,
+ "Error: secure section exceeds secure memory size");
+#endif
+ }
+
+#ifndef __ARMV7_PSCI_STACK_IN_RAM
+ /* Reset VMA but don't allocate space if we have secure SRAM */
+ . = LOADADDR(.secure_stack);
#endif
- __secure_end_lma = .;
- .__secure_end : AT(__secure_end_lma) {
+ .__secure_end : AT(ADDR(.__secure_end)) {
*(.__secure_end)
LONG(0x1d1071c); /* Must output something to reset LMA */
}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ef573ec685..7e2108312b 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -31,7 +31,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3288-firefly.dtb \
rk3288-jerry.dtb \
rk3288-rock2-square.dtb \
- rk3036-sdk.dtb
+ rk3288-evb.dtb \
+ rk3036-sdk.dtb \
+ rk3399-evb.dtb
dtb-$(CONFIG_ARCH_MESON) += \
meson-gxbb-odroidc2.dtb
dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
@@ -53,7 +55,8 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
tegra124-jetson-tk1.dtb \
tegra124-nyan-big.dtb \
tegra124-venice2.dtb \
- tegra186-p2771-0000.dtb \
+ tegra186-p2771-0000-a02.dtb \
+ tegra186-p2771-0000-b00.dtb \
tegra210-e2220-1170.dtb \
tegra210-p2371-0000.dtb \
tegra210-p2371-2180.dtb \
@@ -242,8 +245,10 @@ dtb-$(CONFIG_MACH_SUN8I_A83T) += \
sun8i-a83t-sinovoip-bpi-m3.dtb
dtb-$(CONFIG_MACH_SUN8I_H3) += \
sun8i-h3-orangepi-2.dtb \
+ sun8i-h3-orangepi-lite.dtb \
sun8i-h3-orangepi-one.dtb \
sun8i-h3-orangepi-pc.dtb \
+ sun8i-h3-orangepi-pc-plus.dtb \
sun8i-h3-orangepi-plus.dtb
dtb-$(CONFIG_MACH_SUN50I) += \
sun50i-a64-pine64-plus.dtb \
diff --git a/arch/arm/dts/dra7-evm.dts b/arch/arm/dts/dra7-evm.dts
index 08ef04e177..429b9edc1b 100644
--- a/arch/arm/dts/dra7-evm.dts
+++ b/arch/arm/dts/dra7-evm.dts
@@ -491,15 +491,13 @@
pinctrl-names = "default";
pinctrl-0 = <&qspi1_pins>;
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
m25p80@0 {
compatible = "s25fl256s1","spi-flash";
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
- spi-cpol;
- spi-cpha;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/dts/dra72-evm.dts b/arch/arm/dts/dra72-evm.dts
index 205103e2b0..ced2f1166d 100644
--- a/arch/arm/dts/dra72-evm.dts
+++ b/arch/arm/dts/dra72-evm.dts
@@ -603,15 +603,13 @@
pinctrl-names = "default";
pinctrl-0 = <&qspi1_pins>;
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
m25p80@0 {
compatible = "s25fl256s1","spi-flash";
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
- spi-cpol;
- spi-cpha;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts
index 3f87761584..26c4d7f4c6 100644
--- a/arch/arm/dts/exynos4210-origen.dts
+++ b/arch/arm/dts/exynos4210-origen.dts
@@ -22,7 +22,7 @@
aliases {
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc2 = "sdhci@12530000";
+ mmc2 = "/sdhci@12530000";
};
sdhci@12510000 {
diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts
index f3fac80190..2ed38f369e 100644
--- a/arch/arm/dts/exynos4210-trats.dts
+++ b/arch/arm/dts/exynos4210-trats.dts
@@ -29,8 +29,8 @@
i2c7 = "/i2c@138d0000";
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc0 = "sdhci@12510000";
- mmc2 = "sdhci@12530000";
+ mmc0 = "/sdhci@12510000";
+ mmc2 = "/sdhci@12530000";
};
fimd@11c00000 {
diff --git a/arch/arm/dts/exynos4210-universal_c210.dts b/arch/arm/dts/exynos4210-universal_c210.dts
index ad3527ec6f..8cac7dd752 100644
--- a/arch/arm/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/dts/exynos4210-universal_c210.dts
@@ -17,8 +17,8 @@
aliases {
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc0 = "sdhci@12510000";
- mmc2 = "sdhci@12530000";
+ mmc0 = "/sdhci@12510000";
+ mmc2 = "/sdhci@12530000";
};
sdhci@12510000 {
diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts
index a63e8abab4..188cb939bb 100644
--- a/arch/arm/dts/exynos4412-odroid.dts
+++ b/arch/arm/dts/exynos4412-odroid.dts
@@ -25,8 +25,8 @@
i2c7 = "/i2c@138d0000";
serial0 = "/serial@13800000";
console = "/serial@13810000";
- mmc2 = "sdhci@12530000";
- mmc4 = "dwmmc@12550000";
+ mmc2 = "/sdhci@12530000";
+ mmc4 = "/dwmmc@12550000";
};
i2c@13860000 {
diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts
index 2d4e522ea2..1fbcf8914f 100644
--- a/arch/arm/dts/exynos4412-trats2.dts
+++ b/arch/arm/dts/exynos4412-trats2.dts
@@ -29,9 +29,9 @@
i2c7 = "/i2c@138d0000";
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc0 = "sdhci@12510000";
- mmc2 = "sdhci@12530000";
- mmc4 = "dwmmc@12550000";
+ mmc0 = "/sdhci@12510000";
+ mmc2 = "/sdhci@12530000";
+ mshc0 = "/dwmmc@12550000";
};
i2c@138d0000 {
diff --git a/arch/arm/dts/k2e-evm.dts b/arch/arm/dts/k2e-evm.dts
index 50c83c21d9..e2c3fb4910 100644
--- a/arch/arm/dts/k2e-evm.dts
+++ b/arch/arm/dts/k2e-evm.dts
@@ -119,10 +119,11 @@
};
&spi0 {
+ status = "okay";
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11";
+ compatible = "Micron,n25q128a11", "spi-flash";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/k2g-evm.dts b/arch/arm/dts/k2g-evm.dts
index 0ca36ef39a..e95efd4767 100644
--- a/arch/arm/dts/k2g-evm.dts
+++ b/arch/arm/dts/k2g-evm.dts
@@ -31,3 +31,72 @@
&gbe0 {
phy-handle = <&ethphy0>;
};
+
+&spi1 {
+ status = "okay";
+
+ spi_nor: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <50000000>;
+ m25p,fast-read;
+ reg = <0>;
+
+ partition@0 {
+ label = "u-boot-spl";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "misc";
+ reg = <0x80000 0xf80000>;
+ };
+ };
+};
+
+&qspi {
+ status = "okay";
+
+ flash0: m25p80@0 {
+ compatible = "s25fl512s","spi-flash";
+ reg = <0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <96000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ tshsl-ns = <392>;
+ tsd2d-ns = <392>;
+ tchsh-ns = <100>;
+ tslch-ns = <100>;
+ block-size = <18>;
+
+
+ partition@0 {
+ label = "QSPI.u-boot-spl-os";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@1 {
+ label = "QSPI.u-boot-env";
+ reg = <0x00100000 0x00040000>;
+ };
+ partition@2 {
+ label = "QSPI.skern";
+ reg = <0x00140000 0x0040000>;
+ };
+ partition@3 {
+ label = "QSPI.pmmc-firmware";
+ reg = <0x00180000 0x0040000>;
+ };
+ partition@4 {
+ label = "QSPI.kernel";
+ reg = <0x001C0000 0x0800000>;
+ };
+ partition@5 {
+ label = "QSPI.file-system";
+ reg = <0x009C0000 0x3640000>;
+ };
+ };
+};
diff --git a/arch/arm/dts/k2g.dtsi b/arch/arm/dts/k2g.dtsi
index a3ed444d3c..00cd492973 100644
--- a/arch/arm/dts/k2g.dtsi
+++ b/arch/arm/dts/k2g.dtsi
@@ -19,6 +19,11 @@
aliases {
serial0 = &uart0;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
+ spi3 = &spi3;
+ spi4 = &qspi;
};
memory {
@@ -80,6 +85,19 @@
bus_freq = <2500000>;
};
+ qspi: qspi@2940000 {
+ compatible = "cadence,qspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x02940000 0x1000>,
+ <0x24000000 0x4000000>;
+ interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_RISING>;
+ num-cs = <4>;
+ fifo-depth = <256>;
+ sram-size = <256>;
+ status = "disabled";
+ };
+
#include "k2g-netcp.dtsi"
pmmc: pmmc@2900000 {
@@ -88,5 +106,48 @@
ti,lpsc_module = <1>;
};
+ spi0: spi@21805400 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21805400 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@21805800 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21805800 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@21805c00 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21805C00 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi3: spi@21806000 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21806000 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/dts/k2hk-evm.dts b/arch/arm/dts/k2hk-evm.dts
index 660ebf58d5..c5cad2c9da 100644
--- a/arch/arm/dts/k2hk-evm.dts
+++ b/arch/arm/dts/k2hk-evm.dts
@@ -147,10 +147,11 @@
};
&spi0 {
+ status = "okay";
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11";
+ compatible = "Micron,n25q128a11", "spi-flash";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/k2l-evm.dts b/arch/arm/dts/k2l-evm.dts
index 9a69a6b553..da0661ba3e 100644
--- a/arch/arm/dts/k2l-evm.dts
+++ b/arch/arm/dts/k2l-evm.dts
@@ -96,10 +96,11 @@
};
&spi0 {
+ status ="okay";
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11";
+ compatible = "Micron,n25q128a11", "spi-flash";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/keystone.dtsi b/arch/arm/dts/keystone.dtsi
index f39b969f8d..be97f3f21f 100644
--- a/arch/arm/dts/keystone.dtsi
+++ b/arch/arm/dts/keystone.dtsi
@@ -19,6 +19,9 @@
aliases {
serial0 = &uart0;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
};
chosen {
diff --git a/arch/arm/dts/rk3288-evb.dts b/arch/arm/dts/rk3288-evb.dts
new file mode 100644
index 0000000000..caf24ee8ad
--- /dev/null
+++ b/arch/arm/dts/rk3288-evb.dts
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+ X11
+ */
+
+/dts-v1/;
+#include "rk3288-evb.dtsi"
+
+/ {
+ model = "Evb-RK3288";
+ compatible = "evb-rk3288,evb-rk3288", "rockchip,rk3288";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+};
+
+&dmc {
+ rockchip,num-channels = <2>;
+ rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
+ 0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
+ 0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
+ 0x1 0x2 0x2 0x4 0x0 0x0 0xc0 0x4
+ 0x8 0x1f4>;
+ rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
+ 0x0 0xc3 0x6 0x2>;
+ rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe>;
+ rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
+};
+
+&pinctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&uart2 {
+ u-boot,dm-pre-reloc;
+ reg-shift = <2>;
+};
+
+&sdmmc {
+ u-boot,dm-pre-reloc;
+};
+
+&emmc {
+ u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+ u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3288-evb.dtsi b/arch/arm/dts/rk3288-evb.dtsi
new file mode 100644
index 0000000000..cb7d03e558
--- /dev/null
+++ b/arch/arm/dts/rk3288-evb.dtsi
@@ -0,0 +1,379 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+ X11
+ */
+
+#include "rk3288.dtsi"
+
+/ {
+ memory {
+ reg = <0 0x80000000>;
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ gpio-key,wakeup = <1>;
+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+ label = "GPIO Power";
+ linux,code = <116>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+ };
+ };
+
+ vcc_sys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_flash: flash-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_flash";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_5v: usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc_host_5v: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "vcc_host_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_5v>;
+ };
+
+ vcc_otg_5v: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ regulator-name = "vcc_otg_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_5v>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&emmc {
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vcc_flash>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x40>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vdd_gpu: syr828@41 {
+ compatible = "silergy,syr828";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x41>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ hym8563: hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio7>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int>;
+ };
+
+ act8846: act8846@5a {
+ compatible = "active-semi,act8846";
+ reg = <0x5a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_hold>;
+ system-power-controller;
+
+ regulators {
+ vcc_ddr: REG1 {
+ regulator-name = "vcc_ddr";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vcc_io: REG2 {
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_log: REG3 {
+ regulator-name = "vdd_log";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vcc_20: REG4 {
+ regulator-name = "vcc_20";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ vccio_sd: REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd10_lcd: REG6 {
+ regulator-name = "vdd10_lcd";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcca_codec: REG7 {
+ regulator-name = "vcca_codec";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_tp: REG8 {
+ regulator-name = "vcca_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vccio_pmu: REG9 {
+ regulator-name = "vccio_pmu";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_10: REG10 {
+ regulator-name = "vdd_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcc_18: REG11 {
+ regulator-name = "vcc_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc18_lcd: REG12 {
+ regulator-name = "vcc18_lcd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ act8846 {
+ pwr_hold: pwr-hold {
+ rockchip,pins = <0 9 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ hym8563 {
+ rtc_int: rtc-int {
+ rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb_host {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb_otg {
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_18>;
+ status = "okay";
+};
+
+&sdio0 {
+ broken-cd;
+ bus-width = <4>;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>;
+ vmmc-supply = <&vcc_18>;
+ status = "disabled";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
+ vmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk>, <&spi0_cs0>, <&spi0_tx>, <&spi0_rx>, <&spi0_cs1>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usb_host1 {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
+
+&vopl {
+ status = "okay";
+};
+
+&vopl_mmu {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts
index aed8d3a712..3176d5046b 100644
--- a/arch/arm/dts/rk3288-firefly.dts
+++ b/arch/arm/dts/rk3288-firefly.dts
@@ -30,7 +30,8 @@
0x5 0x0>;
rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
0xa60 0x40 0x10 0x0>;
- rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>;
+ /* Add a dummy value to cause of-platdata think this is bytes */
+ rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
};
diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi
index 3dab0fc83e..bcf051a9d9 100644
--- a/arch/arm/dts/rk3288.dtsi
+++ b/arch/arm/dts/rk3288.dtsi
@@ -454,6 +454,7 @@
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_OTG0>;
clock-names = "otg";
+ dr_mode = "otg";
phys = <&usbphy0>;
phy-names = "usb2-phy";
status = "disabled";
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
new file mode 100644
index 0000000000..bbcfcd0da9
--- /dev/null
+++ b/arch/arm/dts/rk3399-evb.dts
@@ -0,0 +1,104 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+
+/ {
+ model = "Rockchip RK3399 Evaluation Board";
+ compatible = "rockchip,rk3399-evb", "rockchip,rk3399",
+ "google,rk3399evb-rev2";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ vdd_center: vdd-center {
+ compatible = "pwm-regulator";
+ pwms = <&pwm3 0 25000 0>;
+ regulator-name = "vdd_center";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ status = "okay";
+ };
+
+ vcc3v3_sys: vcc3v3-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_phy: vcc-phy-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_phy";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&emmc_phy {
+ status = "okay";
+};
+
+&pwm0 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ non-removable;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&pinctrl {
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins =
+ <1 21 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ pmic_dvs2: pmic-dvs2 {
+ rockchip,pins =
+ <1 18 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
new file mode 100644
index 0000000000..fb5af54799
--- /dev/null
+++ b/arch/arm/dts/rk3399.dtsi
@@ -0,0 +1,1028 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <dt-bindings/clock/rk3399-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+/ {
+ compatible = "rockchip,rk3399";
+
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu_l0>;
+ };
+ core1 {
+ cpu = <&cpu_l1>;
+ };
+ core2 {
+ cpu = <&cpu_l2>;
+ };
+ core3 {
+ cpu = <&cpu_l3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu_b0>;
+ };
+ core1 {
+ cpu = <&cpu_b1>;
+ };
+ };
+ };
+
+ cpu_l0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ #cooling-cells = <2>; /* min followed by max */
+ clocks = <&cru ARMCLKL>;
+ };
+
+ cpu_l1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLKL>;
+ };
+
+ cpu_l2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLKL>;
+ };
+
+ cpu_l3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLKL>;
+ };
+
+ cpu_b0: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ #cooling-cells = <2>; /* min followed by max */
+ clocks = <&cru ARMCLKB>;
+ };
+
+ cpu_b1: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0x0 0x101>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLKB>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ xin24m: xin24m {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ dmac_bus: dma-controller@ff6d0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0xff6d0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC0_PERILP>;
+ clock-names = "apb_pclk";
+ };
+
+ dmac_peri: dma-controller@ff6e0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0xff6e0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC1_PERILP>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ sdio0: dwmmc@fe310000 {
+ compatible = "rockchip,rk3399-dw-mshc",
+ "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xfe310000 0x0 0x4000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ status = "disabled";
+ };
+
+ sdmmc: dwmmc@fe320000 {
+ compatible = "rockchip,rk3399-dw-mshc",
+ "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xfe320000 0x0 0x4000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ status = "disabled";
+ };
+
+ sdhci: sdhci@fe330000 {
+ compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
+ reg = <0x0 0xfe330000 0x0 0x10000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ assigned-clocks = <&cru SCLK_EMMC>;
+ assigned-clock-rates = <200000000>;
+ clocks = <&cru SCLK_EMMC>, <&cru ACLK_EMMC>;
+ clock-names = "clk_xin", "clk_ahb";
+ phys = <&emmc_phy>;
+ phy-names = "phy_arasan";
+ status = "disabled";
+ };
+
+ usb_host0_ehci: usb@fe380000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0xfe380000 0x0 0x20000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
+ clock-names = "hclk_host0", "hclk_host0_arb";
+ status = "disabled";
+ };
+
+ usb_host0_ohci: usb@fe3a0000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0xfe3a0000 0x0 0x20000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
+ clock-names = "hclk_host0", "hclk_host0_arb";
+ status = "disabled";
+ };
+
+ usb_host1_ehci: usb@fe3c0000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0xfe3c0000 0x0 0x20000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
+ clock-names = "hclk_host1", "hclk_host1_arb";
+ status = "disabled";
+ };
+
+ usb_host1_ohci: usb@fe3e0000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0xfe3e0000 0x0 0x20000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
+ clock-names = "hclk_host1", "hclk_host1_arb";
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@fee00000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ interrupt-controller;
+
+ reg = <0x0 0xfee00000 0 0x10000>, /* GICD */
+ <0x0 0xfef00000 0 0xc0000>, /* GICR */
+ <0x0 0xfff00000 0 0x10000>, /* GICC */
+ <0x0 0xfff10000 0 0x10000>, /* GICH */
+ <0x0 0xfff20000 0 0x10000>; /* GICV */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ its: interrupt-controller@fee20000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ reg = <0x0 0xfee20000 0x0 0x20000>;
+ };
+ };
+
+ uart0: serial@ff180000 {
+ compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff180000 0x0 0x100>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+ status = "disabled";
+ };
+
+ uart1: serial@ff190000 {
+ compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff190000 0x0 0x100>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+ status = "disabled";
+ };
+
+ uart2: serial@ff1a0000 {
+ compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff1a0000 0x0 0x100>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2c_xfer>;
+ status = "disabled";
+ };
+
+ uart3: serial@ff1b0000 {
+ compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff1b0000 0x0 0x100>;
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>;
+ status = "disabled";
+ };
+
+ spi0: spi@ff1c0000 {
+ compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xff1c0000 0x0 0x1000>;
+ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@ff1d0000 {
+ compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xff1d0000 0x0 0x1000>;
+ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@ff1e0000 {
+ compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xff1e0000 0x0 0x1000>;
+ clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi4: spi@ff1f0000 {
+ compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xff1f0000 0x0 0x1000>;
+ clocks = <&cru SCLK_SPI4>, <&cru PCLK_SPI4>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi4_clk &spi4_tx &spi4_rx &spi4_cs0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi5: spi@ff200000 {
+ compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xff200000 0x0 0x1000>;
+ clocks = <&cru SCLK_SPI5>, <&cru PCLK_SPI5>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi5_clk &spi5_tx &spi5_rx &spi5_cs0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ pmugrf: syscon@ff320000 {
+ compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xff320000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pmu_io_domains: io-domains {
+ compatible = "rockchip,rk3399-pmu-io-voltage-domain";
+ status = "disabled";
+ };
+ };
+
+ spi3: spi@ff350000 {
+ compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+ reg = <0x0 0xff350000 0x0 0x1000>;
+ clocks = <&pmucru SCLK_SPI3_PMU>, <&pmucru PCLK_SPI3_PMU>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi3_clk &spi3_tx &spi3_rx &spi3_cs0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ uart4: serial@ff370000 {
+ compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xff370000 0x0 0x100>;
+ clocks = <&pmucru SCLK_UART4_PMU>, <&pmucru PCLK_UART4_PMU>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_xfer>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@ff420000 {
+ compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff420000 0x0 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ clocks = <&pmucru PCLK_RKPWM_PMU>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm1: pwm@ff420010 {
+ compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff420010 0x0 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pin>;
+ clocks = <&pmucru PCLK_RKPWM_PMU>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm2: pwm@ff420020 {
+ compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff420020 0x0 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pin>;
+ clocks = <&pmucru PCLK_RKPWM_PMU>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm3: pwm@ff420030 {
+ compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff420030 0x0 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3a_pin>;
+ clocks = <&pmucru PCLK_RKPWM_PMU>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pmucru: pmu-clock-controller@ff750000 {
+ compatible = "rockchip,rk3399-pmucru";
+ reg = <0x0 0xff750000 0x0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&pmucru PLL_PPLL>;
+ assigned-clock-rates = <676000000>;
+ };
+
+ cru: clock-controller@ff760000 {
+ compatible = "rockchip,rk3399-cru";
+ reg = <0x0 0xff760000 0x0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks =
+ <&cru PLL_GPLL>, <&cru PLL_CPLL>,
+ <&cru PLL_NPLL>,
+ <&cru ACLK_PERIHP>, <&cru HCLK_PERIHP>,
+ <&cru PCLK_PERIHP>,
+ <&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>,
+ <&cru PCLK_PERILP0>,
+ <&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>;
+ assigned-clock-rates =
+ <594000000>, <800000000>,
+ <1000000000>,
+ <150000000>, <75000000>,
+ <37500000>,
+ <100000000>, <100000000>,
+ <50000000>,
+ <100000000>, <50000000>;
+ };
+
+ grf: syscon@ff770000 {
+ compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xff770000 0x0 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ io_domains: io-domains {
+ compatible = "rockchip,rk3399-io-voltage-domain";
+ status = "disabled";
+ };
+
+ emmc_phy: phy@f780 {
+ compatible = "rockchip,rk3399-emmc-phy";
+ reg = <0xf780 0x24>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ watchdog@ff840000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x0 0xff840000 0x0 0x100>;
+ clocks = <&cru PCLK_WDT>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ spdif: spdif@ff870000 {
+ compatible = "rockchip,rk3399-spdif";
+ reg = <0x0 0xff870000 0x0 0x1000>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac_bus 7>;
+ dma-names = "tx";
+ clock-names = "mclk", "hclk";
+ clocks = <&cru SCLK_SPDIF_8CH>, <&cru HCLK_SPDIF>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_bus>;
+ status = "disabled";
+ };
+
+ i2s0: i2s@ff880000 {
+ compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xff880000 0x0 0x1000>;
+ rockchip,grf = <&grf>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac_bus 0>, <&dmac_bus 1>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_clk", "i2s_hclk";
+ clocks = <&cru SCLK_I2S0_8CH>, <&cru HCLK_I2S0_8CH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_8ch_bus>;
+ status = "disabled";
+ };
+
+ i2s1: i2s@ff890000 {
+ compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xff890000 0x0 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac_bus 2>, <&dmac_bus 3>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_clk", "i2s_hclk";
+ clocks = <&cru SCLK_I2S1_8CH>, <&cru HCLK_I2S1_8CH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1_2ch_bus>;
+ status = "disabled";
+ };
+
+ i2s2: i2s@ff8a0000 {
+ compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
+ reg = <0x0 0xff8a0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac_bus 4>, <&dmac_bus 5>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_clk", "i2s_hclk";
+ clocks = <&cru SCLK_I2S2_8CH>, <&cru HCLK_I2S2_8CH>;
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3399-pinctrl";
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmugrf>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio0: gpio0@ff720000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff720000 0x0 0x100>;
+ clocks = <&pmucru PCLK_GPIO0_PMU>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <0x2>;
+
+ interrupt-controller;
+ #interrupt-cells = <0x2>;
+ };
+
+ gpio1: gpio1@ff730000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff730000 0x0 0x100>;
+ clocks = <&pmucru PCLK_GPIO1_PMU>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <0x2>;
+
+ interrupt-controller;
+ #interrupt-cells = <0x2>;
+ };
+
+ gpio2: gpio2@ff780000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff780000 0x0 0x100>;
+ clocks = <&cru PCLK_GPIO2>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <0x2>;
+
+ interrupt-controller;
+ #interrupt-cells = <0x2>;
+ };
+
+ gpio3: gpio3@ff788000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff788000 0x0 0x100>;
+ clocks = <&cru PCLK_GPIO3>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <0x2>;
+
+ interrupt-controller;
+ #interrupt-cells = <0x2>;
+ };
+
+ gpio4: gpio4@ff790000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x0 0xff790000 0x0 0x100>;
+ clocks = <&cru PCLK_GPIO4>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <0x2>;
+
+ interrupt-controller;
+ #interrupt-cells = <0x2>;
+ };
+
+ pcfg_pull_up: pcfg-pull-up {
+ bias-pull-up;
+ };
+
+ pcfg_pull_down: pcfg-pull-down {
+ bias-pull-down;
+ };
+
+ pcfg_pull_none: pcfg-pull-none {
+ bias-disable;
+ };
+
+ pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+ bias-disable;
+ drive-strength = <12>;
+ };
+
+ pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+ bias-pull-up;
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+ bias-pull-down;
+ drive-strength = <4>;
+ };
+
+ pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ pcfg_pull_down_12ma: pcfg-pull-down-12ma {
+ bias-pull-down;
+ drive-strength = <12>;
+ };
+
+ pcfg_pull_none_13ma: pcfg-pull-none-13ma {
+ bias-disable;
+ drive-strength = <13>;
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins =
+ <1 15 RK_FUNC_2 &pcfg_pull_none>,
+ <1 16 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins =
+ <4 2 RK_FUNC_1 &pcfg_pull_none>,
+ <4 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins =
+ <2 1 RK_FUNC_2 &pcfg_pull_none_12ma>,
+ <2 0 RK_FUNC_2 &pcfg_pull_none_12ma>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins =
+ <4 17 RK_FUNC_1 &pcfg_pull_none>,
+ <4 16 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c4 {
+ i2c4_xfer: i2c4-xfer {
+ rockchip,pins =
+ <1 12 RK_FUNC_1 &pcfg_pull_none>,
+ <1 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c5 {
+ i2c5_xfer: i2c5-xfer {
+ rockchip,pins =
+ <3 11 RK_FUNC_2 &pcfg_pull_none>,
+ <3 10 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c6 {
+ i2c6_xfer: i2c6-xfer {
+ rockchip,pins =
+ <2 10 RK_FUNC_2 &pcfg_pull_none>,
+ <2 9 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c7 {
+ i2c7_xfer: i2c7-xfer {
+ rockchip,pins =
+ <2 8 RK_FUNC_2 &pcfg_pull_none>,
+ <2 7 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c8 {
+ i2c8_xfer: i2c8-xfer {
+ rockchip,pins =
+ <1 21 RK_FUNC_1 &pcfg_pull_none>,
+ <1 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2s0 {
+ i2s0_8ch_bus: i2s0-8ch-bus {
+ rockchip,pins =
+ <3 24 RK_FUNC_1 &pcfg_pull_none>,
+ <3 25 RK_FUNC_1 &pcfg_pull_none>,
+ <3 26 RK_FUNC_1 &pcfg_pull_none>,
+ <3 27 RK_FUNC_1 &pcfg_pull_none>,
+ <3 28 RK_FUNC_1 &pcfg_pull_none>,
+ <3 29 RK_FUNC_1 &pcfg_pull_none>,
+ <3 30 RK_FUNC_1 &pcfg_pull_none>,
+ <3 31 RK_FUNC_1 &pcfg_pull_none>,
+ <4 0 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2s1 {
+ i2s1_2ch_bus: i2s1-2ch-bus {
+ rockchip,pins =
+ <4 3 RK_FUNC_1 &pcfg_pull_none>,
+ <4 4 RK_FUNC_1 &pcfg_pull_none>,
+ <4 5 RK_FUNC_1 &pcfg_pull_none>,
+ <4 6 RK_FUNC_1 &pcfg_pull_none>,
+ <4 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spdif {
+ spdif_bus: spdif-bus {
+ rockchip,pins =
+ <4 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0_clk: spi0-clk {
+ rockchip,pins =
+ <3 6 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs0: spi0-cs0 {
+ rockchip,pins =
+ <3 7 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs1: spi0-cs1 {
+ rockchip,pins =
+ <3 8 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_tx: spi0-tx {
+ rockchip,pins =
+ <3 5 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_rx: spi0-rx {
+ rockchip,pins =
+ <3 4 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ spi1 {
+ spi1_clk: spi1-clk {
+ rockchip,pins =
+ <1 9 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi1_cs0: spi1-cs0 {
+ rockchip,pins =
+ <1 10 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi1_rx: spi1-rx {
+ rockchip,pins =
+ <1 7 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi1_tx: spi1-tx {
+ rockchip,pins =
+ <1 8 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ spi2 {
+ spi2_clk: spi2-clk {
+ rockchip,pins =
+ <2 11 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi2_cs0: spi2-cs0 {
+ rockchip,pins =
+ <2 12 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi2_rx: spi2-rx {
+ rockchip,pins =
+ <2 9 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi2_tx: spi2-tx {
+ rockchip,pins =
+ <2 10 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ spi3 {
+ spi3_clk: spi3-clk {
+ rockchip,pins =
+ <1 17 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi3_cs0: spi3-cs0 {
+ rockchip,pins =
+ <1 18 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi3_rx: spi3-rx {
+ rockchip,pins =
+ <1 15 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi3_tx: spi3-tx {
+ rockchip,pins =
+ <1 16 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ spi4 {
+ spi4_clk: spi4-clk {
+ rockchip,pins =
+ <3 2 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi4_cs0: spi4-cs0 {
+ rockchip,pins =
+ <3 3 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi4_rx: spi4-rx {
+ rockchip,pins =
+ <3 0 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi4_tx: spi4-tx {
+ rockchip,pins =
+ <3 1 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ spi5 {
+ spi5_clk: spi5-clk {
+ rockchip,pins =
+ <2 22 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi5_cs0: spi5-cs0 {
+ rockchip,pins =
+ <2 23 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi5_rx: spi5-rx {
+ rockchip,pins =
+ <2 20 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi5_tx: spi5-tx {
+ rockchip,pins =
+ <2 21 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins =
+ <2 16 RK_FUNC_1 &pcfg_pull_up>,
+ <2 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins =
+ <2 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins =
+ <2 19 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins =
+ <3 12 RK_FUNC_2 &pcfg_pull_up>,
+ <3 13 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ uart2a {
+ uart2a_xfer: uart2a-xfer {
+ rockchip,pins =
+ <4 8 RK_FUNC_2 &pcfg_pull_up>,
+ <4 9 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ uart2b {
+ uart2b_xfer: uart2b-xfer {
+ rockchip,pins =
+ <4 16 RK_FUNC_2 &pcfg_pull_up>,
+ <4 17 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ uart2c {
+ uart2c_xfer: uart2c-xfer {
+ rockchip,pins =
+ <4 19 RK_FUNC_1 &pcfg_pull_up>,
+ <4 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart3 {
+ uart3_xfer: uart3-xfer {
+ rockchip,pins =
+ <3 14 RK_FUNC_2 &pcfg_pull_up>,
+ <3 15 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ uart3_cts: uart3-cts {
+ rockchip,pins =
+ <3 18 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ uart3_rts: uart3-rts {
+ rockchip,pins =
+ <3 19 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ uart4 {
+ uart4_xfer: uart4-xfer {
+ rockchip,pins =
+ <1 7 RK_FUNC_1 &pcfg_pull_up>,
+ <1 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uarthdcp {
+ uarthdcp_xfer: uarthdcp-xfer {
+ rockchip,pins =
+ <4 21 RK_FUNC_2 &pcfg_pull_up>,
+ <4 22 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins =
+ <4 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ vop0_pwm_pin: vop0-pwm-pin {
+ rockchip,pins =
+ <4 18 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins =
+ <4 22 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ vop1_pwm_pin: vop1-pwm-pin {
+ rockchip,pins =
+ <4 18 RK_FUNC_3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_pin: pwm2-pin {
+ rockchip,pins =
+ <1 19 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3a {
+ pwm3a_pin: pwm3a-pin {
+ rockchip,pins =
+ <0 6 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3b {
+ pwm3b_pin: pwm3b-pin {
+ rockchip,pins =
+ <1 14 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/sun50i-a64-pine64-plus.dts b/arch/arm/dts/sun50i-a64-pine64-plus.dts
index 549dc15bd5..389c6096ca 100644
--- a/arch/arm/dts/sun50i-a64-pine64-plus.dts
+++ b/arch/arm/dts/sun50i-a64-pine64-plus.dts
@@ -57,3 +57,16 @@
reg = <0x40000000 0x40000000>;
};
};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ phy-mode = "rgmii";
+ phy = <&phy1>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
diff --git a/arch/arm/dts/sun50i-a64.dtsi b/arch/arm/dts/sun50i-a64.dtsi
index 1bd436f847..7d0dc76a11 100644
--- a/arch/arm/dts/sun50i-a64.dtsi
+++ b/arch/arm/dts/sun50i-a64.dtsi
@@ -506,6 +506,25 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ rmii_pins: rmii_pins {
+ allwinner,pins = "PD10", "PD11", "PD13", "PD14",
+ "PD17", "PD18", "PD19", "PD20",
+ "PD22", "PD23";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ rgmii_pins: rgmii_pins {
+ allwinner,pins = "PD8", "PD9", "PD10", "PD11",
+ "PD12", "PD13", "PD15",
+ "PD16", "PD17", "PD18", "PD19",
+ "PD20", "PD21", "PD22", "PD23";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
ahb_rst: reset@1c202c0 {
@@ -620,5 +639,19 @@
#address-cells = <1>;
#size-cells = <0>;
};
+
+ emac: ethernet@01c30000 {
+ compatible = "allwinner,sun50i-a64-emac";
+ reg = <0x01c30000 0x2000>, <0x01c00030 0x4>;
+ reg-names = "emac", "syscon";
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&ahb_rst 17>;
+ reset-names = "ahb";
+ clocks = <&bus_gates 17>;
+ clock-names = "ahb";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
};
diff --git a/arch/arm/dts/sun5i-a10s.dtsi b/arch/arm/dts/sun5i-a10s.dtsi
index bddd0de88a..a5f8855389 100644
--- a/arch/arm/dts/sun5i-a10s.dtsi
+++ b/arch/arm/dts/sun5i-a10s.dtsi
@@ -241,6 +241,20 @@
allwinner,drive = <SUN4I_PINCTRL_30_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ nand_cs2_pins_a: nand_cs@2 {
+ allwinner,pins = "PC17";
+ allwinner,function = "nand0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ nand_cs3_pins_a: nand_cs@3 {
+ allwinner,pins = "PC18";
+ allwinner,function = "nand0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
};
&sram_a {
diff --git a/arch/arm/dts/sun5i-a13-olinuxino.dts b/arch/arm/dts/sun5i-a13-olinuxino.dts
index b3c234c65e..30e069a6cf 100644
--- a/arch/arm/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/dts/sun5i-a13-olinuxino.dts
@@ -155,6 +155,21 @@
status = "okay";
};
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+ status = "okay";
+
+ nand@0 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ reg = <0>;
+ allwinner,rb = <0>;
+ nand-ecc-mode = "hw";
+ allwinner,randomize;
+ };
+};
+
&ohci0 {
status = "okay";
};
diff --git a/arch/arm/dts/sun5i-r8-chip.dts b/arch/arm/dts/sun5i-r8-chip.dts
index 6ad19e272f..b1b62d5116 100644
--- a/arch/arm/dts/sun5i-r8-chip.dts
+++ b/arch/arm/dts/sun5i-r8-chip.dts
@@ -142,6 +142,21 @@
status = "okay";
};
+&nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+ status = "okay";
+
+ nand@0 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ reg = <0>;
+ allwinner,rb = <0>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+ };
+};
+
&ohci0 {
status = "okay";
};
diff --git a/arch/arm/dts/sun5i.dtsi b/arch/arm/dts/sun5i.dtsi
index 59a9426e3b..87e535301a 100644
--- a/arch/arm/dts/sun5i.dtsi
+++ b/arch/arm/dts/sun5i.dtsi
@@ -356,6 +356,17 @@
#dma-cells = <2>;
};
+ nfc: nand@01c03000 {
+ compatible = "allwinner,sun4i-a10-nand";
+ reg = <0x01c03000 0x1000>;
+ interrupts = <37>;
+ clocks = <&ahb_gates 13>, <&nand_clk>;
+ clock-names = "ahb", "mod";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
spi0: spi@01c05000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c05000 0x1000>;
@@ -548,6 +559,44 @@
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
+ nand_pins_a: nand_base0@0 {
+ allwinner,pins = "PC0", "PC1", "PC2",
+ "PC5", "PC8", "PC9", "PC10",
+ "PC11", "PC12", "PC13", "PC14",
+ "PC15";
+ allwinner,function = "nand0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ nand_cs0_pins_a: nand_cs@0 {
+ allwinner,pins = "PC4";
+ allwinner,function = "nand0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ nand_cs1_pins_a: nand_cs@1 {
+ allwinner,pins = "PC3";
+ allwinner,function = "nand0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ nand_rb0_pins_a: nand_rb@0 {
+ allwinner,pins = "PC6";
+ allwinner,function = "nand0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ nand_rb1_pins_a: nand_rb@1 {
+ allwinner,pins = "PC7";
+ allwinner,function = "nand0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
uart3_pins_a: uart3@0 {
allwinner,pins = "PG9", "PG10";
allwinner,function = "uart3";
diff --git a/arch/arm/dts/sun8i-h3-orangepi-2.dts b/arch/arm/dts/sun8i-h3-orangepi-2.dts
index f93f5d1695..d3f8f550a2 100644
--- a/arch/arm/dts/sun8i-h3-orangepi-2.dts
+++ b/arch/arm/dts/sun8i-h3-orangepi-2.dts
@@ -184,3 +184,16 @@
usb1_vbus-supply = <&reg_usb1_vbus>;
status = "okay";
};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ phy-mode = "rgmii";
+ phy = <&phy1>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
diff --git a/arch/arm/dts/sun8i-h3-orangepi-lite.dts b/arch/arm/dts/sun8i-h3-orangepi-lite.dts
new file mode 100644
index 0000000000..ac7174914e
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-orangepi-lite.dts
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2016 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Xunlong Orange Pi Lite";
+ compatible = "xunlong,orangepi-lite", "allwinner,sun8i-h3";
+
+ aliases {
+ /* The H3 emac is not used so the wifi is ethernet0 */
+ ethernet1 = &rtl8189ftv;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_opc>, <&leds_r_opc>;
+
+ pwr_led {
+ label = "orangepi:green:pwr";
+ gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ status_led {
+ label = "orangepi:red:status";
+ gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ r_gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sw_r_opc>;
+
+ sw4 {
+ label = "sw4";
+ linux,code = <BTN_0>;
+ gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ehci2 {
+ status = "okay";
+};
+
+&ir {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ /*
+ * Explicitly define the sdio device, so that we can add an ethernet
+ * alias for it (which e.g. makes u-boot set a mac-address).
+ */
+ rtl8189ftv: sdio_wifi@1 {
+ reg = <1>;
+ };
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&ohci2 {
+ status = "okay";
+};
+
+&pio {
+ leds_opc: led_pins@0 {
+ allwinner,pins = "PA15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&r_pio {
+ leds_r_opc: led_pins@0 {
+ allwinner,pins = "PL10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ sw_r_opc: key_pins@0 {
+ allwinner,pins = "PL3";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ /* USB VBUS is always on */
+ status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-h3-orangepi-pc-plus.dts b/arch/arm/dts/sun8i-h3-orangepi-pc-plus.dts
new file mode 100644
index 0000000000..9a8cdd46e7
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-orangepi-pc-plus.dts
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* The Orange Pi PC Plus is an extended version of the regular PC */
+#include "sun8i-h3-orangepi-pc.dts"
+
+/ {
+ model = "Xunlong Orange Pi PC / PC Plus";
+
+ aliases {
+ /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
+ ethernet1 = &rtl8189ftv;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ /*
+ * Explicitly define the sdio device, so that we can add an ethernet
+ * alias for it (which e.g. makes u-boot set a mac-address).
+ */
+ rtl8189ftv: sdio_wifi@1 {
+ reg = <1>;
+ };
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_8bit_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <8>;
+ non-removable;
+ cap-mmc-hw-reset;
+ status = "okay";
+};
+
+&mmc2_8bit_pins {
+ /* Increase drive strength for DDR modes */
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ /* eMMC is missing pull-ups */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
diff --git a/arch/arm/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/dts/sun8i-h3-orangepi-pc.dts
index 30ccca019d..0a74a9193b 100644
--- a/arch/arm/dts/sun8i-h3-orangepi-pc.dts
+++ b/arch/arm/dts/sun8i-h3-orangepi-pc.dts
@@ -173,3 +173,15 @@
/* USB VBUS is always on */
status = "okay";
};
+
+&emac {
+ phy = <&phy1>;
+ phy-mode = "mii";
+ allwinner,use-internal-phy;
+ allwinner,leds-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
diff --git a/arch/arm/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/dts/sun8i-h3-orangepi-plus.dts
index 900ec4fc8c..28f74f6ffd 100644
--- a/arch/arm/dts/sun8i-h3-orangepi-plus.dts
+++ b/arch/arm/dts/sun8i-h3-orangepi-plus.dts
@@ -40,26 +40,13 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/dts-v1/;
-#include "sun8i-h3.dtsi"
-#include "sunxi-common-regulators.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/pinctrl/sun4i-a10.h>
+/* The Orange Pi Plus is an extended version of the Orange Pi 2 */
+#include "sun8i-h3-orangepi-2.dts"
/ {
- model = "Xunlong Orange Pi Plus";
+ model = "Xunlong Orange Pi Plus / Plus 2 / Plus 2E";
compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3";
- aliases {
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
reg_usb3_vbus: usb3-vbus {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -71,75 +58,42 @@
enable-active-high;
gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>;
};
+};
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&leds_opc>;
-
- status_led {
- label = "status:red:user";
- gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>;
- };
- };
-
- r_leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&leds_r_opc>;
-
- tx {
- label = "pwr:green:user";
- gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
- };
-
- r_gpio_keys {
- compatible = "gpio-keys";
- input-name = "sw4";
-
- pinctrl-names = "default";
- pinctrl-0 = <&sw_r_opc>;
+&ehci2 {
+ status = "okay";
+};
- sw4@0 {
- label = "sw4";
- linux,code = <BTN_0>;
- gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
- };
- };
+&ehci3 {
+ status = "okay";
};
-&pio {
- leds_opc: led_pins@0 {
- allwinner,pins = "PA15";
- allwinner,function = "gpio_out";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_8bit_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <8>;
+ non-removable;
+ cap-mmc-hw-reset;
+ status = "okay";
};
-&r_pio {
- leds_r_opc: led_pins@0 {
- allwinner,pins = "PL10";
- allwinner,function = "gpio_out";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
+&mmc2_8bit_pins {
+ /* Increase drive strength for DDR modes */
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ /* eMMC is missing pull-ups */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
- sw_r_opc: key_pins@0 {
- allwinner,pins = "PL03";
- allwinner,function = "gpio_in";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
+&ohci1 {
+ status = "okay";
};
-&ehci1 {
+&ohci2 {
status = "okay";
};
-&ehci3 {
+&ohci3 {
status = "okay";
};
@@ -152,33 +106,6 @@
};
};
-&mmc0 {
- pinctrl-names = "default";
- pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
- vmmc-supply = <&reg_vcc3v3>;
- bus-width = <4>;
- cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
- cd-inverted;
- status = "okay";
-};
-
-&reg_usb1_vbus {
- gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
- status = "okay";
-};
-
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins_a>;
- status = "okay";
-};
-
-&usb1_vbus_pin_a {
- allwinner,pins = "PG13";
-};
-
&usbphy {
- usb1_vbus-supply = <&reg_usb1_vbus>;
usb3_vbus-supply = <&reg_usb3_vbus>;
- status = "okay";
};
diff --git a/arch/arm/dts/sun8i-h3.dtsi b/arch/arm/dts/sun8i-h3.dtsi
index c2f63c5050..84e52b9cdb 100644
--- a/arch/arm/dts/sun8i-h3.dtsi
+++ b/arch/arm/dts/sun8i-h3.dtsi
@@ -48,6 +48,10 @@
/ {
interrupt-parent = <&gic>;
+ aliases {
+ ethernet0 = <&emac>;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -501,6 +505,17 @@
interrupt-controller;
#interrupt-cells = <3>;
+ rgmii_pins: rgmii_pins {
+ allwinner,pins = "PD0", "PD1", "PD2", "PD3",
+ "PD4", "PD5", "PD7",
+ "PD8", "PD9", "PD10",
+ "PD12", "PD13", "PD15",
+ "PD16", "PD17";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
uart0_pins_a: uart0@0 {
allwinner,pins = "PA4", "PA5";
allwinner,function = "uart0";
@@ -530,6 +545,16 @@
allwinner,drive = <SUN4I_PINCTRL_30_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ mmc2_8bit_pins: mmc2_8bit {
+ allwinner,pins = "PC5", "PC6", "PC8",
+ "PC9", "PC10", "PC11",
+ "PC12", "PC13", "PC14",
+ "PC15", "PC16";
+ allwinner,function = "mmc2";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
ahb_rst: reset@01c202c0 {
@@ -616,6 +641,20 @@
status = "disabled";
};
+ emac: ethernet@01c30000 {
+ compatible = "allwinner,sun8i-h3-emac";
+ reg = <0x01c30000 0x2000>, <0x01c00030 0x4>;
+ reg-names = "emac", "syscon";
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&ahb_rst 17>, <&ahb_rst 66>;
+ reset-names = "ahb", "ephy";
+ clocks = <&bus_gates 17>, <&bus_gates 128>;
+ clock-names = "ahb", "ephy";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@01c81000 {
compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
reg = <0x01c81000 0x1000>,
diff --git a/arch/arm/dts/tegra186-p2771-0000-a02.dts b/arch/arm/dts/tegra186-p2771-0000-a02.dts
new file mode 100644
index 0000000000..70f4326c09
--- /dev/null
+++ b/arch/arm/dts/tegra186-p2771-0000-a02.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "tegra186-p2771-0000.dtsi"
+
+/ {
+ model = "NVIDIA P2771-0000 A02";
+ compatible = "nvidia,p2771-0000-a02", "nvidia,p2771-0000", "nvidia,tegra186";
+};
diff --git a/arch/arm/dts/tegra186-p2771-0000-b00.dts b/arch/arm/dts/tegra186-p2771-0000-b00.dts
new file mode 100644
index 0000000000..2384a65e87
--- /dev/null
+++ b/arch/arm/dts/tegra186-p2771-0000-b00.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "tegra186-p2771-0000.dtsi"
+
+/ {
+ model = "NVIDIA P2771-0000 B00";
+ compatible = "nvidia,p2771-0000-b00", "nvidia,p2771-0000", "nvidia,tegra186";
+};
diff --git a/arch/arm/dts/tegra186-p2771-0000.dts b/arch/arm/dts/tegra186-p2771-0000.dtsi
index 5f29ee4501..87f0427e80 100644
--- a/arch/arm/dts/tegra186-p2771-0000.dts
+++ b/arch/arm/dts/tegra186-p2771-0000.dtsi
@@ -1,5 +1,3 @@
-/dts-v1/;
-
#include "tegra186.dtsi"
/ {
diff --git a/arch/arm/dts/tegra186.dtsi b/arch/arm/dts/tegra186.dtsi
index fce34fa650..99d49254b3 100644
--- a/arch/arm/dts/tegra186.dtsi
+++ b/arch/arm/dts/tegra186.dtsi
@@ -1,5 +1,5 @@
#include "skeleton.dtsi"
-#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/gpio/tegra186-gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/tegra-hsp.h>
diff --git a/arch/arm/dts/uniphier-proxstream2-gentil.dts b/arch/arm/dts/uniphier-proxstream2-gentil.dts
index 61f61641af..117570352f 100644
--- a/arch/arm/dts/uniphier-proxstream2-gentil.dts
+++ b/arch/arm/dts/uniphier-proxstream2-gentil.dts
@@ -19,13 +19,13 @@
};
chosen {
- stdout-path = "serial2:115200n8";
+ stdout-path = "serial0:115200n8";
};
aliases {
- serial0 = &serial0;
- serial1 = &serial1;
- serial2 = &serial2;
+ serial0 = &serial2;
+ serial1 = &serial0;
+ serial2 = &serial1;
i2c0 = &i2c0;
i2c2 = &i2c2;
i2c4 = &i2c4;
diff --git a/arch/arm/dts/uniphier-proxstream2-vodka.dts b/arch/arm/dts/uniphier-proxstream2-vodka.dts
index 3d5b300716..928a0928fd 100644
--- a/arch/arm/dts/uniphier-proxstream2-vodka.dts
+++ b/arch/arm/dts/uniphier-proxstream2-vodka.dts
@@ -19,13 +19,13 @@
};
chosen {
- stdout-path = "serial2:115200n8";
+ stdout-path = "serial0:115200n8";
};
aliases {
- serial0 = &serial0;
- serial1 = &serial1;
- serial2 = &serial2;
+ serial0 = &serial2;
+ serial1 = &serial0;
+ serial2 = &serial1;
i2c0 = &i2c0;
i2c4 = &i2c4;
i2c5 = &i2c5;
diff --git a/arch/arm/imx-common/ddrmc-vf610.c b/arch/arm/imx-common/ddrmc-vf610.c
index daf3c7ebfa..9bc56f6ac1 100644
--- a/arch/arm/imx-common/ddrmc-vf610.c
+++ b/arch/arm/imx-common/ddrmc-vf610.c
@@ -212,7 +212,7 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
cr_setting++;
}
- /* perform default PHY settings (may be overriden by custom settings */
+ /* perform default PHY settings (may be overridden by custom settings */
phy_setting = default_phy_settings;
while (phy_setting->phy_rnum >= 0) {
writel(phy_setting->setting,
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index 8f573d2d02..ed1a46c2e7 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -25,9 +25,8 @@ void ddr_pll_config(unsigned int ddrpll_M);
void sdelay(unsigned long);
-struct gpmc_cs;
void gpmc_init(void);
-void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs, u32 base,
u32 size);
void omap_nand_switch_ecc(uint32_t, uint32_t);
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h
index 44fe0c0095..b0ad4b4626 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/config.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h
@@ -149,43 +149,43 @@
#define CONFIG_ARM_ERRATA_833471
#define CONFIG_SYS_FSL_MAX_NUM_OF_SEC 1
-#elif defined(CONFIG_LS1043A)
-#define CONFIG_MAX_CPUS 4
+#elif defined(CONFIG_FSL_LSCH2)
#define CONFIG_SYS_CACHELINE_SIZE 64
-#define CONFIG_SYS_FMAN_V3
-#define CONFIG_SYS_NUM_FMAN 1
-#define CONFIG_SYS_NUM_FM1_DTSEC 7
-#define CONFIG_SYS_NUM_FM1_10GEC 1
-#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
#define CONFIG_NUM_DDR_CONTROLLERS 1
-#define CONFIG_SYS_CCSRBAR_DEFAULT 0x01000000
#define CONFIG_SYS_FSL_SEC_COMPAT 5
#define CONFIG_SYS_FSL_OCRAM_BASE 0x10000000 /* initial RAM */
-#define CONFIG_SYS_FSL_OCRAM_SIZE 0x200000 /* 2 MiB */
-#define CONFIG_SYS_FSL_DDR_BE
-#define CONFIG_SYS_DDR_BLOCK1_SIZE ((phys_size_t)2 << 30)
-#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_DDR_BLOCK1_SIZE
+#define CONFIG_SYS_FSL_OCRAM_SIZE 0x00200000 /* 2M */
+#define CONFIG_SYS_CCSRBAR_DEFAULT 0x01000000
-#define CONFIG_SYS_FSL_CCSR_GUR_BE
#define CONFIG_SYS_FSL_CCSR_SCFG_BE
-#define CONFIG_SYS_FSL_IFC_BE
#define CONFIG_SYS_FSL_ESDHC_BE
#define CONFIG_SYS_FSL_WDOG_BE
#define CONFIG_SYS_FSL_DSPI_BE
#define CONFIG_SYS_FSL_QSPI_BE
+#define CONFIG_SYS_FSL_CCSR_GUR_BE
#define CONFIG_SYS_FSL_PEX_LUT_BE
+#define CONFIG_SYS_FSL_SEC_BE
+
+#define CONFIG_SYS_FSL_SRDS_1
+/* SoC related */
+#ifdef CONFIG_LS1043A
+#define CONFIG_MAX_CPUS 4
+#define CONFIG_SYS_FMAN_V3
+#define CONFIG_SYS_NUM_FMAN 1
+#define CONFIG_SYS_NUM_FM1_DTSEC 7
+#define CONFIG_SYS_NUM_FM1_10GEC 1
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
+#define CONFIG_SYS_FSL_DDR_BE
+#define CONFIG_SYS_DDR_BLOCK1_SIZE ((phys_size_t)2 << 30)
+#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_DDR_BLOCK1_SIZE
#define QE_MURAM_SIZE 0x6000UL
#define MAX_QE_RISC 1
#define QE_NUM_OF_SNUM 28
-#define SRDS_MAX_LANES 4
-#define CONFIG_SYS_FSL_SRDS_1
-#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4"
-
+#define CONFIG_SYS_FSL_IFC_BE
#define CONFIG_SYS_FSL_SFP_VER_3_2
#define CONFIG_SYS_FSL_SEC_MON_BE
-#define CONFIG_SYS_FSL_SEC_BE
#define CONFIG_SYS_FSL_SFP_BE
#define CONFIG_SYS_FSL_SRK_LE
#define CONFIG_KEY_REVOCATION
@@ -205,32 +205,40 @@
#define CONFIG_SYS_FSL_MAX_NUM_OF_SEC 1
#elif defined(CONFIG_LS1012A)
#define CONFIG_MAX_CPUS 1
-#define CONFIG_SYS_CACHELINE_SIZE 64
-#define CONFIG_NUM_DDR_CONTROLLERS 1
-#define CONFIG_SYS_CCSRBAR_DEFAULT 0x01000000
-#define CONFIG_SYS_FSL_SEC_COMPAT 5
#undef CONFIG_SYS_FSL_DDRC_ARM_GEN3
-#define CONFIG_SYS_FSL_OCRAM_BASE 0x10000000 /* initial RAM */
-#define CONFIG_SYS_FSL_OCRAM_SIZE 0x200000 /* 2 MiB */
-
#define GICD_BASE 0x01401000
#define GICC_BASE 0x01402000
+#elif defined(CONFIG_LS1046A)
+#define CONFIG_MAX_CPUS 4
+#define CONFIG_SYS_FMAN_V3
+#define CONFIG_SYS_NUM_FMAN 1
+#define CONFIG_SYS_NUM_FM1_DTSEC 8
+#define CONFIG_SYS_NUM_FM1_10GEC 2
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
+#define CONFIG_SYS_FSL_DDR_BE
+#define CONFIG_SYS_DDR_BLOCK1_SIZE ((phys_size_t)2 << 30)
+#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_DDR_BLOCK1_SIZE
-#define CONFIG_SYS_FSL_CCSR_GUR_BE
-#define CONFIG_SYS_FSL_CCSR_SCFG_BE
-#define CONFIG_SYS_FSL_ESDHC_BE
-#define CONFIG_SYS_FSL_WDOG_BE
-#define CONFIG_SYS_FSL_DSPI_BE
-#define CONFIG_SYS_FSL_QSPI_BE
-#define CONFIG_SYS_FSL_PEX_LUT_BE
+#define CONFIG_SYS_FSL_SRDS_2
+#define CONFIG_SYS_FSL_IFC_BE
+#define CONFIG_SYS_FSL_SFP_VER_3_2
+#define CONFIG_SYS_FSL_SNVS_LE
+#define CONFIG_SYS_FSL_SFP_BE
+#define CONFIG_SYS_FSL_SRK_LE
+#define CONFIG_KEY_REVOCATION
-#define SRDS_MAX_LANES 4
-#define CONFIG_SYS_FSL_SRDS_1
-#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4"
-#define CONFIG_SYS_FSL_SEC_BE
+/* SMMU Defintions */
+#define SMMU_BASE 0x09000000
+
+/* Generic Interrupt Controller Definitions */
+#define GICD_BASE 0x01410000
+#define GICC_BASE 0x01420000
+
+#define CONFIG_SYS_FSL_MAX_NUM_OF_SEC 1
#else
#error SoC not defined
#endif
+#endif
#endif /* _ASM_ARMV8_FSL_LAYERSCAPE_CONFIG_H_ */
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
index 197b0eb5a5..e2d96a1b78 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
@@ -13,35 +13,14 @@ static struct cpu_type cpu_type_list[] = {
CPU_TYPE_ENTRY(LS2045A, LS2045A, 4),
CPU_TYPE_ENTRY(LS1043A, LS1043A, 4),
CPU_TYPE_ENTRY(LS1023A, LS1023A, 2),
+ CPU_TYPE_ENTRY(LS1046A, LS1046A, 4),
+ CPU_TYPE_ENTRY(LS1026A, LS1026A, 2),
CPU_TYPE_ENTRY(LS2040A, LS2040A, 4),
CPU_TYPE_ENTRY(LS1012A, LS1012A, 1),
};
#ifndef CONFIG_SYS_DCACHE_OFF
-#define SECTION_SHIFT_L0 39UL
-#define SECTION_SHIFT_L1 30UL
-#define SECTION_SHIFT_L2 21UL
-#define BLOCK_SIZE_L0 0x8000000000
-#define BLOCK_SIZE_L1 0x40000000
-#define BLOCK_SIZE_L2 0x200000
-#define NUM_OF_ENTRY 512
-#define TCR_EL2_PS_40BIT (2 << 16)
-
-#define LAYERSCAPE_VA_BITS (40)
-#define LAYERSCAPE_TCR (TCR_TG0_4K | \
- TCR_EL2_PS_40BIT | \
- TCR_SHARED_NON | \
- TCR_ORGN_NC | \
- TCR_IRGN_NC | \
- TCR_T0SZ(LAYERSCAPE_VA_BITS))
-#define LAYERSCAPE_TCR_FINAL (TCR_TG0_4K | \
- TCR_EL2_PS_40BIT | \
- TCR_SHARED_OUTER | \
- TCR_ORGN_WBWA | \
- TCR_IRGN_WBWA | \
- TCR_T0SZ(LAYERSCAPE_VA_BITS))
-
#ifdef CONFIG_FSL_LSCH3
#define CONFIG_SYS_FSL_CCSR_BASE 0x00000000
#define CONFIG_SYS_FSL_CCSR_SIZE 0x10000000
@@ -101,174 +80,261 @@ static struct cpu_type cpu_type_list[] = {
#define CONFIG_SYS_FSL_DRAM_SIZE3 0x7800000000 /* 480GB */
#endif
-struct sys_mmu_table {
- u64 virt_addr;
- u64 phys_addr;
- u64 size;
- u64 memory_type;
- u64 attribute;
-};
-
-struct table_info {
- u64 *ptr;
- u64 table_base;
- u64 entry_size;
-};
-
-static const struct sys_mmu_table early_mmu_table[] = {
+#define EARLY_PGTABLE_SIZE 0x5000
+static struct mm_region early_map[] = {
#ifdef CONFIG_FSL_LSCH3
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1,
- CONFIG_SYS_FSL_QSPI_SIZE1, MT_NORMAL, PTE_BLOCK_NON_SHARE},
+ CONFIG_SYS_FSL_QSPI_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE},
/* For IFC Region #1, only the first 4MB is cache-enabled */
{ CONFIG_SYS_FSL_IFC_BASE1, CONFIG_SYS_FSL_IFC_BASE1,
- CONFIG_SYS_FSL_IFC_SIZE1_1, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE1_1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1,
CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1,
CONFIG_SYS_FSL_IFC_SIZE1 - CONFIG_SYS_FSL_IFC_SIZE1_1,
- MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FSL_IFC_BASE1,
- CONFIG_SYS_FSL_IFC_SIZE1, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
/* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */
{ CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2,
CONFIG_SYS_FLASH_BASE - CONFIG_SYS_FSL_IFC_BASE2,
- MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#elif defined(CONFIG_FSL_LSCH2)
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE,
- CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_QSPI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
- CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#endif
+ {}, /* list terminator */
};
-static const struct sys_mmu_table final_mmu_table[] = {
+static struct mm_region final_map[] = {
#ifdef CONFIG_FSL_LSCH3
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1,
- CONFIG_SYS_FSL_QSPI_SIZE1, MT_NORMAL, PTE_BLOCK_NON_SHARE},
+ CONFIG_SYS_FSL_QSPI_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_BASE2,
- CONFIG_SYS_FSL_QSPI_SIZE2, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_QSPI_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2,
- CONFIG_SYS_FSL_IFC_SIZE2, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_MC_BASE, CONFIG_SYS_FSL_MC_BASE,
- CONFIG_SYS_FSL_MC_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_MC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_NI_BASE, CONFIG_SYS_FSL_NI_BASE,
- CONFIG_SYS_FSL_NI_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_NI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
/* For QBMAN portal, only the first 64MB is cache-enabled */
{ CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE,
- CONFIG_SYS_FSL_QBMAN_SIZE_1, MT_NORMAL,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_QBMAN_SIZE_1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1,
CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1,
CONFIG_SYS_FSL_QBMAN_SIZE - CONFIG_SYS_FSL_QBMAN_SIZE_1,
- MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR,
- CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE1_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR,
- CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE2_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR,
- CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE3_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
#ifdef CONFIG_LS2080A
{ CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_ADDR,
- CONFIG_SYS_PCIE4_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE4_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
#endif
{ CONFIG_SYS_FSL_WRIOP1_BASE, CONFIG_SYS_FSL_WRIOP1_BASE,
- CONFIG_SYS_FSL_WRIOP1_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_WRIOP1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_AIOP1_BASE, CONFIG_SYS_FSL_AIOP1_BASE,
- CONFIG_SYS_FSL_AIOP1_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_AIOP1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_PEBUF_BASE, CONFIG_SYS_FSL_PEBUF_BASE,
- CONFIG_SYS_FSL_PEBUF_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_PEBUF_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#elif defined(CONFIG_FSL_LSCH2)
{ CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_BASE,
- CONFIG_SYS_FSL_BOOTROM_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_BOOTROM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE,
- CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_QSPI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
- CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE,
- CONFIG_SYS_FSL_QBMAN_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_QBMAN_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR,
- CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE1_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR,
- CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE2_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR,
- CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE3_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE3, CONFIG_SYS_FSL_DRAM_BASE3,
- CONFIG_SYS_FSL_DRAM_SIZE3, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE3,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#endif
-};
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ {}, /* space holder for secure mem */
#endif
+ {},
+};
+#endif /* !CONFIG_SYS_DCACHE_OFF */
int fsl_qoriq_core_to_cluster(unsigned int core);
u32 cpu_mask(void);
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
index 487cba8080..e1b3f44d85 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
@@ -140,6 +140,7 @@ enum srds_prtcl {
enum srds {
FSL_SRDS_1 = 0,
+ FSL_SRDS_2 = 1,
};
#endif
@@ -150,7 +151,7 @@ int serdes_get_first_lane(u32 sd, enum srds_prtcl device);
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane);
int is_serdes_prtcl_valid(int serdes, u32 prtcl);
-#ifdef CONFIG_LS1043A
+#ifdef CONFIG_FSL_LSCH2
const char *serdes_clock_to_string(u32 clock);
int get_serdes_protocol(void);
#endif
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
index 8b8a7c15bd..95a42935ca 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
@@ -31,9 +31,9 @@
#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011c0600)
#define CONFIG_SYS_NS16550_COM3 (CONFIG_SYS_IMMR + 0x011d0500)
#define CONFIG_SYS_NS16550_COM4 (CONFIG_SYS_IMMR + 0x011d0600)
-#define CONFIG_SYS_LS1043A_XHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x01f00000)
-#define CONFIG_SYS_LS1043A_XHCI_USB2_ADDR (CONFIG_SYS_IMMR + 0x02000000)
-#define CONFIG_SYS_LS1043A_XHCI_USB3_ADDR (CONFIG_SYS_IMMR + 0x02100000)
+#define CONFIG_SYS_XHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x01f00000)
+#define CONFIG_SYS_XHCI_USB2_ADDR (CONFIG_SYS_IMMR + 0x02000000)
+#define CONFIG_SYS_XHCI_USB3_ADDR (CONFIG_SYS_IMMR + 0x02100000)
#define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_IMMR + 0x2400000)
#define CONFIG_SYS_PCIE2_ADDR (CONFIG_SYS_IMMR + 0x2500000)
#define CONFIG_SYS_PCIE3_ADDR (CONFIG_SYS_IMMR + 0x2600000)
@@ -94,6 +94,7 @@
#define TY_ITYP_VER_A7 0x1
#define TY_ITYP_VER_A53 0x2
#define TY_ITYP_VER_A57 0x3
+#define TY_ITYP_VER_A72 0x4
#define TP_CLUSTER_EOC 0xc0000000 /* end of clusters */
#define TP_CLUSTER_INIT_MASK 0x0000003f /* initiator mask */
@@ -227,6 +228,8 @@ struct ccsr_gur {
#define FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK 0x3f
#define FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK 0xffff0000
#define FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT 16
+#define FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK 0x0000ffff
+#define FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT 0
#define RCW_SB_EN_REG_INDEX 7
#define RCW_SB_EN_MASK 0x00200000
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
index 3ad46eb371..93e26c1d7f 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
@@ -52,8 +52,8 @@
#define I2C3_BASE_ADDR (CONFIG_SYS_IMMR + 0x01020000)
#define I2C4_BASE_ADDR (CONFIG_SYS_IMMR + 0x01030000)
-#define CONFIG_SYS_LS2080A_XHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x02100000)
-#define CONFIG_SYS_LS2080A_XHCI_USB2_ADDR (CONFIG_SYS_IMMR + 0x02110000)
+#define CONFIG_SYS_XHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x02100000)
+#define CONFIG_SYS_XHCI_USB2_ADDR (CONFIG_SYS_IMMR + 0x02110000)
/* TZ Address Space Controller Definitions */
#define TZASC1_BASE 0x01100000 /* as per CCSR map. */
@@ -156,6 +156,7 @@
#define TY_ITYP_VER_A7 0x1
#define TY_ITYP_VER_A53 0x2
#define TY_ITYP_VER_A57 0x3
+#define TY_ITYP_VER_A72 0x4
#define TP_CLUSTER_EOC 0x80000000 /* end of clusters */
#define TP_CLUSTER_INIT_MASK 0x0000003f /* initiator mask */
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/ppa.h b/arch/arm/include/asm/arch-fsl-layerscape/ppa.h
new file mode 100644
index 0000000000..1f1442b6f0
--- /dev/null
+++ b/arch/arm/include/asm/arch-fsl-layerscape/ppa.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __FSL_PPA_H_
+#define __FSL_PPA_H_
+
+#define SEC_FIRMWARE_FIT_IMAGE "firmware"
+#define SEC_FIRMEWARE_FIT_CNF_NAME "config@1"
+#define SEC_FIRMWARE_TARGET_EL 2
+
+int ppa_init(void);
+
+#endif
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
index 39e8c7a17c..8d4a7adb1d 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
@@ -44,6 +44,8 @@ struct cpu_type {
#define SVR_LS1012A 0x870400
#define SVR_LS1043A 0x879200
#define SVR_LS1023A 0x879208
+#define SVR_LS1046A 0x870700
+#define SVR_LS1026A 0x870708
#define SVR_LS2045A 0x870120
#define SVR_LS2080A 0x870110
#define SVR_LS2085A 0x870100
diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h
index 04abec467c..d408fe4056 100644
--- a/arch/arm/include/asm/arch-ls102xa/config.h
+++ b/arch/arm/include/asm/arch-ls102xa/config.h
@@ -10,7 +10,7 @@
#define CONFIG_SYS_CACHELINE_SIZE 64
#define OCRAM_BASE_ADDR 0x10000000
-#define OCRAM_SIZE 0x00020000
+#define OCRAM_SIZE 0x00010000
#define OCRAM_BASE_S_ADDR 0x10010000
#define OCRAM_S_SIZE 0x00010000
@@ -32,16 +32,15 @@
#define CONFIG_SYS_FSL_SERDES_ADDR (CONFIG_SYS_IMMR + 0x00ea0000)
#define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00ee0000)
#define CONFIG_SYS_FSL_LS1_CLK_ADDR (CONFIG_SYS_IMMR + 0x00ee1000)
+#define CONFIG_SYS_FSL_RCPM_ADDR (CONFIG_SYS_IMMR + 0x00ee2000)
#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011c0500)
#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011d0500)
#define CONFIG_SYS_DCU_ADDR (CONFIG_SYS_IMMR + 0x01ce0000)
-#define CONFIG_SYS_LS102XA_XHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x02100000)
-#define CONFIG_SYS_LS102XA_USB1_ADDR \
- (CONFIG_SYS_IMMR + CONFIG_SYS_LS102XA_USB1_OFFSET)
+#define CONFIG_SYS_XHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x02100000)
+#define CONFIG_SYS_EHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x07600000)
#define CONFIG_SYS_FSL_SEC_OFFSET 0x00700000
#define CONFIG_SYS_FSL_JR0_OFFSET 0x00710000
-#define CONFIG_SYS_LS102XA_USB1_OFFSET 0x07600000
#define CONFIG_SYS_TSEC1_OFFSET 0x01d10000
#define CONFIG_SYS_TSEC2_OFFSET 0x01d50000
#define CONFIG_SYS_TSEC3_OFFSET 0x01d90000
diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h
index 24563c08e4..5979340ac8 100644
--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
@@ -40,11 +40,12 @@ void sdrc_init(void);
void do_sdrc_init(u32, u32);
void get_board_mem_timings(struct board_sdrc_timings *timings);
-void identify_nand_chip(int *mfr, int *id);
+int identify_nand_chip(int *mfr, int *id);
void emif4_init(void);
void gpmc_init(void);
-void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
- u32 size);
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs,
+ u32 base, u32 size);
+void set_gpmc_cs0(int flash_type);
void watchdog_init(void);
void set_muxconf_regs(void);
diff --git a/arch/arm/include/asm/arch-omap4/i2c.h b/arch/arm/include/asm/arch-omap4/i2c.h
index adc8eb23ff..463e979758 100644
--- a/arch/arm/include/asm/arch-omap4/i2c.h
+++ b/arch/arm/include/asm/arch-omap4/i2c.h
@@ -14,9 +14,9 @@ struct i2c {
unsigned short revnb_lo; /* 0x00 */
unsigned short res1;
unsigned short revnb_hi; /* 0x04 */
- unsigned short res2[13];
- unsigned short sysc; /* 0x20 */
- unsigned short res3;
+ unsigned short res2[5];
+ unsigned short sysc; /* 0x10 */
+ unsigned short res3[9];
unsigned short irqstatus_raw; /* 0x24 */
unsigned short res4;
unsigned short stat; /* 0x28 */
diff --git a/arch/arm/include/asm/arch-omap5/i2c.h b/arch/arm/include/asm/arch-omap5/i2c.h
index d875cfe0b4..2b55edf7f0 100644
--- a/arch/arm/include/asm/arch-omap5/i2c.h
+++ b/arch/arm/include/asm/arch-omap5/i2c.h
@@ -14,9 +14,9 @@ struct i2c {
unsigned short revnb_lo; /* 0x00 */
unsigned short res1;
unsigned short revnb_hi; /* 0x04 */
- unsigned short res2[13];
- unsigned short sysc; /* 0x20 */
- unsigned short res3;
+ unsigned short res2[5];
+ unsigned short sysc; /* 0x10 */
+ unsigned short res3[9];
unsigned short irqstatus_raw; /* 0x24 */
unsigned short res4;
unsigned short stat; /* 0x28 */
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 317e5128ed..21edbc2f89 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -65,6 +65,8 @@ void *rockchip_get_cru(void);
struct rk3288_cru;
struct rk3288_grf;
-void rkclk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf);
+void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf);
+
+int rockchip_get_clk(struct udevice **devp);
#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index d3de42d297..e08e28f4f0 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -24,6 +24,12 @@ struct rk3288_sdram_channel {
u8 row_3_4;
u8 cs0_row;
u8 cs1_row;
+ /*
+ * For of-platdata, which would otherwise convert this into two
+ * byte-swapped integers. With a size of 9 bytes, this struct will
+ * appear in of-platdata as a byte array.
+ */
+ u8 dummy;
};
struct rk3288_sdram_pctl_timing {
@@ -81,12 +87,4 @@ struct rk3288_base_params {
u32 odt;
};
-struct rk3288_sdram_params {
- struct rk3288_sdram_channel ch[2];
- struct rk3288_sdram_pctl_timing pctl_timing;
- struct rk3288_sdram_phy_timing phy_timing;
- struct rk3288_base_params base;
- int num_channels;
-};
-
#endif
diff --git a/arch/arm/include/asm/arch-stm32f7/fmc.h b/arch/arm/include/asm/arch-stm32f7/fmc.h
new file mode 100644
index 0000000000..7dd5077d0c
--- /dev/null
+++ b/arch/arm/include/asm/arch-stm32f7/fmc.h
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2013
+ * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com
+ *
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _MACH_FMC_H_
+#define _MACH_FMC_H_
+
+struct stm32_fmc_regs {
+ u32 sdcr1; /* Control register 1 */
+ u32 sdcr2; /* Control register 2 */
+ u32 sdtr1; /* Timing register 1 */
+ u32 sdtr2; /* Timing register 2 */
+ u32 sdcmr; /* Mode register */
+ u32 sdrtr; /* Refresh timing register */
+ u32 sdsr; /* Status register */
+};
+
+/*
+ * FMC registers base
+ */
+#define STM32_SDRAM_FMC_BASE 0xA0000140
+#define STM32_SDRAM_FMC ((struct stm32_fmc_regs *)STM32_SDRAM_FMC_BASE)
+
+/* Control register SDCR */
+#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */
+#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */
+#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */
+#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */
+#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */
+#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */
+#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */
+#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */
+#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */
+
+/* Timings register SDTR */
+#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */
+#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */
+#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */
+#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */
+#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */
+#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */
+#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */
+
+
+#define FMC_SDCMR_NRFS_SHIFT 5
+
+#define FMC_SDCMR_MODE_NORMAL 0
+#define FMC_SDCMR_MODE_START_CLOCK 1
+#define FMC_SDCMR_MODE_PRECHARGE 2
+#define FMC_SDCMR_MODE_AUTOREFRESH 3
+#define FMC_SDCMR_MODE_WRITE_MODE 4
+#define FMC_SDCMR_MODE_SELFREFRESH 5
+#define FMC_SDCMR_MODE_POWERDOWN 6
+
+#define FMC_SDCMR_BANK_1 (1 << 4)
+#define FMC_SDCMR_BANK_2 (1 << 3)
+
+#define FMC_SDCMR_MODE_REGISTER_SHIFT 9
+
+#define FMC_SDSR_BUSY (1 << 5)
+
+#define FMC_BUSY_WAIT() do { \
+ __asm__ __volatile__ ("dsb" : : : "memory"); \
+ while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \
+ ; \
+ } while (0)
+
+
+#endif /* _MACH_FMC_H_ */
diff --git a/arch/arm/include/asm/arch-stm32f7/stm32.h b/arch/arm/include/asm/arch-stm32f7/stm32.h
index 68bdab069d..de55ae5df1 100644
--- a/arch/arm/include/asm/arch-stm32f7/stm32.h
+++ b/arch/arm/include/asm/arch-stm32f7/stm32.h
@@ -64,6 +64,52 @@ enum clock {
};
#define STM32_BUS_MASK 0xFFFF0000
+struct stm32_rcc_regs {
+ u32 cr; /* RCC clock control */
+ u32 pllcfgr; /* RCC PLL configuration */
+ u32 cfgr; /* RCC clock configuration */
+ u32 cir; /* RCC clock interrupt */
+ u32 ahb1rstr; /* RCC AHB1 peripheral reset */
+ u32 ahb2rstr; /* RCC AHB2 peripheral reset */
+ u32 ahb3rstr; /* RCC AHB3 peripheral reset */
+ u32 rsv0;
+ u32 apb1rstr; /* RCC APB1 peripheral reset */
+ u32 apb2rstr; /* RCC APB2 peripheral reset */
+ u32 rsv1[2];
+ u32 ahb1enr; /* RCC AHB1 peripheral clock enable */
+ u32 ahb2enr; /* RCC AHB2 peripheral clock enable */
+ u32 ahb3enr; /* RCC AHB3 peripheral clock enable */
+ u32 rsv2;
+ u32 apb1enr; /* RCC APB1 peripheral clock enable */
+ u32 apb2enr; /* RCC APB2 peripheral clock enable */
+ u32 rsv3[2];
+ u32 ahb1lpenr; /* RCC AHB1 periph clk enable in low pwr mode */
+ u32 ahb2lpenr; /* RCC AHB2 periph clk enable in low pwr mode */
+ u32 ahb3lpenr; /* RCC AHB3 periph clk enable in low pwr mode */
+ u32 rsv4;
+ u32 apb1lpenr; /* RCC APB1 periph clk enable in low pwr mode */
+ u32 apb2lpenr; /* RCC APB2 periph clk enable in low pwr mode */
+ u32 rsv5[2];
+ u32 bdcr; /* RCC Backup domain control */
+ u32 csr; /* RCC clock control & status */
+ u32 rsv6[2];
+ u32 sscgr; /* RCC spread spectrum clock generation */
+ u32 plli2scfgr; /* RCC PLLI2S configuration */
+ u32 pllsaicfgr;
+ u32 dckcfgr;
+};
+#define STM32_RCC ((struct stm32_rcc_regs *)RCC_BASE)
+
+struct stm32_pwr_regs {
+ u32 cr1; /* power control register 1 */
+ u32 csr1; /* power control/status register 2 */
+ u32 cr2; /* power control register 2 */
+ u32 csr2; /* power control/status register 2 */
+};
+#define STM32_PWR ((struct stm32_pwr_regs *)PWR_BASE)
+
int configure_clocks(void);
+unsigned long clock_get(enum clock clck);
+void stm32_flash_latency_cfg(int latency);
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index 0088bb9d0b..d1c5ad0a73 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -269,6 +269,11 @@ struct sunxi_ccm_reg {
#define CCM_MBUS_CTRL_CLK_SRC_PLL5 0x2
#define CCM_MBUS_CTRL_GATE (0x1 << 31)
+#define CCM_NAND_CTRL_M(x) ((x) - 1)
+#define CCM_NAND_CTRL_N(x) ((x) << 16)
+#define CCM_NAND_CTRL_OSCM24 (0x0 << 24)
+#define CCM_NAND_CTRL_PLL6 (0x1 << 24)
+#define CCM_NAND_CTRL_PLL5 (0x2 << 24)
#define CCM_NAND_CTRL_ENABLE (0x1 << 31)
#define CCM_MMC_CTRL_M(x) ((x) - 1)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index c2e72f5a86..d4dff1e346 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -40,7 +40,8 @@ struct sunxi_ccm_reg {
u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */
u32 apb1_gate; /* 0x68 apb1 module clock gating */
u32 apb2_gate; /* 0x6c apb2 module clock gating */
- u32 reserved9[4];
+ u32 bus_gate4; /* 0x70 gate 4 module clock gating */
+ u8 res3[0xc];
u32 nand0_clk_cfg; /* 0x80 nand0 clock control */
u32 nand1_clk_cfg; /* 0x84 nand1 clock control */
u32 sd0_clk_cfg; /* 0x88 sd0 clock control */
@@ -387,6 +388,7 @@ struct sunxi_ccm_reg {
#define AHB_RESET_OFFSET_LCD0 4
/* ahb_reset2 offsets */
+#define AHB_RESET_OFFSET_EPHY 2
#define AHB_RESET_OFFSET_LVDS 0
/* apb2 reset */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index c5e9d88bab..cd009d7ccc 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -87,7 +87,8 @@
#define SUNXI_KEYPAD_BASE 0x01c23000
#define SUNXI_TZPC_BASE 0x01c23400
-#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3)
+#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) || \
+defined(CONFIG_MACH_SUN50I)
/* SID address space starts at 0x01c1400, but e-fuse is at offset 0x200 */
#define SUNXI_SID_BASE 0x01c14200
#else
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 1ace548022..bff7d1453f 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -141,6 +141,7 @@ enum sunxi_gpio_number {
/* GPIO pin function config */
#define SUNXI_GPIO_INPUT 0
#define SUNXI_GPIO_OUTPUT 1
+#define SUNXI_GPIO_DISABLE 7
#define SUNXI_GPA_EMAC 2
#define SUN6I_GPA_GMAC 2
@@ -162,8 +163,10 @@ enum sunxi_gpio_number {
#define SUN50I_GPB_UART0 4
#define SUNXI_GPC_NAND 2
+#define SUNXI_GPC_SPI0 3
#define SUNXI_GPC_SDC2 3
#define SUN6I_GPC_SDC3 4
+#define SUN50I_GPC_SPI0 4
#define SUN8I_GPD_SDC1 3
#define SUNXI_GPD_LCD0 2
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 3da360b177..cb52e64873 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -127,5 +127,4 @@ struct sunxi_mmc {
#define SUNXI_MMC_COMMON_RESET (1 << 18)
struct mmc *sunxi_mmc_init(int sdc_no);
-int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc);
#endif /* _SUNXI_MMC_H */
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index ec73379735..5d7ab559ef 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -51,7 +51,14 @@ struct boot_file_head {
uint8_t spl_signature[4];
};
uint32_t fel_script_address;
- uint32_t reserved1[3];
+ /*
+ * If the fel_uEnv_length member below is set to a non-zero value,
+ * it specifies the size (byte count) of data at fel_script_address.
+ * At the same time this indicates that the data is in uEnv.txt
+ * compatible format, ready to be imported via "env import -t".
+ */
+ uint32_t fel_uEnv_length;
+ uint32_t reserved1[2];
uint32_t boot_media; /* written here by the boot ROM */
uint32_t reserved2[5]; /* padding, align to 64 bytes */
};
diff --git a/arch/arm/include/asm/arch-tegra/board.h b/arch/arm/include/asm/arch-tegra/board.h
index 783bb3c0fa..a3db7ed604 100644
--- a/arch/arm/include/asm/arch-tegra/board.h
+++ b/arch/arm/include/asm/arch-tegra/board.h
@@ -20,7 +20,7 @@ void gpio_early_init(void); /* overrideable GPIO config */
/*
* Hooks to allow boards to set up the pinmux for a specific function.
* Has to be implemented in the board files as we don't yet support pinmux
- * setup from FTD. If a board file does not implement one of those functions
+ * setup from FDT. If a board file does not implement one of those functions
* an empty stub function will be called.
*/
diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h
index e56031d1af..7daf8bc163 100644
--- a/arch/arm/include/asm/arch-tegra/clock.h
+++ b/arch/arm/include/asm/arch-tegra/clock.h
@@ -324,7 +324,7 @@ enum periph_id clk_id_to_periph_id(int clk_id);
* @param p post divider(DIVP)
* @param cpcon base PLL charge pump(CPCON)
* @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
- * be overriden), 1 if PLL is already correct
+ * be overridden), 1 if PLL is already correct
*/
int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon);
diff --git a/arch/arm/include/asm/arch-tegra/ivc.h b/arch/arm/include/asm/arch-tegra/ivc.h
new file mode 100644
index 0000000000..7f2287ae28
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra/ivc.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_TEGRA_IVC_H
+#define _ASM_ARCH_TEGRA_IVC_H
+
+#include <common.h>
+
+/*
+ * Tegra IVC is a communication protocol that transfers fixed-size frames
+ * bi-directionally and in-order between the local CPU and some remote entity.
+ * Communication is via a statically sized and allocated buffer in shared
+ * memory and a notification mechanism.
+ *
+ * This API handles all aspects of the shared memory buffer's metadata, and
+ * leaves all aspects of the frame content to the calling code; frames
+ * typically contain some higher-level protocol. The notification mechanism is
+ * also handled externally to this API, since it can vary from instance to
+ * instance.
+ *
+ * The client model is to first find some free (for TX) or filled (for RX)
+ * frame, process that frame's memory buffer (fill or read it), and then
+ * inform the protocol that the frame has been filled/read, i.e. advance the
+ * write/read pointer. If the channel is full, there may be no available frames
+ * to fill/read. In this case, client code may either poll for an available
+ * frame, or wait for the remote entity to send a notification to the local
+ * CPU.
+ */
+
+/**
+ * struct tegra_ivc - In-memory shared memory layout.
+ *
+ * This is described in detail in ivc.c.
+ */
+struct tegra_ivc_channel_header;
+
+/**
+ * struct tegra_ivc - Software state of an IVC channel.
+ *
+ * This state is internal to the IVC code and should not be accessed directly
+ * by clients. It is public solely so clients can allocate storage for the
+ * structure.
+ */
+struct tegra_ivc {
+ /**
+ * rx_channel - Pointer to the shared memory region used to receive
+ * messages from the remote entity.
+ */
+ struct tegra_ivc_channel_header *rx_channel;
+ /**
+ * tx_channel - Pointer to the shared memory region used to send
+ * messages to the remote entity.
+ */
+ struct tegra_ivc_channel_header *tx_channel;
+ /**
+ * r_pos - The position in list of frames in rx_channel that we are
+ * reading from.
+ */
+ uint32_t r_pos;
+ /**
+ * w_pos - The position in list of frames in tx_channel that we are
+ * writing to.
+ */
+ uint32_t w_pos;
+ /**
+ * nframes - The number of frames allocated (in each direction) in
+ * shared memory.
+ */
+ uint32_t nframes;
+ /**
+ * frame_size - The size of each frame in shared memory.
+ */
+ uint32_t frame_size;
+ /**
+ * notify - Function to call to notify the remote processor of a
+ * change in channel state.
+ */
+ void (*notify)(struct tegra_ivc *);
+};
+
+/**
+ * tegra_ivc_read_get_next_frame - Locate the next frame to receive.
+ *
+ * Locate the next frame to be received/processed, return the address of the
+ * frame, and do not remove it from the queue. Repeated calls to this function
+ * will return the same address until tegra_ivc_read_advance() is called.
+ *
+ * @ivc The IVC channel.
+ * @frame Pointer to be filled with the address of the frame to receive.
+ *
+ * @return 0 if a frame is available, else a negative error code.
+ */
+int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame);
+
+/**
+ * tegra_ivc_read_advance - Advance the read queue.
+ *
+ * Inform the protocol and remote entity that the frame returned by
+ * tegra_ivc_read_get_next_frame() has been processed. The remote end may then
+ * re-use it to transmit further data. Subsequent to this function returning,
+ * tegra_ivc_read_get_next_frame() will return a different frame.
+ *
+ * @ivc The IVC channel.
+ *
+ * @return 0 if OK, else a negative error code.
+ */
+int tegra_ivc_read_advance(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_write_get_next_frame - Locate the next frame to fill for transmit.
+ *
+ * Locate the next frame to be filled for transmit, return the address of the
+ * frame, and do not add it to the queue. Repeated calls to this function
+ * will return the same address until tegra_ivc_read_advance() is called.
+ *
+ * @ivc The IVC channel.
+ * @frame Pointer to be filled with the address of the frame to fill.
+ *
+ * @return 0 if a frame is available, else a negative error code.
+ */
+int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, void **frame);
+
+/**
+ * tegra_ivc_write_advance - Advance the write queue.
+ *
+ * Inform the protocol and remote entity that the frame returned by
+ * tegra_ivc_write_get_next_frame() has been filled and should be transmitted.
+ * The remote end may then read data from it. Subsequent to this function
+ * returning, tegra_ivc_write_get_next_frame() will return a different frame.
+ *
+ * @ivc The IVC channel.
+ *
+ * @return 0 if OK, else a negative error code.
+ */
+int tegra_ivc_write_advance(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_channel_notified - handle internal messages
+ *
+ * This function must be called following every notification.
+ *
+ * @ivc The IVC channel.
+ *
+ * @return 0 if the channel is ready for communication, or -EAGAIN if a
+ * channel reset is in progress.
+ */
+int tegra_ivc_channel_notified(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_channel_reset - initiates a reset of the shared memory state
+ *
+ * This function must be called after a channel is initialized but before it
+ * is used for communication. The channel will be ready for use when a
+ * subsequent call to notify the remote of the channel reset indicates the
+ * reset operation is complete.
+ *
+ * @ivc The IVC channel.
+ */
+void tegra_ivc_channel_reset(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_init - Initialize a channel's software state.
+ *
+ * @ivc The IVC channel.
+ * @rx_base Address of the the RX shared memory buffer.
+ * @tx_base Address of the the TX shared memory buffer.
+ * @nframes Number of frames in each shared memory buffer.
+ * @frame_size Size of each frame.
+ *
+ * @return 0 if OK, else a negative error code.
+ */
+int tegra_ivc_init(struct tegra_ivc *ivc, ulong rx_base, ulong tx_base,
+ uint32_t nframes, uint32_t frame_size,
+ void (*notify)(struct tegra_ivc *));
+
+#endif
diff --git a/arch/arm/include/asm/arch-tegra124/display.h b/arch/arm/include/asm/arch-tegra124/display.h
index ca6644af34..c522faa936 100644
--- a/arch/arm/include/asm/arch-tegra124/display.h
+++ b/arch/arm/include/asm/arch-tegra124/display.h
@@ -11,7 +11,7 @@
/**
* Register a new display based on device tree configuration.
*
- * The frame buffer can be positioned by U-Boot or overriden by the fdt.
+ * The frame buffer can be positioned by U-Boot or overridden by the fdt.
* You should pass in the U-Boot address here, and check the contents of
* struct fdt_disp_config to see what was actually chosen.
*
diff --git a/arch/arm/include/asm/arch-zynqmp/clk.h b/arch/arm/include/asm/arch-zynqmp/clk.h
index b18333d1ca..bfd53b5305 100644
--- a/arch/arm/include/asm/arch-zynqmp/clk.h
+++ b/arch/arm/include/asm/arch-zynqmp/clk.h
@@ -8,7 +8,6 @@
#ifndef _ASM_ARCH_CLK_H_
#define _ASM_ARCH_CLK_H_
-unsigned long get_uart_clk(int dev_id);
unsigned long zynqmp_get_system_timer_freq(void);
#endif /* _ASM_ARCH_CLK_H_ */
diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h
index 423fc70111..a20702e612 100644
--- a/arch/arm/include/asm/armv7.h
+++ b/arch/arm/include/asm/armv7.h
@@ -126,6 +126,8 @@ void _smp_pen(void);
extern char __secure_start[];
extern char __secure_end[];
+extern char __secure_stack_start[];
+extern char __secure_stack_end[];
#endif /* CONFIG_ARMV7_NONSEC */
diff --git a/arch/arm/include/asm/armv7m.h b/arch/arm/include/asm/armv7m.h
index 200444dda1..54d8a2bdff 100644
--- a/arch/arm/include/asm/armv7m.h
+++ b/arch/arm/include/asm/armv7m.h
@@ -51,10 +51,21 @@ struct v7m_mpu {
#define V7M_MPU_CTRL_ENABLE (1 << 0)
#define V7M_MPU_CTRL_HFNMIENA (1 << 1)
+#define V7M_MPU_CTRL_ENABLE (1 << 0)
+#define V7M_MPU_CTRL_DISABLE (0 << 0)
+#define V7M_MPU_CTRL_HFNMIENA (1 << 1)
+
#define V7M_MPU_RASR_EN (1 << 0)
#define V7M_MPU_RASR_SIZE_BITS 1
#define V7M_MPU_RASR_SIZE_4GB (31 << V7M_MPU_RASR_SIZE_BITS)
+#define V7M_MPU_RASR_SIZE_8MB (24 << V7M_MPU_RASR_SIZE_BITS)
+#define V7M_MPU_RASR_TEX_SHIFT 19
+#define V7M_MPU_RASR_S_SHIFT 18
+#define V7M_MPU_RASR_C_SHIFT 17
+#define V7M_MPU_RASR_B_SHIFT 16
#define V7M_MPU_RASR_AP_RW_RW (3 << 24)
+#define V7M_MPU_RASR_XN_ENABLE (0 << 28)
+#define V7M_MPU_RASR_XN_DISABLE (1 << 28)
#endif /* !defined(__ASSEMBLY__) */
#endif /* ARMV7M_H */
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index 0d08ed3ba8..aa0f3c42f6 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -135,12 +135,15 @@ static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr)
}
struct mm_region {
- u64 base;
+ u64 virt;
+ u64 phys;
u64 size;
u64 attrs;
};
extern struct mm_region *mem_map;
+void setup_pgtables(void);
+u64 get_tcr(int el, u64 *pips, u64 *pva_bits);
#endif
#endif /* _ASM_ARMV8_MMU_H_ */
diff --git a/arch/arm/include/asm/armv8/sec_firmware.h b/arch/arm/include/asm/armv8/sec_firmware.h
new file mode 100644
index 0000000000..eb68185fed
--- /dev/null
+++ b/arch/arm/include/asm/armv8/sec_firmware.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SEC_FIRMWARE_H_
+#define __SEC_FIRMWARE_H_
+
+#ifdef CONFIG_FSL_LS_PPA
+#include <asm/arch/ppa.h>
+#endif
+
+int sec_firmware_init(const void *, u32 *, u32 *);
+int _sec_firmware_entry(const void *, u32 *, u32 *);
+bool sec_firmware_is_valid(const void *);
+#ifdef CONFIG_ARMV8_PSCI
+unsigned int sec_firmware_support_psci_version(void);
+unsigned int _sec_firmware_support_psci_version(void);
+#endif
+
+#endif /* __SEC_FIRMWARE_H_ */
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 1f63127bdc..16e65c36a9 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -29,6 +29,8 @@ static inline void invalidate_l2_cache(void)
}
#endif
+int check_cache_range(unsigned long start, unsigned long stop);
+
void l2_cache_enable(void);
void l2_cache_disable(void);
void set_section_dcache(int section, enum dcache_option option);
diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h
index 53cd7550a0..b35c271bba 100644
--- a/arch/arm/include/asm/fsl_secure_boot.h
+++ b/arch/arm/include/asm/fsl_secure_boot.h
@@ -17,8 +17,6 @@
#ifdef CONFIG_CHAIN_OF_TRUST
#define CONFIG_CMD_ESBC_VALIDATE
-#define CONFIG_CMD_BLOB
-#define CONFIG_CMD_HASH
#define CONFIG_FSL_SEC_MON
#define CONFIG_SHA_HW_ACCEL
#define CONFIG_SHA_PROG_HW_ACCEL
@@ -28,6 +26,28 @@
#define CONFIG_FSL_CAAM
#endif
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_DM 1
+#define CONFIG_SPL_CRYPTO_SUPPORT
+#define CONFIG_SPL_HASH_SUPPORT
+#define CONFIG_SPL_RSA
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+/*
+ * Define the key hash for U-Boot here if public/private key pair used to
+ * sign U-boot are different from the SRK hash put in the fuse
+ * Example of defining KEY_HASH is
+ * #define CONFIG_SPL_UBOOT_KEY_HASH \
+ * "41066b564c6ffcef40ccbc1e0a5d0d519604000c785d97bbefd25e4d288d1c8b"
+ * else leave it defined as NULL
+ */
+
+#define CONFIG_SPL_UBOOT_KEY_HASH NULL
+#endif /* ifdef CONFIG_SPL_BUILD */
+
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_CMD_BLOB
+#define CONFIG_CMD_HASH
#define CONFIG_KEY_REVOCATION
#ifndef CONFIG_SYS_RAMBOOT
/* The key used for verification of next level images
@@ -58,39 +78,55 @@
"setenv hwconfig \'fsl_ddr:ctlr_intlv=null,bank_intlv=null\';"
#else
#define CONFIG_EXTRA_ENV \
- "setenv fdt_high 0xcfffffff;" \
- "setenv initrd_high 0xcfffffff;" \
+ "setenv fdt_high 0xffffffff;" \
+ "setenv initrd_high 0xffffffff;" \
"setenv hwconfig \'fsl_ddr:ctlr_intlv=null,bank_intlv=null\';"
#endif
/* Copying Bootscript and Header to DDR from NOR for LS2 and for rest, from
* Non-XIP Memory (Nand/SD)*/
-#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_LS2080A)
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_LS2080A) || \
+ defined(CONFIG_SD_BOOT)
#define CONFIG_BOOTSCRIPT_COPY_RAM
#endif
-/* The address needs to be modified according to NOR and DDR memory map */
+/* The address needs to be modified according to NOR, NAND, SD and
+ * DDR memory map
+ */
#ifdef CONFIG_LS2080A
-#define CONFIG_BS_HDR_ADDR_FLASH 0x583920000
-#define CONFIG_BS_ADDR_FLASH 0x583900000
+#define CONFIG_BS_HDR_ADDR_DEVICE 0x583920000
+#define CONFIG_BS_ADDR_DEVICE 0x583900000
#define CONFIG_BS_HDR_ADDR_RAM 0xa3920000
#define CONFIG_BS_ADDR_RAM 0xa3900000
+#define CONFIG_BS_HDR_SIZE 0x00002000
+#define CONFIG_BS_SIZE 0x00001000
+#else
+#ifdef CONFIG_SD_BOOT
+/* For SD boot address and size are assigned in terms of sector
+ * offset and no. of sectors respectively.
+ */
+#define CONFIG_BS_HDR_ADDR_DEVICE 0x00000800
+#define CONFIG_BS_ADDR_DEVICE 0x00000840
+#define CONFIG_BS_HDR_SIZE 0x00000010
+#define CONFIG_BS_SIZE 0x00000008
#else
-#define CONFIG_BS_HDR_ADDR_FLASH 0x600a0000
-#define CONFIG_BS_ADDR_FLASH 0x60060000
-#define CONFIG_BS_HDR_ADDR_RAM 0xa0060000
-#define CONFIG_BS_ADDR_RAM 0xa0060000
+#define CONFIG_BS_HDR_ADDR_DEVICE 0x600a0000
+#define CONFIG_BS_ADDR_DEVICE 0x60060000
+#define CONFIG_BS_HDR_SIZE 0x00002000
+#define CONFIG_BS_SIZE 0x00001000
+#endif /* #ifdef CONFIG_SD_BOOT */
+#define CONFIG_BS_HDR_ADDR_RAM 0x81000000
+#define CONFIG_BS_ADDR_RAM 0x81020000
#endif
#ifdef CONFIG_BOOTSCRIPT_COPY_RAM
#define CONFIG_BOOTSCRIPT_HDR_ADDR CONFIG_BS_HDR_ADDR_RAM
-#define CONFIG_BS_HDR_SIZE 0x00002000
#define CONFIG_BOOTSCRIPT_ADDR CONFIG_BS_ADDR_RAM
-#define CONFIG_BS_SIZE 0x00001000
#else
-#define CONFIG_BOOTSCRIPT_HDR_ADDR CONFIG_BS_HDR_ADDR_FLASH
-/* BS_HDR_SIZE, BOOTSCRIPT_ADDR and BS_SIZE are not required */
+#define CONFIG_BOOTSCRIPT_HDR_ADDR CONFIG_BS_HDR_ADDR_DEVICE
+/* BOOTSCRIPT_ADDR is not required */
#endif
#include <config_fsl_chain_trust.h>
+#endif /* #ifndef CONFIG_SPL_BUILD */
#endif /* #ifdef CONFIG_CHAIN_OF_TRUST */
#endif
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index 77d2653e27..10550174df 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -44,6 +44,21 @@ struct arch_global_data {
unsigned long tlb_emerg;
#endif
#endif
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+#define MEM_RESERVE_SECURE_SECURED 0x1
+#define MEM_RESERVE_SECURE_MAINTAINED 0x2
+#define MEM_RESERVE_SECURE_ADDR_MASK (~0x3)
+ /*
+ * Secure memory addr
+ * This variable needs maintenance if the RAM base is not zero,
+ * or if RAM splits into non-consecutive banks. It also has a
+ * flag indicating the secure memory is marked as secure by MMU.
+ * Flags used: 0x1 secured
+ * 0x2 maintained
+ */
+ phys_addr_t secure_ram;
+ unsigned long tlb_allocated;
+#endif
#ifdef CONFIG_OMAP_COMMON
u32 omap_boot_device;
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 9d185a6122..6121f1ddca 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -292,40 +292,6 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define readsb(a, d, s) __raw_readsb((unsigned long)a, d, s)
/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt. If you want a
- * physical address, use __ioremap instead.
- */
-extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- * iomem_valid_addr(off,size)
- * iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off,sz,nocache) \
- ({ \
- unsigned long _off = (off), _size = (sz); \
- void *_ret = (void *)0; \
- if (iomem_valid_addr(_off, _size)) \
- _ret = __ioremap(iomem_to_phys(_off),_size,nocache); \
- _ret; \
- })
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off,sz) __arch_ioremap((off),(sz),0)
-#define ioremap_nocache(off,sz) __arch_ioremap((off),(sz),1)
-#define iounmap(_addr) __arch_iounmap(_addr)
-
-/*
* DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA
* devices. This is the "generic" version. The PCI specific version
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 07f384867e..605c549f0a 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -627,6 +627,12 @@ void recalibrate_iodelay(void);
void omap_smc1(u32 service, u32 val);
+/*
+ * Low-level helper function used when performing secure ROM calls on high-
+ * security (HS) device variants by doing a specially-formed smc entry.
+ */
+u32 omap_smc_sec(u32 service, u32 proc_id, u32 flag, u32 *params);
+
void enable_edma3_clocks(void);
void disable_edma3_clocks(void);
diff --git a/arch/arm/include/asm/omap_sec_common.h b/arch/arm/include/asm/omap_sec_common.h
new file mode 100644
index 0000000000..842f2af8d1
--- /dev/null
+++ b/arch/arm/include/asm/omap_sec_common.h
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _OMAP_SEC_COMMON_H_
+#define _OMAP_SEC_COMMON_H_
+
+#include <common.h>
+
+/*
+ * Invoke secure ROM API on high-security (HS) device variants. It formats
+ * the variable argument list into the format expected by the ROM code before
+ * triggering the actual low-level smc entry.
+ */
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...);
+
+/*
+ * Invoke a secure ROM API on high-secure (HS) device variants that can be used
+ * to verify a secure blob by authenticating and optionally decrypting it. The
+ * exact operation performed depends on how the certificate that was embedded
+ * into the blob during the signing/encryption step when the secure blob was
+ * first created.
+ */
+int secure_boot_verify_image(void **p_image, size_t *p_size);
+
+#endif /* _OMAP_SEC_COMMON_H_ */
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
index bc5edda73f..8aefaa7708 100644
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -31,6 +31,12 @@
#define ARM_PSCI_RET_NI (-1)
#define ARM_PSCI_RET_INVAL (-2)
#define ARM_PSCI_RET_DENIED (-3)
+#define ARM_PSCI_RET_ALREADY_ON (-4)
+#define ARM_PSCI_RET_ON_PENDING (-5)
+#define ARM_PSCI_RET_INTERNAL_FAILURE (-6)
+#define ARM_PSCI_RET_NOT_PRESENT (-7)
+#define ARM_PSCI_RET_DISABLED (-8)
+#define ARM_PSCI_RET_INVALID_ADDRESS (-9)
/* PSCI 0.2 interface */
#define ARM_PSCI_0_2_FN_BASE 0x84000000
@@ -47,16 +53,39 @@
#define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8)
#define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9)
+/* PSCI 1.0 interface */
+#define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10)
+#define ARM_PSCI_1_0_FN_CPU_FREEZE ARM_PSCI_0_2_FN(11)
+#define ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND ARM_PSCI_0_2_FN(12)
+#define ARM_PSCI_1_0_FN_NODE_HW_STATE ARM_PSCI_0_2_FN(13)
+#define ARM_PSCI_1_0_FN_SYSTEM_SUSPEND ARM_PSCI_0_2_FN(14)
+#define ARM_PSCI_1_0_FN_SET_SUSPEND_MODE ARM_PSCI_0_2_FN(15)
+#define ARM_PSCI_1_0_FN_STAT_RESIDENCY ARM_PSCI_0_2_FN(16)
+#define ARM_PSCI_1_0_FN_STAT_COUNT ARM_PSCI_0_2_FN(17)
+
+/* 1KB stack per core */
+#define ARM_PSCI_STACK_SHIFT 10
+#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT)
+
+/* PSCI affinity level state returned by AFFINITY_INFO */
+#define PSCI_AFFINITY_LEVEL_ON 0
+#define PSCI_AFFINITY_LEVEL_OFF 1
+#define PSCI_AFFINITY_LEVEL_ON_PENDING 2
+
#ifndef __ASSEMBLY__
#include <asm/types.h>
+/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */
+u32 psci_get_target_pc(int cpu);
+void psci_save_target_pc(int cpu, u32 pc);
+
void psci_cpu_entry(void);
u32 psci_get_cpu_id(void);
-u32 psci_get_cpu_stack_top(int cpu);
void psci_cpu_off_common(void);
int psci_update_dt(void *fdt);
void psci_board_init(void);
+int fdt_psci(void *fdt);
#endif /* ! __ASSEMBLY__ */
#endif /* __ARM_PSCI_H__ */
diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h
index effdb1858d..5a403bc0f1 100644
--- a/arch/arm/include/asm/secure.h
+++ b/arch/arm/include/asm/secure.h
@@ -3,6 +3,9 @@
#include <config.h>
+#define __secure __attribute__ ((section ("._secure.text")))
+#define __secure_data __attribute__ ((section ("._secure.data")))
+
#ifdef CONFIG_ARMV7_SECURE_BASE
/*
* Warning, horror ahead.
diff --git a/arch/arm/include/asm/spin_table.h b/arch/arm/include/asm/spin_table.h
new file mode 100644
index 0000000000..8b57539f8d
--- /dev/null
+++ b/arch/arm/include/asm/spin_table.h
@@ -0,0 +1,14 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ASM_SPIN_TABLE_H__
+#define __ASM_SPIN_TABLE_H__
+
+extern u64 spin_table_cpu_release_addr;
+extern char spin_table_reserve_begin;
+extern char spin_table_reserve_end;
+
+int spin_table_update_dt(void *fdt);
+
+#endif /* __ASM_SPIN_TABLE_H__ */
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
index d108915ff5..9af7353f08 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/asm/types.h
@@ -71,5 +71,4 @@ typedef u32 dma_addr_t;
#endif /* __KERNEL__ */
-typedef unsigned long resource_size_t;
#endif
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 0e05e87dea..9f71376d30 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -27,11 +27,13 @@ endif
obj-$(CONFIG_CPU_V7M) += cmd_boot.o
obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_CMD_BOOTM) += zimage.o
obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
obj-$(CONFIG_USE_ARCH_MEMSET) += memset.o
obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
else
obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o
endif
obj-$(CONFIG_SEMIHOSTING) += semihosting.o
@@ -55,6 +57,8 @@ ifndef CONFIG_ARM64
obj-y += cache-cp15.o
endif
+obj-y += psci-dt.o
+
obj-$(CONFIG_DEBUG_LL) += debug.o
# For EABI conformant tool chains, provide eabi_compat()
diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c
index 76b75d8e46..4481f9e2fa 100644
--- a/arch/arm/lib/bootm-fdt.c
+++ b/arch/arm/lib/bootm-fdt.c
@@ -21,6 +21,7 @@
#include <asm/armv7.h>
#endif
#include <asm/psci.h>
+#include <asm/spin_table.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -45,7 +46,13 @@ int arch_fixup_fdt(void *blob)
if (ret)
return ret;
-#ifdef CONFIG_ARMV7_NONSEC
+#ifdef CONFIG_ARMV8_SPIN_TABLE
+ ret = spin_table_update_dt(blob);
+ if (ret)
+ return ret;
+#endif
+
+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV8_PSCI)
ret = psci_update_dt(blob);
if (ret)
return ret;
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 0838d89907..c20ef227fb 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -358,38 +358,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
return 0;
}
-#ifdef CONFIG_CMD_BOOTZ
-
-struct zimage_header {
- uint32_t code[9];
- uint32_t zi_magic;
- uint32_t zi_start;
- uint32_t zi_end;
-};
-
-#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818
-
-int bootz_setup(ulong image, ulong *start, ulong *end)
-{
- struct zimage_header *zi;
-
- zi = (struct zimage_header *)map_sysmem(image, 0);
- if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
- puts("Bad Linux ARM zImage magic!\n");
- return 1;
- }
-
- *start = zi->zi_start;
- *end = zi->zi_end;
-
- printf("Kernel image @ %#08lx [ %#08lx - %#08lx ]\n", image, *start,
- *end);
-
- return 0;
-}
-
-#endif /* CONFIG_CMD_BOOTZ */
-
#if defined(CONFIG_BOOTM_VXWORKS)
void boot_prep_vxworks(bootm_headers_t *images)
{
diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
index 3bd87105c5..d330b09434 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/lib/cache.c
@@ -10,6 +10,10 @@
#include <common.h>
#include <malloc.h>
+#ifndef CONFIG_SYS_CACHELINE_SIZE
+#define CONFIG_SYS_CACHELINE_SIZE 32
+#endif
+
/*
* Flush range from all levels of d-cache/unified-cache.
* Affects the range [start, start + size - 1].
@@ -46,6 +50,24 @@ __weak void flush_dcache_range(unsigned long start, unsigned long stop)
/* An empty stub, real implementation should be in platform code */
}
+int check_cache_range(unsigned long start, unsigned long stop)
+{
+ int ok = 1;
+
+ if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (!ok) {
+ warn_non_spl("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
+ start, stop);
+ }
+
+ return ok;
+}
+
#ifdef CONFIG_SYS_NONCACHED_MEMORY
/*
* Reserve one MMU section worth of address space below the malloc() area that
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index cad22c7b41..91b19e00da 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -108,6 +108,7 @@ relocation_return:
* Set up final (full) environment
*/
bl c_runtime_cpu_setup /* still call old routine */
+#endif /* !CONFIG_SPL_BUILD */
/* TODO: For SPL, call spl_relocate_stack_gd() to alloc stack relocation */
@@ -130,6 +131,4 @@ clear_loop:
/* NOTREACHED - board_init_r() does not return */
-#endif /* !CONFIG_SPL_BUILD */
-
ENDPROC(_main)
diff --git a/arch/arm/lib/psci-dt.c b/arch/arm/lib/psci-dt.c
new file mode 100644
index 0000000000..8dc31d4897
--- /dev/null
+++ b/arch/arm/lib/psci-dt.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <linux/sizes.h>
+#include <linux/kernel.h>
+#include <asm/psci.h>
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
+
+int fdt_psci(void *fdt)
+{
+#if defined(CONFIG_ARMV8_PSCI) || defined(CONFIG_ARMV7_PSCI)
+ int nodeoff;
+ unsigned int psci_ver = 0;
+ char *psci_compt;
+ int tmp;
+
+ nodeoff = fdt_path_offset(fdt, "/cpus");
+ if (nodeoff < 0) {
+ printf("couldn't find /cpus\n");
+ return nodeoff;
+ }
+
+ /* add 'enable-method = "psci"' to each cpu node */
+ for (tmp = fdt_first_subnode(fdt, nodeoff);
+ tmp >= 0;
+ tmp = fdt_next_subnode(fdt, tmp)) {
+ const struct fdt_property *prop;
+ int len;
+
+ prop = fdt_get_property(fdt, tmp, "device_type", &len);
+ if (!prop)
+ continue;
+ if (len < 4)
+ continue;
+ if (strcmp(prop->data, "cpu"))
+ continue;
+
+ /*
+ * Not checking rv here, our approach is to skip over errors in
+ * individual cpu nodes, hopefully some of the nodes are
+ * processed correctly and those will boot
+ */
+ fdt_setprop_string(fdt, tmp, "enable-method", "psci");
+ }
+
+ /*
+ * The PSCI node might be called "/psci" or might be called something
+ * else but contain either of the compatible strings
+ * "arm,psci"/"arm,psci-0.2"
+ */
+ nodeoff = fdt_path_offset(fdt, "/psci");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-0.2");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-1.0");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_path_offset(fdt, "/");
+ if (nodeoff < 0)
+ return nodeoff;
+
+ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
+ if (nodeoff < 0)
+ return nodeoff;
+
+init_psci_node:
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+ psci_ver = sec_firmware_support_psci_version();
+#endif
+ switch (psci_ver) {
+ case 0x00010000:
+ psci_compt = "arm,psci-1.0";
+ break;
+ case 0x00000002:
+ psci_compt = "arm,psci-0.2";
+ break;
+ default:
+ psci_compt = "arm,psci";
+ break;
+ }
+
+ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", psci_compt);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
+ if (tmp)
+ return tmp;
+
+#ifdef CONFIG_ARMV7_PSCI
+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend",
+ ARM_PSCI_FN_CPU_SUSPEND);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE);
+ if (tmp)
+ return tmp;
+#endif
+#endif
+ return 0;
+}
diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c
index 6a94522418..952e8ae49b 100644
--- a/arch/arm/lib/sections.c
+++ b/arch/arm/lib/sections.c
@@ -27,6 +27,8 @@ char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start")));
char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end")));
char __secure_start[0] __attribute__((section(".__secure_start")));
char __secure_end[0] __attribute__((section(".__secure_end")));
+char __secure_stack_start[0] __attribute__((section(".__secure_stack_start")));
+char __secure_stack_end[0] __attribute__((section(".__secure_stack_end")));
char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start")));
char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop")));
char __efi_runtime_rel_start[0] __attribute__((section(".__efi_runtime_rel_start")));
diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c
index e42886840e..3587ad6812 100644
--- a/arch/arm/lib/spl.c
+++ b/arch/arm/lib/spl.c
@@ -25,22 +25,20 @@ gd_t gdata __attribute__ ((section(".data")));
#endif
/*
- * In the context of SPL, board_init_f must ensure that any clocks/etc for
- * DDR are enabled, ensure that the stack pointer is valid, clear the BSS
- * and call board_init_r. We provide this version by default but mark it
- * as __weak to allow for platforms to do this in their own way if needed.
+ * In the context of SPL, board_init_f() prepares the hardware for execution
+ * from system RAM (DRAM, DDR...). As system RAM may not be available yet,
+ * board_init_f() must use the current GD to store any data which must be
+ * passed on to later stages. These data include the relocation destination,
+ * the future stack, and the future GD location. BSS is cleared after this
+ * function (and therefore must be accessible).
+ *
+ * We provide this version by default but mark it as __weak to allow for
+ * platforms to do this in their own way if needed. Please see the top
+ * level U-Boot README "Board Initialization Flow" section for info on what
+ * to put in this function.
*/
void __weak board_init_f(ulong dummy)
{
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
-#ifndef CONFIG_SPL_DM
- /* TODO: Remove settings of the global data pointer here */
- gd = &gdata;
-#endif
-
- board_init_r(NULL, 0);
}
/*
@@ -60,7 +58,7 @@ void __noreturn jump_to_image_linux(void *arg)
typedef void (*image_entry_arg_t)(int, int, void *)
__attribute__ ((noreturn));
image_entry_arg_t image_entry =
- (image_entry_arg_t) spl_image.entry_point;
+ (image_entry_arg_t)(uintptr_t) spl_image.entry_point;
cleanup_before_linux();
image_entry(0, machid, arg);
}
diff --git a/arch/arm/lib/zimage.c b/arch/arm/lib/zimage.c
new file mode 100644
index 0000000000..1e811a87dd
--- /dev/null
+++ b/arch/arm/lib/zimage.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016
+ * Ladislav Michl <ladis@linux-mips.org>
+ *
+ * bootz code:
+ * Copyright (C) 2012 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+
+#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818
+
+struct arm_z_header {
+ uint32_t code[9];
+ uint32_t zi_magic;
+ uint32_t zi_start;
+ uint32_t zi_end;
+} __attribute__ ((__packed__));
+
+int bootz_setup(ulong image, ulong *start, ulong *end)
+{
+ struct arm_z_header *zi = (struct arm_z_header *)image;
+
+ if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
+#ifndef CONFIG_SPL_FRAMEWORK
+ puts("Bad Linux ARM zImage magic!\n");
+#endif
+ return 1;
+ }
+
+ *start = zi->zi_start;
+ *end = zi->zi_end;
+#ifndef CONFIG_SPL_FRAMEWORK
+ printf("Kernel image @ %#08lx [ %#08lx - %#08lx ]\n",
+ image, *start, *end);
+#endif
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/include/mach/dwmmc.h b/arch/arm/mach-exynos/include/mach/dwmmc.h
index bd997ad47e..ab8361f4a8 100644
--- a/arch/arm/mach-exynos/include/mach/dwmmc.h
+++ b/arch/arm/mach-exynos/include/mach/dwmmc.h
@@ -28,4 +28,3 @@
#define DWMCI_DIVRATIO_MASK 0x7
int exynos_dwmmc_init(const void *blob);
-int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel);
diff --git a/arch/arm/mach-exynos/mmu-arm64.c b/arch/arm/mach-exynos/mmu-arm64.c
index ba6d99d329..23814222d8 100644
--- a/arch/arm/mach-exynos/mmu-arm64.c
+++ b/arch/arm/mach-exynos/mmu-arm64.c
@@ -13,21 +13,20 @@ DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_EXYNOS7420
static struct mm_region exynos7420_mem_map[] = {
{
- .base = 0x10000000UL,
+ .virt = 0x10000000UL,
+ .phys = 0x10000000UL,
.size = 0x10000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN,
}, {
- .base = 0x40000000UL,
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE,
}, {
/* List terminator */
- .base = 0,
- .size = 0,
- .attrs = 0,
},
};
diff --git a/arch/arm/mach-keystone/init.c b/arch/arm/mach-keystone/init.c
index 3b6d5efce1..6e5a1e1af1 100644
--- a/arch/arm/mach-keystone/init.c
+++ b/arch/arm/mach-keystone/init.c
@@ -101,9 +101,7 @@ static void msmc_k2hkle_common_setup(void)
msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_0);
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_ARM);
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_NETCP);
-#ifdef KS2_MSMC_SEGMENT_QM_PDSP
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_QM_PDSP);
-#endif
msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_PCIE0);
msmc_share_all_segments(KS2_MSMC_SEGMENT_DEBUG);
}
diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board.c
index 64fa3c191e..1dd53e2313 100644
--- a/arch/arm/mach-meson/board.c
+++ b/arch/arm/mach-meson/board.c
@@ -48,12 +48,14 @@ void reset_cpu(ulong addr)
static struct mm_region gxbb_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 2a8afac5e1..1aac3c85ba 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -1,7 +1,21 @@
if ARCH_ROCKCHIP
+config ROCKCHIP_RK3036
+ bool "Support Rockchip RK3036"
+ select CPU_V7
+ select SUPPORT_SPL
+ select SPL
+ help
+ The Rockchip RK3036 is a ARM-based SoC with a dual-core Cortex-A7
+ including NEON and GPU, Mali-400 graphics, several DDR3 options
+ and video codec support. Peripherals include Gigabit Ethernet,
+ USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+
config ROCKCHIP_RK3288
bool "Support Rockchip RK3288"
+ select CPU_V7
+ select SUPPORT_SPL
+ select SPL
help
The Rockchip RK3288 is a ARM-based SoC with a quad-core Cortex-A17
including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
@@ -9,41 +23,26 @@ config ROCKCHIP_RK3288
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UART,s, SPI, I2C and PWMs.
-config ROCKCHIP_RK3036
- bool "Support Rockchip RK3036"
+config ROCKCHIP_RK3399
+ bool "Support Rockchip RK3399"
+ select ARM64
help
- The Rockchip RK3036 is a ARM-based SoC with a dual-core Cortex-A7
- including NEON and GPU, Mali-400 graphics, several DDR3 options
+ The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
+ and quad-core Cortex-A53.
+ including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
+ video interfaces supporting HDMI and eDP, several DDR3 options
and video codec support. Peripherals include Gigabit Ethernet,
- USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
-
-config SYS_MALLOC_F
- default y
-
-config SPL_SYS_MALLOC_SIMPLE
- default y
-
-config SPL_DM
- default y
-
-config DM_SERIAL
- default y
-
-config DM_SPI
- default y
+ USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
-config DM_SPI_FLASH
- default y
-
-config DM_I2C
- default y
-
-config DM_GPIO
- default y
-
-config BLK
- default y
+config ROCKCHIP_SPL_BACK_TO_BROM
+ bool "SPL returns to bootrom"
+ default y if ROCKCHIP_RK3036
+ help
+ Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
+ SPL will return to the boot rom, which will then load the U-Boot
+ binary to keep going on.
-source "arch/arm/mach-rockchip/rk3288/Kconfig"
source "arch/arm/mach-rockchip/rk3036/Kconfig"
+source "arch/arm/mach-rockchip/rk3288/Kconfig"
+source "arch/arm/mach-rockchip/rk3399/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 55567cb131..157d42fe96 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -5,11 +5,15 @@
#
ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
+obj-$(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) += save_boot_param.o
else
obj-$(CONFIG_ROCKCHIP_RK3288) += board.o
endif
+ifndef CONFIG_ARM64
obj-y += rk_timer.o
-obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+endif
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
index 816540e582..bec756d7ac 100644
--- a/arch/arm/mach-rockchip/board.c
+++ b/arch/arm/mach-rockchip/board.c
@@ -10,12 +10,45 @@
#include <ram.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
+#include <asm/arch/periph.h>
+#include <asm/gpio.h>
+#include <dm/pinctrl.h>
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+ struct udevice *pinctrl;
+ int ret;
+
+ /*
+ * We need to implement sdcard iomux here for the further
+ * initlization, otherwise, it'll hit sdcard command sending
+ * timeout exception.
+ */
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+ if (ret) {
+ debug("%s: Cannot find pinctrl device\n", __func__);
+ goto err;
+ }
+ ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+ if (ret) {
+ debug("%s: Failed to set up SD card\n", __func__);
+ goto err;
+ }
+
+ return 0;
+err:
+ printf("board_init: Error %d\n", ret);
+
+ /* No way to report error here */
+ hang();
+
+ return -1;
+#else
return 0;
+#endif
}
int dram_init(void)
@@ -52,6 +85,78 @@ void lowlevel_init(void)
{
}
+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
+#include <usb.h>
+#include <usb/dwc2_udc.h>
+
+static struct dwc2_plat_otg_data rk3288_otg_data = {
+ .rx_fifo_sz = 512,
+ .np_tx_fifo_sz = 16,
+ .tx_fifo_sz = 128,
+};
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ int node, phy_node;
+ const char *mode;
+ bool matched = false;
+ const void *blob = gd->fdt_blob;
+ u32 grf_phy_offset;
+
+ /* find the usb_otg node */
+ node = fdt_node_offset_by_compatible(blob, -1,
+ "rockchip,rk3288-usb");
+
+ while (node > 0) {
+ mode = fdt_getprop(blob, node, "dr_mode", NULL);
+ if (mode && strcmp(mode, "otg") == 0) {
+ matched = true;
+ break;
+ }
+
+ node = fdt_node_offset_by_compatible(blob, node,
+ "rockchip,rk3288-usb");
+ }
+ if (!matched) {
+ debug("Not found usb_otg device\n");
+ return -ENODEV;
+ }
+ rk3288_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
+
+ node = fdtdec_lookup_phandle(blob, node, "phys");
+ if (node <= 0) {
+ debug("Not found usb phy device\n");
+ return -ENODEV;
+ }
+
+ phy_node = fdt_parent_offset(blob, node);
+ if (phy_node <= 0) {
+ debug("Not found usb phy device\n");
+ return -ENODEV;
+ }
+
+ rk3288_otg_data.phy_of_node = phy_node;
+ grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
+
+ /* find the grf node */
+ node = fdt_node_offset_by_compatible(blob, -1,
+ "rockchip,rk3288-grf");
+ if (node <= 0) {
+ debug("Not found grf device\n");
+ return -ENODEV;
+ }
+ rk3288_otg_data.regs_phy = grf_phy_offset +
+ fdtdec_get_addr(blob, node, "reg");
+
+ return dwc2_udc_probe(&rk3288_otg_data);
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ return 0;
+}
+#endif
+
static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
@@ -73,7 +178,7 @@ static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
int ret, i;
struct udevice *dev;
- ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+ ret = rockchip_get_clk(&dev);
if (ret) {
printf("clk-uclass not found\n");
return 0;
diff --git a/arch/arm/mach-rockchip/rk3036/Kconfig b/arch/arm/mach-rockchip/rk3036/Kconfig
index cc03808847..f7562bd610 100644
--- a/arch/arm/mach-rockchip/rk3036/Kconfig
+++ b/arch/arm/mach-rockchip/rk3036/Kconfig
@@ -15,7 +15,7 @@ config SYS_MALLOC_F_LEN
config ROCKCHIP_COMMON
bool "Support rk common fuction"
-source "board/evb_rk3036/evb_rk3036/Kconfig"
-source "board/kylin/kylin_rk3036/Kconfig"
+source "board/rockchip/evb_rk3036/Kconfig"
+source "board/rockchip/kylin_rk3036/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile
index 97d299d6cc..6095777b8f 100644
--- a/arch/arm/mach-rockchip/rk3036/Makefile
+++ b/arch/arm/mach-rockchip/rk3036/Makefile
@@ -10,4 +10,3 @@ obj-y += syscon_rk3036.o
endif
obj-y += sdram_rk3036.o
-obj-y += save_boot_param.o
diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
index 15f1266a7b..ed14023021 100644
--- a/arch/arm/mach-rockchip/rk3288-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
@@ -29,6 +29,7 @@ DECLARE_GLOBAL_DATA_PTR;
u32 spl_boot_device(void)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
const void *blob = gd->fdt_blob;
struct udevice *dev;
const char *bootdev;
@@ -63,6 +64,7 @@ u32 spl_boot_device(void)
}
fallback:
+#endif
return BOOT_DEVICE_MMC1;
}
@@ -114,7 +116,6 @@ static void configure_l2ctlr(void)
#ifdef CONFIG_SPL_MMC_SUPPORT
static int configure_emmc(struct udevice *pinctrl)
{
-#if !defined(CONFIG_TARGET_ROCK2) && !defined(CONFIG_TARGET_FIREFLY_RK3288)
struct gpio_desc desc;
int ret;
@@ -144,12 +145,11 @@ static int configure_emmc(struct udevice *pinctrl)
debug("gpio value ret=%d\n", ret);
return ret;
}
-#endif
return 0;
}
#endif
-
+extern void back_to_bootrom(void);
void board_init_f(ulong dummy)
{
struct udevice *pinctrl;
@@ -187,7 +187,7 @@ void board_init_f(ulong dummy)
rockchip_timer_init();
configure_l2ctlr();
- ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+ ret = rockchip_get_clk(&dev);
if (ret) {
debug("CLK init failed: %d\n", ret);
return;
@@ -204,6 +204,9 @@ void board_init_f(ulong dummy)
debug("DRAM init failed: %d\n", ret);
return;
}
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+ back_to_bootrom();
+#endif
}
static int setup_led(void)
@@ -247,15 +250,19 @@ void spl_board_init(void)
goto err;
}
#ifdef CONFIG_SPL_MMC_SUPPORT
- ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
- if (ret) {
- debug("%s: Failed to set up SD card\n", __func__);
- goto err;
- }
- ret = configure_emmc(pinctrl);
- if (ret) {
- debug("%s: Failed to set up eMMC\n", __func__);
- goto err;
+ if (!IS_ENABLED(CONFIG_TARGET_ROCK2) &&
+ !IS_ENABLED(CONFIG_TARGET_FIREFLY_RK3288) &&
+ !IS_ENABLED(CONFIG_TARGET_EVB_RK3288)) {
+ ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+ if (ret) {
+ debug("%s: Failed to set up SD card\n", __func__);
+ goto err;
+ }
+ ret = configure_emmc(pinctrl);
+ if (ret) {
+ debug("%s: Failed to set up eMMC\n", __func__);
+ goto err;
+ }
}
#endif
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 72156245bd..031dbfc061 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -8,6 +8,14 @@ config TARGET_FIREFLY_RK3288
also includes on-board eMMC and 1GB of SDRAM. Expansion connectors
provide access to display pins, I2C, SPI, UART and GPIOs.
+config TARGET_EVB_RK3288
+ bool "Evb-RK3288"
+ help
+ EVB-RK3288 is a RK3288-based development board with 2 USB ports,
+ HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It
+ also includes on-board eMMC and 2GB of SDRAM. Expansion connectors
+ provide access to display pins, I2C, SPI, UART and GPIOs.
+
config TARGET_CHROMEBOOK_JERRY
bool "Google/Rockchip Veyron-Jerry Chromebook"
help
@@ -45,4 +53,6 @@ source "board/firefly/firefly-rk3288/Kconfig"
source "board/radxa/rock2/Kconfig"
+source "board/evb-rk3288/evb-rk3288/Kconfig"
+
endif
diff --git a/arch/arm/mach-rockchip/rk3288/Makefile b/arch/arm/mach-rockchip/rk3288/Makefile
index 6f62375f46..82b00a1b01 100644
--- a/arch/arm/mach-rockchip/rk3288/Makefile
+++ b/arch/arm/mach-rockchip/rk3288/Makefile
@@ -4,6 +4,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
+obj-y += clk_rk3288.o
obj-y += reset_rk3288.o
obj-y += sdram_rk3288.o
obj-y += syscon_rk3288.o
diff --git a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
new file mode 100644
index 0000000000..2099e349c1
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(rockchip_rk3288_cru), devp);
+}
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
index 55ac73e9d2..cf9ef2e845 100644
--- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
+#include <dt-structs.h>
#include <errno.h>
#include <ram.h>
#include <regmap.h>
@@ -41,6 +42,19 @@ struct dram_info {
struct rk3288_grf *grf;
struct rk3288_sgrf *sgrf;
struct rk3288_pmu *pmu;
+ bool is_veyron;
+};
+
+struct rk3288_sdram_params {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3288_dmc of_plat;
+#endif
+ struct rk3288_sdram_channel ch[2];
+ struct rk3288_sdram_pctl_timing pctl_timing;
+ struct rk3288_sdram_phy_timing phy_timing;
+ struct rk3288_base_params base;
+ int num_channels;
+ struct regmap *map;
};
#ifdef CONFIG_SPL_BUILD
@@ -561,14 +575,14 @@ static void dram_all_config(const struct dram_info *dram,
&sdram_params->ch[chan];
sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
- sys_reg |= chan << SYS_REG_CHINFO_SHIFT(chan);
+ sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
- sys_reg |= info->bk == 3 ? 1 << SYS_REG_BK_SHIFT(chan) : 0;
+ sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
- sys_reg |= info->bw << SYS_REG_BW_SHIFT(chan);
- sys_reg |= info->dbw << SYS_REG_DBW_SHIFT(chan);
+ sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
+ sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
}
@@ -703,7 +717,7 @@ static int sdram_init(struct dram_info *dram,
return 0;
}
-#endif
+#endif /* CONFIG_SPL_BUILD */
size_t sdram_size_mb(struct rk3288_pmu *pmu)
{
@@ -720,13 +734,13 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu)
rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
SYS_REG_RANK_MASK);
col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
- bk = sys_reg & (1 << SYS_REG_BK_SHIFT(ch)) ? 3 : 0;
+ bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
SYS_REG_CS0_ROW_MASK);
cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
SYS_REG_CS1_ROW_MASK);
- bw = (sys_reg >> SYS_REG_BW_SHIFT(ch)) &
- SYS_REG_BW_MASK;
+ bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
+ SYS_REG_BW_MASK));
row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
SYS_REG_ROW_3_4_MASK;
@@ -770,7 +784,7 @@ static int veyron_init(struct dram_info *priv)
return ret;
udelay(100);/* Must wait for voltage to stabilize, 2mV/us */
- rkclk_configure_cpu(priv->cru, priv->grf);
+ rk3288_clk_configure_cpu(priv->cru, priv->grf);
return 0;
}
@@ -779,18 +793,36 @@ static int veyron_init(struct dram_info *priv)
static int setup_sdram(struct udevice *dev)
{
struct dram_info *priv = dev_get_priv(dev);
- struct rk3288_sdram_params params;
+ struct rk3288_sdram_params *params = dev_get_platdata(dev);
+
+# ifdef CONFIG_ROCKCHIP_FAST_SPL
+ if (priv->is_veyron) {
+ int ret;
+
+ ret = veyron_init(priv);
+ if (ret)
+ return ret;
+ }
+# endif
+
+ return sdram_init(priv, params);
+}
+
+static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3288_sdram_params *params = dev_get_platdata(dev);
const void *blob = gd->fdt_blob;
int node = dev->of_offset;
int i, ret;
- params.num_channels = fdtdec_get_int(blob, node,
- "rockchip,num-channels", 1);
- for (i = 0; i < params.num_channels; i++) {
+ params->num_channels = fdtdec_get_int(blob, node,
+ "rockchip,num-channels", 1);
+ for (i = 0; i < params->num_channels; i++) {
ret = fdtdec_get_byte_array(blob, node,
"rockchip,sdram-channel",
- (u8 *)&params.ch[i],
- sizeof(params.ch[i]));
+ (u8 *)&params->ch[i],
+ sizeof(params->ch[i]));
if (ret) {
debug("%s: Cannot read rockchip,sdram-channel\n",
__func__);
@@ -798,46 +830,82 @@ static int setup_sdram(struct udevice *dev)
}
}
ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
- (u32 *)&params.pctl_timing,
- sizeof(params.pctl_timing) / sizeof(u32));
+ (u32 *)&params->pctl_timing,
+ sizeof(params->pctl_timing) / sizeof(u32));
if (ret) {
debug("%s: Cannot read rockchip,pctl-timing\n", __func__);
return -EINVAL;
}
ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing",
- (u32 *)&params.phy_timing,
- sizeof(params.phy_timing) / sizeof(u32));
+ (u32 *)&params->phy_timing,
+ sizeof(params->phy_timing) / sizeof(u32));
if (ret) {
debug("%s: Cannot read rockchip,phy-timing\n", __func__);
return -EINVAL;
}
ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
- (u32 *)&params.base,
- sizeof(params.base) / sizeof(u32));
+ (u32 *)&params->base,
+ sizeof(params->base) / sizeof(u32));
if (ret) {
debug("%s: Cannot read rockchip,sdram-params\n", __func__);
return -EINVAL;
}
+#ifdef CONFIG_ROCKCHIP_FAST_SPL
+ struct dram_info *priv = dev_get_priv(dev);
-# ifdef CONFIG_ROCKCHIP_FAST_SPL
- if (!fdt_node_check_compatible(blob, 0, "google,veyron")) {
- ret = veyron_init(priv);
- if (ret)
- return ret;
+ priv->is_veyron = !fdt_node_check_compatible(blob, 0, "google,veyron");
+#endif
+ ret = regmap_init_mem(dev, &params->map);
+ if (ret)
+ return ret;
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_SPL_BUILD */
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int conv_of_platdata(struct udevice *dev)
+{
+ struct rk3288_sdram_params *plat = dev_get_platdata(dev);
+ struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
+ int i, ret;
+
+ for (i = 0; i < 2; i++) {
+ memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
+ sizeof(plat->ch[i]));
}
-# endif
+ memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
+ sizeof(plat->pctl_timing));
+ memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
+ sizeof(plat->phy_timing));
+ memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
+ plat->num_channels = of_plat->rockchip_num_channels;
+ ret = regmap_init_mem_platdata(dev, of_plat->reg,
+ ARRAY_SIZE(of_plat->reg) / 2,
+ &plat->map);
+ if (ret)
+ return ret;
- return sdram_init(priv, &params);
+ return 0;
}
#endif
static int rk3288_dmc_probe(struct udevice *dev)
{
+#ifdef CONFIG_SPL_BUILD
+ struct rk3288_sdram_params *plat = dev_get_platdata(dev);
+#endif
struct dram_info *priv = dev_get_priv(dev);
struct regmap *map;
int ret;
struct udevice *dev_clk;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ ret = conv_of_platdata(dev);
+ if (ret)
+ return ret;
+#endif
map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
if (IS_ERR(map))
return PTR_ERR(map);
@@ -849,15 +917,13 @@ static int rk3288_dmc_probe(struct udevice *dev)
priv->sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
- ret = regmap_init_mem(dev, &map);
- if (ret)
- return ret;
- priv->chan[0].pctl = regmap_get_range(map, 0);
- priv->chan[0].publ = regmap_get_range(map, 1);
- priv->chan[1].pctl = regmap_get_range(map, 2);
- priv->chan[1].publ = regmap_get_range(map, 3);
-
- ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk);
+#ifdef CONFIG_SPL_BUILD
+ priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+ priv->chan[0].publ = regmap_get_range(plat->map, 1);
+ priv->chan[1].pctl = regmap_get_range(plat->map, 2);
+ priv->chan[1].publ = regmap_get_range(plat->map, 3);
+#endif
+ ret = rockchip_get_clk(&dev_clk);
if (ret)
return ret;
priv->ddr_clk.id = CLK_DDR;
@@ -898,10 +964,16 @@ static const struct udevice_id rk3288_dmc_ids[] = {
};
U_BOOT_DRIVER(dmc_rk3288) = {
- .name = "rk3288_dmc",
+ .name = "rockchip_rk3288_dmc",
.id = UCLASS_RAM,
.of_match = rk3288_dmc_ids,
.ops = &rk3288_dmc_ops,
+#ifdef CONFIG_SPL_BUILD
+ .ofdata_to_platdata = rk3288_dmc_ofdata_to_platdata,
+#endif
.probe = rk3288_dmc_probe,
.priv_auto_alloc_size = sizeof(struct dram_info),
+#ifdef CONFIG_SPL_BUILD
+ .platdata_auto_alloc_size = sizeof(struct rk3288_sdram_params),
+#endif
};
diff --git a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
index c9f7c4e32f..be4b2b00c3 100644
--- a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
@@ -23,3 +23,41 @@ U_BOOT_DRIVER(syscon_rk3288) = {
.id = UCLASS_SYSCON,
.of_match = rk3288_syscon_ids,
};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3288_syscon_bind_of_platdata(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3288_noc) = {
+ .name = "rockchip_rk3288_noc",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_grf) = {
+ .name = "rockchip_rk3288_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 1,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_sgrf) = {
+ .name = "rockchip_rk3288_sgrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 2,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_pmu) = {
+ .name = "rockchip_rk3288_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 3,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+#endif
diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
new file mode 100644
index 0000000000..83bd04add2
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -0,0 +1,23 @@
+if ROCKCHIP_RK3399
+
+choice
+ prompt "RK3399 board select"
+
+config TARGET_EVB_RK3399
+ bool "RK3399 evaluation board"
+ help
+ RK3399evb is a evaluation board for Rockchp rk3399,
+ with full function and phisical connectors support like type-C ports,
+ usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
+
+endchoice
+
+config SYS_SOC
+ default "rockchip"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+source "board/rockchip/evb_rk3399/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile
new file mode 100644
index 0000000000..3f219ac6f8
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += rk3399.o
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
new file mode 100644
index 0000000000..b9d7629407
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/armv8/mmu.h>
+
+static struct mm_region rk3399_mem_map[] = {
+ {
+ .virt = 0x0UL,
+ .phys = 0x0UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xf0000000UL,
+ .phys = 0xf0000000UL,
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = rk3399_mem_map;
diff --git a/arch/arm/mach-rockchip/rk3036/save_boot_param.S b/arch/arm/mach-rockchip/save_boot_param.S
index 778ec83c2c..85b407b4d3 100644
--- a/arch/arm/mach-rockchip/rk3036/save_boot_param.S
+++ b/arch/arm/mach-rockchip/save_boot_param.S
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2015 Google, Inc
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
diff --git a/arch/arm/mach-snapdragon/sysmap-apq8016.c b/arch/arm/mach-snapdragon/sysmap-apq8016.c
index ef0db2ab5f..580b9c7e61 100644
--- a/arch/arm/mach-snapdragon/sysmap-apq8016.c
+++ b/arch/arm/mach-snapdragon/sysmap-apq8016.c
@@ -11,13 +11,15 @@
static struct mm_region apq8016_mem_map[] = {
{
- .base = 0x0UL, /* Peripheral block */
+ .virt = 0x0UL, /* Peripheral block */
+ .phys = 0x0UL, /* Peripheral block */
.size = 0x8000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0x80000000UL, /* DDR */
+ .virt = 0x80000000UL, /* DDR */
+ .phys = 0x80000000UL, /* DDR */
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
diff --git a/arch/arm/mach-stm32/stm32f7/Makefile b/arch/arm/mach-stm32/stm32f7/Makefile
index 40f1ad35b7..643d4d919c 100644
--- a/arch/arm/mach-stm32/stm32f7/Makefile
+++ b/arch/arm/mach-stm32/stm32f7/Makefile
@@ -5,4 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y += timer.o clock.o
+obj-y += timer.o clock.o soc.o
diff --git a/arch/arm/mach-stm32/stm32f7/clock.c b/arch/arm/mach-stm32/stm32f7/clock.c
index 17a715bac9..78d22d40fd 100644
--- a/arch/arm/mach-stm32/stm32f7/clock.c
+++ b/arch/arm/mach-stm32/stm32f7/clock.c
@@ -11,6 +11,234 @@
#include <asm/arch/stm32.h>
#include <asm/arch/stm32_periph.h>
+#define RCC_CR_HSION (1 << 0)
+#define RCC_CR_HSEON (1 << 16)
+#define RCC_CR_HSERDY (1 << 17)
+#define RCC_CR_HSEBYP (1 << 18)
+#define RCC_CR_CSSON (1 << 19)
+#define RCC_CR_PLLON (1 << 24)
+#define RCC_CR_PLLRDY (1 << 25)
+
+#define RCC_PLLCFGR_PLLM_MASK 0x3F
+#define RCC_PLLCFGR_PLLN_MASK 0x7FC0
+#define RCC_PLLCFGR_PLLP_MASK 0x30000
+#define RCC_PLLCFGR_PLLQ_MASK 0xF000000
+#define RCC_PLLCFGR_PLLSRC (1 << 22)
+#define RCC_PLLCFGR_PLLM_SHIFT 0
+#define RCC_PLLCFGR_PLLN_SHIFT 6
+#define RCC_PLLCFGR_PLLP_SHIFT 16
+#define RCC_PLLCFGR_PLLQ_SHIFT 24
+
+#define RCC_CFGR_AHB_PSC_MASK 0xF0
+#define RCC_CFGR_APB1_PSC_MASK 0x1C00
+#define RCC_CFGR_APB2_PSC_MASK 0xE000
+#define RCC_CFGR_SW0 (1 << 0)
+#define RCC_CFGR_SW1 (1 << 1)
+#define RCC_CFGR_SW_MASK 0x3
+#define RCC_CFGR_SW_HSI 0
+#define RCC_CFGR_SW_HSE RCC_CFGR_SW0
+#define RCC_CFGR_SW_PLL RCC_CFGR_SW1
+#define RCC_CFGR_SWS0 (1 << 2)
+#define RCC_CFGR_SWS1 (1 << 3)
+#define RCC_CFGR_SWS_MASK 0xC
+#define RCC_CFGR_SWS_HSI 0
+#define RCC_CFGR_SWS_HSE RCC_CFGR_SWS0
+#define RCC_CFGR_SWS_PLL RCC_CFGR_SWS1
+#define RCC_CFGR_HPRE_SHIFT 4
+#define RCC_CFGR_PPRE1_SHIFT 10
+#define RCC_CFGR_PPRE2_SHIFT 13
+
+#define RCC_APB1ENR_PWREN (1 << 28)
+
+/*
+ * RCC USART specific definitions
+ */
+#define RCC_ENR_USART1EN (1 << 4)
+#define RCC_ENR_USART2EN (1 << 17)
+#define RCC_ENR_USART3EN (1 << 18)
+#define RCC_ENR_USART6EN (1 << 5)
+
+/*
+ * Offsets of some PWR registers
+ */
+#define PWR_CR1_ODEN (1 << 16)
+#define PWR_CR1_ODSWEN (1 << 17)
+#define PWR_CSR1_ODRDY (1 << 16)
+#define PWR_CSR1_ODSWRDY (1 << 17)
+
+
+/*
+ * RCC GPIO specific definitions
+ */
+#define RCC_ENR_GPIO_A_EN (1 << 0)
+#define RCC_ENR_GPIO_B_EN (1 << 1)
+#define RCC_ENR_GPIO_C_EN (1 << 2)
+#define RCC_ENR_GPIO_D_EN (1 << 3)
+#define RCC_ENR_GPIO_E_EN (1 << 4)
+#define RCC_ENR_GPIO_F_EN (1 << 5)
+#define RCC_ENR_GPIO_G_EN (1 << 6)
+#define RCC_ENR_GPIO_H_EN (1 << 7)
+#define RCC_ENR_GPIO_I_EN (1 << 8)
+#define RCC_ENR_GPIO_J_EN (1 << 9)
+#define RCC_ENR_GPIO_K_EN (1 << 10)
+
+struct pll_psc {
+ u8 pll_m;
+ u16 pll_n;
+ u8 pll_p;
+ u8 pll_q;
+ u8 ahb_psc;
+ u8 apb1_psc;
+ u8 apb2_psc;
+};
+
+#define AHB_PSC_1 0
+#define AHB_PSC_2 0x8
+#define AHB_PSC_4 0x9
+#define AHB_PSC_8 0xA
+#define AHB_PSC_16 0xB
+#define AHB_PSC_64 0xC
+#define AHB_PSC_128 0xD
+#define AHB_PSC_256 0xE
+#define AHB_PSC_512 0xF
+
+#define APB_PSC_1 0
+#define APB_PSC_2 0x4
+#define APB_PSC_4 0x5
+#define APB_PSC_8 0x6
+#define APB_PSC_16 0x7
+
+#if !defined(CONFIG_STM32_HSE_HZ)
+#error "CONFIG_STM32_HSE_HZ not defined!"
+#else
+#if (CONFIG_STM32_HSE_HZ == 25000000)
+#if (CONFIG_SYS_CLK_FREQ == 200000000)
+/* 200 MHz */
+struct pll_psc sys_pll_psc = {
+ .pll_m = 25,
+ .pll_n = 400,
+ .pll_p = 2,
+ .pll_q = 8,
+ .ahb_psc = AHB_PSC_1,
+ .apb1_psc = APB_PSC_4,
+ .apb2_psc = APB_PSC_2
+};
+#endif
+#else
+#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
+#endif
+#endif
+
+int configure_clocks(void)
+{
+ /* Reset RCC configuration */
+ setbits_le32(&STM32_RCC->cr, RCC_CR_HSION);
+ writel(0, &STM32_RCC->cfgr); /* Reset CFGR */
+ clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON
+ | RCC_CR_PLLON));
+ writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */
+ clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP);
+ writel(0, &STM32_RCC->cir); /* Disable all interrupts */
+
+ /* Configure for HSE+PLL operation */
+ setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON);
+ while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY))
+ ;
+
+ setbits_le32(&STM32_RCC->cfgr, ((
+ sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT)
+ | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
+ | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
+
+ /* Configure the main PLL */
+ uint32_t pllcfgr = 0;
+ pllcfgr = RCC_PLLCFGR_PLLSRC; /* pll source HSE */
+ pllcfgr |= sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT;
+ pllcfgr |= sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT;
+ pllcfgr |= ((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT;
+ pllcfgr |= sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT;
+ writel(pllcfgr, &STM32_RCC->pllcfgr);
+
+ /* Enable the main PLL */
+ setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON);
+ while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY))
+ ;
+
+ /* Enable high performance mode, System frequency up to 200 MHz */
+ setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN);
+ setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODEN);
+ /* Infinite wait! */
+ while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODRDY))
+ ;
+ /* Enable the Over-drive switch */
+ setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODSWEN);
+ /* Infinite wait! */
+ while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODSWRDY))
+ ;
+
+ stm32_flash_latency_cfg(5);
+ clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
+ setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL);
+
+ while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) !=
+ RCC_CFGR_SWS_PLL)
+ ;
+
+ return 0;
+}
+
+unsigned long clock_get(enum clock clck)
+{
+ u32 sysclk = 0;
+ u32 shift = 0;
+ /* Prescaler table lookups for clock computation */
+ u8 ahb_psc_table[16] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
+ };
+ u8 apb_psc_table[8] = {
+ 0, 0, 0, 0, 1, 2, 3, 4
+ };
+
+ if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) ==
+ RCC_CFGR_SWS_PLL) {
+ u16 pllm, plln, pllp;
+ pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
+ plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
+ >> RCC_PLLCFGR_PLLN_SHIFT);
+ pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
+ >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
+ sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp;
+ }
+
+ switch (clck) {
+ case CLOCK_CORE:
+ return sysclk;
+ break;
+ case CLOCK_AHB:
+ shift = ahb_psc_table[(
+ (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK)
+ >> RCC_CFGR_HPRE_SHIFT)];
+ return sysclk >>= shift;
+ break;
+ case CLOCK_APB1:
+ shift = apb_psc_table[(
+ (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK)
+ >> RCC_CFGR_PPRE1_SHIFT)];
+ return sysclk >>= shift;
+ break;
+ case CLOCK_APB2:
+ shift = apb_psc_table[(
+ (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK)
+ >> RCC_CFGR_PPRE2_SHIFT)];
+ return sysclk >>= shift;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+
void clock_setup(int peripheral)
{
switch (peripheral) {
diff --git a/arch/arm/mach-stm32/stm32f7/soc.c b/arch/arm/mach-stm32/stm32f7/soc.c
new file mode 100644
index 0000000000..8baee99a4f
--- /dev/null
+++ b/arch/arm/mach-stm32/stm32f7/soc.c
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/armv7m.h>
+#include <asm/arch/stm32.h>
+
+u32 get_cpu_rev(void)
+{
+ return 0;
+}
+
+int arch_cpu_init(void)
+{
+ configure_clocks();
+
+ /*
+ * Configure the memory protection unit (MPU)
+ * 0x00000000 - 0xffffffff: Strong-order, Shareable
+ * 0xC0000000 - 0xC0800000: Normal, Outer and inner Non-cacheable
+ */
+
+ /* Disable MPU */
+ writel(0, &V7M_MPU->ctrl);
+
+ writel(
+ 0x00000000 /* address */
+ | 1 << 4 /* VALID */
+ | 0 << 0 /* REGION */
+ , &V7M_MPU->rbar
+ );
+
+ /* Strong-order, Shareable */
+ /* TEX=000, S=1, C=0, B=0*/
+ writel(
+ (V7M_MPU_RASR_XN_ENABLE
+ | V7M_MPU_RASR_AP_RW_RW
+ | 0x01 << V7M_MPU_RASR_S_SHIFT
+ | 0x00 << V7M_MPU_RASR_TEX_SHIFT
+ | V7M_MPU_RASR_SIZE_4GB
+ | V7M_MPU_RASR_EN)
+ , &V7M_MPU->rasr
+ );
+
+ writel(
+ 0xC0000000 /* address */
+ | 1 << 4 /* VALID */
+ | 1 << 0 /* REGION */
+ , &V7M_MPU->rbar
+ );
+
+ /* Normal, Outer and inner Non-cacheable */
+ /* TEX=001, S=0, C=0, B=0*/
+ writel(
+ (V7M_MPU_RASR_XN_ENABLE
+ | V7M_MPU_RASR_AP_RW_RW
+ | 0x01 << V7M_MPU_RASR_TEX_SHIFT
+ | V7M_MPU_RASR_SIZE_8MB
+ | V7M_MPU_RASR_EN)
+ , &V7M_MPU->rasr
+ );
+
+ /* Enable MPU */
+ writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl);
+
+ return 0;
+}
+
+void s_init(void)
+{
+}
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 66e028ec14..6d9518d4c6 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -46,13 +46,15 @@ struct fel_stash fel_stash __attribute__((section(".data")));
static struct mm_region sunxi_mem_map[] = {
{
/* SRAM, MMIO regions */
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x40000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}, {
/* RAM */
- .base = 0x40000000UL,
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
@@ -203,7 +205,8 @@ DECLARE_GLOBAL_DATA_PTR;
*/
u32 spl_boot_device(void)
{
- __maybe_unused struct mmc *mmc0, *mmc1;
+ int boot_source;
+
/*
* When booting from the SD card or NAND memory, the "eGON.BT0"
* signature is expected to be found in memory at the address 0x0004
@@ -223,27 +226,19 @@ u32 spl_boot_device(void)
if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
return BOOT_DEVICE_BOARD;
- /* The BROM will try to boot from mmc0 first, so try that first. */
-#ifdef CONFIG_MMC
- mmc_initialize(gd->bd);
- mmc0 = find_mmc_device(0);
- if (sunxi_mmc_has_egon_boot_signature(mmc0))
+ boot_source = readb(SPL_ADDR + 0x28);
+ switch (boot_source) {
+ case SUNXI_BOOTED_FROM_MMC0:
return BOOT_DEVICE_MMC1;
-#endif
-
- /* Fallback to booting NAND if enabled. */
- if (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT))
+ case SUNXI_BOOTED_FROM_NAND:
return BOOT_DEVICE_NAND;
-
-#ifdef CONFIG_MMC
- if (CONFIG_MMC_SUNXI_SLOT_EXTRA == 2) {
- mmc1 = find_mmc_device(1);
- if (sunxi_mmc_has_egon_boot_signature(mmc1))
- return BOOT_DEVICE_MMC2;
+ case SUNXI_BOOTED_FROM_MMC2:
+ return BOOT_DEVICE_MMC2;
+ case SUNXI_BOOTED_FROM_SPI:
+ return BOOT_DEVICE_SPI;
}
-#endif
- panic("Could not determine boot source\n");
+ panic("Unknown boot source %d\n", boot_source);
return -1; /* Never reached */
}
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index f4affa5512..85ae3b7f42 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -1,5 +1,13 @@
if TEGRA
+config TEGRA_IVC
+ bool "Tegra IVC protocol"
+ help
+ IVC (Inter-VM Communication) protocol is a Tegra-specific IPC
+ (Inter Processor Communication) framework. Within the context of
+ U-Boot, it is typically used for communication between the main CPU
+ and various auxiliary processors.
+
config TEGRA_COMMON
bool "Tegra common options"
select DM
@@ -60,6 +68,7 @@ config TEGRA186
select TEGRA186_GPIO
select TEGRA_ARMV8_COMMON
select TEGRA_HSP
+ select TEGRA_IVC
endchoice
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 12ee1cd749..d0bf5a6e75 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -15,23 +15,24 @@ else
obj-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o
endif
-obj-$(CONFIG_ARM64) += arm64-mmu.o
obj-y += ap.o
obj-y += board.o board2.o
obj-y += cache.o
obj-y += clock.o
-obj-y += lowlevel_init.o
obj-y += pinmux-common.o
obj-y += powergate.o
obj-y += xusb-padctl-dummy.o
-obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
-obj-$(CONFIG_TEGRA_GPU) += gpu.o
-obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
+endif
+obj-$(CONFIG_ARM64) += arm64-mmu.o
+obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
+obj-$(CONFIG_TEGRA_GPU) += gpu.o
+obj-$(CONFIG_TEGRA_IVC) += ivc.o
+obj-y += lowlevel_init.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ARMV7_PSCI) += psci.o
endif
-endif
+obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
obj-$(CONFIG_TEGRA20) += tegra20/
obj-$(CONFIG_TEGRA30) += tegra30/
diff --git a/arch/arm/mach-tegra/arm64-mmu.c b/arch/arm/mach-tegra/arm64-mmu.c
index 501c4f00c4..7b1d258ed8 100644
--- a/arch/arm/mach-tegra/arm64-mmu.c
+++ b/arch/arm/mach-tegra/arm64-mmu.c
@@ -14,13 +14,15 @@
static struct mm_region tegra_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0xff80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
diff --git a/arch/arm/mach-tegra/board186.c b/arch/arm/mach-tegra/board186.c
index f4b6152a79..876ccba5e5 100644
--- a/arch/arm/mach-tegra/board186.c
+++ b/arch/arm/mach-tegra/board186.c
@@ -11,12 +11,6 @@
DECLARE_GLOBAL_DATA_PTR;
-int dram_init(void)
-{
- gd->ram_size = (1.5 * 1024 * 1024 * 1024);
- return 0;
-}
-
int board_early_init_f(void)
{
return 0;
@@ -32,12 +26,6 @@ int board_late_init(void)
return 0;
}
-void dram_init_banksize(void)
-{
- gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
- gd->bd->bi_dram[0].size = gd->ram_size;
-}
-
void pad_init_mmc(struct mmc_host *host)
{
}
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index c50d56dc88..36eabc8f57 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -510,7 +510,7 @@ unsigned clock_get_rate(enum clock_id clkid)
* @param p post divider(DIVP)
* @param cpcon base PLL charge pump(CPCON)
* @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
- * be overriden), 1 if PLL is already correct
+ * be overridden), 1 if PLL is already correct
*/
int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
{
diff --git a/arch/arm/mach-tegra/ivc.c b/arch/arm/mach-tegra/ivc.c
new file mode 100644
index 0000000000..cf6626fb12
--- /dev/null
+++ b/arch/arm/mach-tegra/ivc.c
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch-tegra/ivc.h>
+
+#define TEGRA_IVC_ALIGN 64
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum ivc_state {
+ /*
+ * This value is zero for backwards compatibility with services that
+ * assume channels to be initially zeroed. Such channels are in an
+ * initially valid state, but cannot be asynchronously reset, and must
+ * maintain a valid state at all times.
+ *
+ * The transmitting end can enter the established state from the sync or
+ * ack state when it observes the receiving endpoint in the ack or
+ * established state, indicating that has cleared the counters in our
+ * rx_channel.
+ */
+ ivc_state_established = 0,
+
+ /*
+ * If an endpoint is observed in the sync state, the remote endpoint is
+ * allowed to clear the counters it owns asynchronously with respect to
+ * the current endpoint. Therefore, the current endpoint is no longer
+ * allowed to communicate.
+ */
+ ivc_state_sync,
+
+ /*
+ * When the transmitting end observes the receiving end in the sync
+ * state, it can clear the w_count and r_count and transition to the ack
+ * state. If the remote endpoint observes us in the ack state, it can
+ * return to the established state once it has cleared its counters.
+ */
+ ivc_state_ack
+};
+
+/*
+ * This structure is divided into two-cache aligned parts, the first is only
+ * written through the tx_channel pointer, while the second is only written
+ * through the rx_channel pointer. This delineates ownership of the cache lines,
+ * which is critical to performance and necessary in non-cache coherent
+ * implementations.
+ */
+struct tegra_ivc_channel_header {
+ union {
+ /* fields owned by the transmitting end */
+ struct {
+ uint32_t w_count;
+ uint32_t state;
+ };
+ uint8_t w_align[TEGRA_IVC_ALIGN];
+ };
+ union {
+ /* fields owned by the receiving end */
+ uint32_t r_count;
+ uint8_t r_align[TEGRA_IVC_ALIGN];
+ };
+};
+
+static inline void tegra_ivc_invalidate_counter(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *h,
+ ulong offset)
+{
+ ulong base = ((ulong)h) + offset;
+ invalidate_dcache_range(base, base + TEGRA_IVC_ALIGN);
+}
+
+static inline void tegra_ivc_flush_counter(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *h,
+ ulong offset)
+{
+ ulong base = ((ulong)h) + offset;
+ flush_dcache_range(base, base + TEGRA_IVC_ALIGN);
+}
+
+static inline ulong tegra_ivc_frame_addr(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *h,
+ uint32_t frame)
+{
+ BUG_ON(frame >= ivc->nframes);
+
+ return ((ulong)h) + sizeof(struct tegra_ivc_channel_header) +
+ (ivc->frame_size * frame);
+}
+
+static inline void *tegra_ivc_frame_pointer(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *ch,
+ uint32_t frame)
+{
+ return (void *)tegra_ivc_frame_addr(ivc, ch, frame);
+}
+
+static inline void tegra_ivc_invalidate_frame(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *h,
+ unsigned frame)
+{
+ ulong base = tegra_ivc_frame_addr(ivc, h, frame);
+ invalidate_dcache_range(base, base + ivc->frame_size);
+}
+
+static inline void tegra_ivc_flush_frame(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *h,
+ unsigned frame)
+{
+ ulong base = tegra_ivc_frame_addr(ivc, h, frame);
+ flush_dcache_range(base, base + ivc->frame_size);
+}
+
+static inline int tegra_ivc_channel_empty(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *ch)
+{
+ /*
+ * This function performs multiple checks on the same values with
+ * security implications, so create snapshots with ACCESS_ONCE() to
+ * ensure that these checks use the same values.
+ */
+ uint32_t w_count = ACCESS_ONCE(ch->w_count);
+ uint32_t r_count = ACCESS_ONCE(ch->r_count);
+
+ /*
+ * Perform an over-full check to prevent denial of service attacks where
+ * a server could be easily fooled into believing that there's an
+ * extremely large number of frames ready, since receivers are not
+ * expected to check for full or over-full conditions.
+ *
+ * Although the channel isn't empty, this is an invalid case caused by
+ * a potentially malicious peer, so returning empty is safer, because it
+ * gives the impression that the channel has gone silent.
+ */
+ if (w_count - r_count > ivc->nframes)
+ return 1;
+
+ return w_count == r_count;
+}
+
+static inline int tegra_ivc_channel_full(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *ch)
+{
+ /*
+ * Invalid cases where the counters indicate that the queue is over
+ * capacity also appear full.
+ */
+ return (ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count)) >=
+ ivc->nframes;
+}
+
+static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
+{
+ ACCESS_ONCE(ivc->rx_channel->r_count) =
+ ACCESS_ONCE(ivc->rx_channel->r_count) + 1;
+
+ if (ivc->r_pos == ivc->nframes - 1)
+ ivc->r_pos = 0;
+ else
+ ivc->r_pos++;
+}
+
+static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc)
+{
+ ACCESS_ONCE(ivc->tx_channel->w_count) =
+ ACCESS_ONCE(ivc->tx_channel->w_count) + 1;
+
+ if (ivc->w_pos == ivc->nframes - 1)
+ ivc->w_pos = 0;
+ else
+ ivc->w_pos++;
+}
+
+static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
+{
+ ulong offset;
+
+ /*
+ * tx_channel->state is set locally, so it is not synchronized with
+ * state from the remote peer. The remote peer cannot reset its
+ * transmit counters until we've acknowledged its synchronization
+ * request, so no additional synchronization is required because an
+ * asynchronous transition of rx_channel->state to ivc_state_ack is not
+ * allowed.
+ */
+ if (ivc->tx_channel->state != ivc_state_established)
+ return -ECONNRESET;
+
+ /*
+ * Avoid unnecessary invalidations when performing repeated accesses to
+ * an IVC channel by checking the old queue pointers first.
+ * Synchronization is only necessary when these pointers indicate empty
+ * or full.
+ */
+ if (!tegra_ivc_channel_empty(ivc, ivc->rx_channel))
+ return 0;
+
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
+ return tegra_ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0;
+}
+
+static inline int tegra_ivc_check_write(struct tegra_ivc *ivc)
+{
+ ulong offset;
+
+ if (ivc->tx_channel->state != ivc_state_established)
+ return -ECONNRESET;
+
+ if (!tegra_ivc_channel_full(ivc, ivc->tx_channel))
+ return 0;
+
+ offset = offsetof(struct tegra_ivc_channel_header, r_count);
+ tegra_ivc_invalidate_counter(ivc, ivc->tx_channel, offset);
+ return tegra_ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0;
+}
+
+static inline uint32_t tegra_ivc_channel_avail_count(struct tegra_ivc *ivc,
+ struct tegra_ivc_channel_header *ch)
+{
+ /*
+ * This function isn't expected to be used in scenarios where an
+ * over-full situation can lead to denial of service attacks. See the
+ * comment in tegra_ivc_channel_empty() for an explanation about
+ * special over-full considerations.
+ */
+ return ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count);
+}
+
+int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame)
+{
+ int result = tegra_ivc_check_read(ivc);
+ if (result < 0)
+ return result;
+
+ /*
+ * Order observation of w_pos potentially indicating new data before
+ * data read.
+ */
+ mb();
+
+ tegra_ivc_invalidate_frame(ivc, ivc->rx_channel, ivc->r_pos);
+ *frame = tegra_ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+
+ return 0;
+}
+
+int tegra_ivc_read_advance(struct tegra_ivc *ivc)
+{
+ ulong offset;
+ int result;
+
+ /*
+ * No read barriers or synchronization here: the caller is expected to
+ * have already observed the channel non-empty. This check is just to
+ * catch programming errors.
+ */
+ result = tegra_ivc_check_read(ivc);
+ if (result)
+ return result;
+
+ tegra_ivc_advance_rx(ivc);
+ offset = offsetof(struct tegra_ivc_channel_header, r_count);
+ tegra_ivc_flush_counter(ivc, ivc->rx_channel, offset);
+
+ /*
+ * Ensure our write to r_pos occurs before our read from w_pos.
+ */
+ mb();
+
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
+
+ if (tegra_ivc_channel_avail_count(ivc, ivc->rx_channel) ==
+ ivc->nframes - 1)
+ ivc->notify(ivc);
+
+ return 0;
+}
+
+int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, void **frame)
+{
+ int result = tegra_ivc_check_write(ivc);
+ if (result)
+ return result;
+
+ *frame = tegra_ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+
+ return 0;
+}
+
+int tegra_ivc_write_advance(struct tegra_ivc *ivc)
+{
+ ulong offset;
+ int result;
+
+ result = tegra_ivc_check_write(ivc);
+ if (result)
+ return result;
+
+ tegra_ivc_flush_frame(ivc, ivc->tx_channel, ivc->w_pos);
+
+ /*
+ * Order any possible stores to the frame before update of w_pos.
+ */
+ mb();
+
+ tegra_ivc_advance_tx(ivc);
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+ /*
+ * Ensure our write to w_pos occurs before our read from r_pos.
+ */
+ mb();
+
+ offset = offsetof(struct tegra_ivc_channel_header, r_count);
+ tegra_ivc_invalidate_counter(ivc, ivc->tx_channel, offset);
+
+ if (tegra_ivc_channel_avail_count(ivc, ivc->tx_channel) == 1)
+ ivc->notify(ivc);
+
+ return 0;
+}
+
+/*
+ * ===============================================================
+ * IVC State Transition Table - see tegra_ivc_channel_notified()
+ * ===============================================================
+ *
+ * local remote action
+ * ----- ------ -----------------------------------
+ * SYNC EST <none>
+ * SYNC ACK reset counters; move to EST; notify
+ * SYNC SYNC reset counters; move to ACK; notify
+ * ACK EST move to EST; notify
+ * ACK ACK move to EST; notify
+ * ACK SYNC reset counters; move to ACK; notify
+ * EST EST <none>
+ * EST ACK <none>
+ * EST SYNC reset counters; move to ACK; notify
+ *
+ * ===============================================================
+ */
+int tegra_ivc_channel_notified(struct tegra_ivc *ivc)
+{
+ ulong offset;
+ enum ivc_state peer_state;
+
+ /* Copy the receiver's state out of shared memory. */
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
+ peer_state = ACCESS_ONCE(ivc->rx_channel->state);
+
+ if (peer_state == ivc_state_sync) {
+ /*
+ * Order observation of ivc_state_sync before stores clearing
+ * tx_channel.
+ */
+ mb();
+
+ /*
+ * Reset tx_channel counters. The remote end is in the SYNC
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx_channel->w_count = 0;
+ ivc->rx_channel->r_count = 0;
+
+ ivc->w_pos = 0;
+ ivc->r_pos = 0;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ mb();
+
+ /*
+ * Move to ACK state. We have just cleared our counters, so it
+ * is now safe for the remote end to start using these values.
+ */
+ ivc->tx_channel->state = ivc_state_ack;
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+ } else if (ivc->tx_channel->state == ivc_state_sync &&
+ peer_state == ivc_state_ack) {
+ /*
+ * Order observation of ivc_state_sync before stores clearing
+ * tx_channel.
+ */
+ mb();
+
+ /*
+ * Reset tx_channel counters. The remote end is in the ACK
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx_channel->w_count = 0;
+ ivc->rx_channel->r_count = 0;
+
+ ivc->w_pos = 0;
+ ivc->r_pos = 0;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ mb();
+
+ /*
+ * Move to ESTABLISHED state. We know that the remote end has
+ * already cleared its counters, so it is safe to start
+ * writing/reading on this channel.
+ */
+ ivc->tx_channel->state = ivc_state_established;
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+ } else if (ivc->tx_channel->state == ivc_state_ack) {
+ /*
+ * At this point, we have observed the peer to be in either
+ * the ACK or ESTABLISHED state. Next, order observation of
+ * peer state before storing to tx_channel.
+ */
+ mb();
+
+ /*
+ * Move to ESTABLISHED state. We know that we have previously
+ * cleared our counters, and we know that the remote end has
+ * cleared its counters, so it is safe to start writing/reading
+ * on this channel.
+ */
+ ivc->tx_channel->state = ivc_state_established;
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+ } else {
+ /*
+ * There is no need to handle any further action. Either the
+ * channel is already fully established, or we are waiting for
+ * the remote end to catch up with our current state. Refer
+ * to the diagram in "IVC State Transition Table" above.
+ */
+ }
+
+ if (ivc->tx_channel->state != ivc_state_established)
+ return -EAGAIN;
+
+ return 0;
+}
+
+void tegra_ivc_channel_reset(struct tegra_ivc *ivc)
+{
+ ulong offset;
+
+ ivc->tx_channel->state = ivc_state_sync;
+ offset = offsetof(struct tegra_ivc_channel_header, w_count);
+ tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+ ivc->notify(ivc);
+}
+
+static int check_ivc_params(ulong qbase1, ulong qbase2, uint32_t nframes,
+ uint32_t frame_size)
+{
+ int ret = 0;
+
+ BUG_ON(offsetof(struct tegra_ivc_channel_header, w_count) &
+ (TEGRA_IVC_ALIGN - 1));
+ BUG_ON(offsetof(struct tegra_ivc_channel_header, r_count) &
+ (TEGRA_IVC_ALIGN - 1));
+ BUG_ON(sizeof(struct tegra_ivc_channel_header) &
+ (TEGRA_IVC_ALIGN - 1));
+
+ if ((uint64_t)nframes * (uint64_t)frame_size >= 0x100000000) {
+ error("tegra_ivc: nframes * frame_size overflows\n");
+ return -EINVAL;
+ }
+
+ /*
+ * The headers must at least be aligned enough for counters
+ * to be accessed atomically.
+ */
+ if ((qbase1 & (TEGRA_IVC_ALIGN - 1)) ||
+ (qbase2 & (TEGRA_IVC_ALIGN - 1))) {
+ error("tegra_ivc: channel start not aligned\n");
+ return -EINVAL;
+ }
+
+ if (frame_size & (TEGRA_IVC_ALIGN - 1)) {
+ error("tegra_ivc: frame size not adequately aligned\n");
+ return -EINVAL;
+ }
+
+ if (qbase1 < qbase2) {
+ if (qbase1 + frame_size * nframes > qbase2)
+ ret = -EINVAL;
+ } else {
+ if (qbase2 + frame_size * nframes > qbase1)
+ ret = -EINVAL;
+ }
+
+ if (ret) {
+ error("tegra_ivc: queue regions overlap\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int tegra_ivc_init(struct tegra_ivc *ivc, ulong rx_base, ulong tx_base,
+ uint32_t nframes, uint32_t frame_size,
+ void (*notify)(struct tegra_ivc *))
+{
+ int ret;
+
+ if (!ivc)
+ return -EINVAL;
+
+ ret = check_ivc_params(rx_base, tx_base, nframes, frame_size);
+ if (ret)
+ return ret;
+
+ ivc->rx_channel = (struct tegra_ivc_channel_header *)rx_base;
+ ivc->tx_channel = (struct tegra_ivc_channel_header *)tx_base;
+ ivc->w_pos = 0;
+ ivc->r_pos = 0;
+ ivc->nframes = nframes;
+ ivc->frame_size = frame_size;
+ ivc->notify = notify;
+
+ return 0;
+}
diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S
index b836da1c0e..645d08fa0b 100644
--- a/arch/arm/mach-tegra/psci.S
+++ b/arch/arm/mach-tegra/psci.S
@@ -61,9 +61,6 @@ ENTRY(psci_arch_init)
ldrne r7, [r5]
mcrne p15, 0, r7, c14, c0, 0 @ write CNTFRQ to CPU1..3
- bl psci_get_cpu_stack_top @ stack top => r0
- mov sp, r0
-
bx r6
ENDPROC(psci_arch_init)
@@ -88,12 +85,13 @@ _loop: wfi
ENDPROC(psci_cpu_off)
ENTRY(psci_cpu_on)
- push {lr}
+ push {r4, r5, r6, lr}
+ mov r4, r1
mov r0, r1
- bl psci_get_cpu_stack_top @ get stack top of target CPU
- str r2, [r0] @ store target PC at stack top
- dsb
+ mov r1, r2
+ bl psci_save_target_pc @ store target PC
+ mov r1, r4
ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR
ldr r5, =psci_cpu_entry
@@ -106,9 +104,7 @@ ENTRY(psci_cpu_on)
str r5, [r6, r2]
mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS
- pop {pc}
+ pop {r4, r5, r6, pc}
ENDPROC(psci_cpu_on)
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/mach-tegra/tegra186/Makefile b/arch/arm/mach-tegra/tegra186/Makefile
index ce4610d8f8..033d6005fb 100644
--- a/arch/arm/mach-tegra/tegra186/Makefile
+++ b/arch/arm/mach-tegra/tegra186/Makefile
@@ -2,7 +2,6 @@
#
# SPDX-License-Identifier: GPL-2.0
-obj-y += ../arm64-mmu.o
obj-y += ../board186.o
-obj-y += ../lowlevel_init.o
-obj-$(CONFIG_DISPLAY_CPUINFO) += ../sys_info.o
+obj-y += nvtboot_ll.o
+obj-y += nvtboot_mem.o
diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_ll.S b/arch/arm/mach-tegra/tegra186/nvtboot_ll.S
new file mode 100644
index 0000000000..1eab890958
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra186/nvtboot_ll.S
@@ -0,0 +1,20 @@
+/*
+ * Save nvtboot-related boot-time CPU state
+ *
+ * (C) Copyright 2015-2016 NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+.globl nvtboot_boot_x0
+nvtboot_boot_x0:
+ .dword 0
+
+ENTRY(save_boot_params)
+ adr x8, nvtboot_boot_x0
+ str x0, [x8]
+ b save_boot_params_ret
+ENDPROC(save_boot_params)
diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c
new file mode 100644
index 0000000000..37dd8d4334
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdt_support.h>
+#include <fdtdec.h>
+#include <asm/arch/tegra.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern unsigned long nvtboot_boot_x0;
+
+/*
+ * A parsed version of /memory/reg from the DTB that is passed to U-Boot in x0.
+ *
+ * We only support up to two banks since that's all the binary bootloader
+ * ever sets. We assume bank 0 is RAM below 4G and bank 1 is RAM above 4G.
+ * This is all a fairly safe assumption, since the L4T kernel makes the same
+ * assumptions, so the bootloader is unlikely to change.
+ *
+ * This is written to before relocation, and hence cannot be in .bss, since
+ * .bss overlaps the DTB that's appended to the U-Boot binary. The initializer
+ * forces this into .data and avoids this issue. This also has the nice side-
+ * effect of the content being valid after relocation.
+ */
+static struct {
+ u64 start;
+ u64 size;
+} ram_banks[2] = {{1}};
+
+int dram_init(void)
+{
+ unsigned int na, ns;
+ const void *nvtboot_blob = (void *)nvtboot_boot_x0;
+ int node, len, i;
+ const u32 *prop;
+
+ memset(ram_banks, 0, sizeof(ram_banks));
+
+ na = fdtdec_get_uint(nvtboot_blob, 0, "#address-cells", 2);
+ ns = fdtdec_get_uint(nvtboot_blob, 0, "#size-cells", 2);
+
+ node = fdt_path_offset(nvtboot_blob, "/memory");
+ if (node < 0) {
+ error("Can't find /memory node in nvtboot DTB");
+ hang();
+ }
+ prop = fdt_getprop(nvtboot_blob, node, "reg", &len);
+ if (!prop) {
+ error("Can't find /memory/reg property in nvtboot DTB");
+ hang();
+ }
+
+ len /= (na + ns);
+ if (len > ARRAY_SIZE(ram_banks))
+ len = ARRAY_SIZE(ram_banks);
+
+ gd->ram_size = 0;
+ for (i = 0; i < len; i++) {
+ ram_banks[i].start = of_read_number(prop, na);
+ prop += na;
+ ram_banks[i].size = of_read_number(prop, ns);
+ prop += ns;
+ gd->ram_size += ram_banks[i].size;
+ }
+
+ return 0;
+}
+
+extern unsigned long nvtboot_boot_x0;
+
+void dram_init_banksize(void)
+{
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ gd->bd->bi_dram[i].start = ram_banks[i].start;
+ gd->bd->bi_dram[i].size = ram_banks[i].size;
+ }
+}
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+ return ram_banks[0].start + ram_banks[0].size;
+}
diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig
index e256eeb668..e39ced674f 100644
--- a/arch/arm/mach-uniphier/Kconfig
+++ b/arch/arm/mach-uniphier/Kconfig
@@ -12,6 +12,7 @@ config ARCH_UNIPHIER_64BIT
select ARM64
select SPL_SEPARATE_BSS
select ARMV8_MULTIENTRY
+ select ARMV8_SPIN_TABLE
choice
prompt "UniPhier SoC select"
diff --git a/arch/arm/mach-uniphier/arm32/Makefile b/arch/arm/mach-uniphier/arm32/Makefile
index 376c06b597..5074ebda97 100644
--- a/arch/arm/mach-uniphier/arm32/Makefile
+++ b/arch/arm/mach-uniphier/arm32/Makefile
@@ -7,7 +7,7 @@ obj-y += lowlevel_init.o
obj-$(CONFIG_DEBUG_LL) += debug_ll.o
else
obj-y += late_lowlevel_init.o
-obj-y += cache_uniphier.o
+obj-y += cache-uniphier.o
endif
obj-y += timer.o
diff --git a/arch/arm/mach-uniphier/arm32/cache-uniphier.c b/arch/arm/mach-uniphier/arm32/cache-uniphier.c
new file mode 100644
index 0000000000..76fe5ebe09
--- /dev/null
+++ b/arch/arm/mach-uniphier/arm32/cache-uniphier.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2012-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <asm/armv7.h>
+
+#include "ssc-regs.h"
+
+#ifdef CONFIG_UNIPHIER_L2CACHE_ON
+static void uniphier_cache_sync(void)
+{
+ /* drain internal buffers */
+ writel(UNIPHIER_SSCOPE_CM_SYNC, UNIPHIER_SSCOPE);
+ /* need a read back to confirm */
+ readl(UNIPHIER_SSCOPE);
+}
+
+static void uniphier_cache_maint_all(u32 operation)
+{
+ /* clear the complete notification flag */
+ writel(UNIPHIER_SSCOLPQS_EF, UNIPHIER_SSCOLPQS);
+
+ /* try until the command is successfully set */
+ do {
+ writel(UNIPHIER_SSCOQM_S_ALL | UNIPHIER_SSCOQM_CE | operation,
+ UNIPHIER_SSCOQM);
+ } while (readl(UNIPHIER_SSCOPPQSEF) &
+ (UNIPHIER_SSCOPPQSEF_FE | UNIPHIER_SSCOPPQSEF_OE));
+
+ /* wait until the operation is completed */
+ while (readl(UNIPHIER_SSCOLPQS) != UNIPHIER_SSCOLPQS_EF)
+ ;
+
+ uniphier_cache_sync();
+}
+
+void v7_outer_cache_flush_all(void)
+{
+ uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+void v7_outer_cache_inval_all(void)
+{
+ uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_INV);
+}
+
+static void __uniphier_cache_maint_range(u32 start, u32 size, u32 operation)
+{
+ /* clear the complete notification flag */
+ writel(UNIPHIER_SSCOLPQS_EF, UNIPHIER_SSCOLPQS);
+
+ /* try until the command is successfully set */
+ do {
+ writel(UNIPHIER_SSCOQM_S_RANGE | UNIPHIER_SSCOQM_CE | operation,
+ UNIPHIER_SSCOQM);
+ writel(start, UNIPHIER_SSCOQAD);
+ writel(size, UNIPHIER_SSCOQSZ);
+
+ } while (readl(UNIPHIER_SSCOPPQSEF) &
+ (UNIPHIER_SSCOPPQSEF_FE | UNIPHIER_SSCOPPQSEF_OE));
+
+ /* wait until the operation is completed */
+ while (readl(UNIPHIER_SSCOLPQS) != UNIPHIER_SSCOLPQS_EF)
+ ;
+}
+
+static void uniphier_cache_maint_range(u32 start, u32 end, u32 operation)
+{
+ u32 size;
+
+ /*
+ * If start address is not aligned to cache-line,
+ * do cache operation for the first cache-line
+ */
+ start = start & ~(UNIPHIER_SSC_LINE_SIZE - 1);
+
+ size = end - start;
+
+ if (unlikely(size >= (u32)(-UNIPHIER_SSC_LINE_SIZE))) {
+ /* this means cache operation for all range */
+ uniphier_cache_maint_all(operation);
+ return;
+ }
+
+ /*
+ * If end address is not aligned to cache-line,
+ * do cache operation for the last cache-line
+ */
+ size = ALIGN(size, UNIPHIER_SSC_LINE_SIZE);
+
+ while (size) {
+ u32 chunk_size = size > UNIPHIER_SSC_RANGE_OP_MAX_SIZE ?
+ UNIPHIER_SSC_RANGE_OP_MAX_SIZE : size;
+ __uniphier_cache_maint_range(start, chunk_size, operation);
+
+ start += chunk_size;
+ size -= chunk_size;
+ }
+
+ uniphier_cache_sync();
+}
+
+void v7_outer_cache_flush_range(u32 start, u32 end)
+{
+ uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+void v7_outer_cache_inval_range(u32 start, u32 end)
+{
+ if (start & (UNIPHIER_SSC_LINE_SIZE - 1)) {
+ start &= ~(UNIPHIER_SSC_LINE_SIZE - 1);
+ __uniphier_cache_maint_range(start, UNIPHIER_SSC_LINE_SIZE,
+ UNIPHIER_SSCOQM_CM_FLUSH);
+ start += UNIPHIER_SSC_LINE_SIZE;
+ }
+
+ if (start >= end) {
+ uniphier_cache_sync();
+ return;
+ }
+
+ if (end & (UNIPHIER_SSC_LINE_SIZE - 1)) {
+ end &= ~(UNIPHIER_SSC_LINE_SIZE - 1);
+ __uniphier_cache_maint_range(end, UNIPHIER_SSC_LINE_SIZE,
+ UNIPHIER_SSCOQM_CM_FLUSH);
+ }
+
+ if (start >= end) {
+ uniphier_cache_sync();
+ return;
+ }
+
+ uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_INV);
+}
+
+void v7_outer_cache_enable(void)
+{
+ u32 tmp;
+
+ writel(U32_MAX, UNIPHIER_SSCLPDAWCR); /* activate all ways */
+ tmp = readl(UNIPHIER_SSCC);
+ tmp |= UNIPHIER_SSCC_ON;
+ writel(tmp, UNIPHIER_SSCC);
+}
+#endif
+
+void v7_outer_cache_disable(void)
+{
+ u32 tmp;
+
+ tmp = readl(UNIPHIER_SSCC);
+ tmp &= ~UNIPHIER_SSCC_ON;
+ writel(tmp, UNIPHIER_SSCC);
+}
+
+void enable_caches(void)
+{
+ dcache_enable();
+}
diff --git a/arch/arm/mach-uniphier/arm32/cache_uniphier.c b/arch/arm/mach-uniphier/arm32/cache_uniphier.c
deleted file mode 100644
index 4398114658..0000000000
--- a/arch/arm/mach-uniphier/arm32/cache_uniphier.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <linux/io.h>
-#include <asm/armv7.h>
-
-#include "ssc-regs.h"
-
-#ifdef CONFIG_UNIPHIER_L2CACHE_ON
-static void uniphier_cache_sync(void)
-{
- writel(SSCOPE_CM_SYNC, SSCOPE); /* drain internal buffers */
- readl(SSCOPE); /* need a read back to confirm */
-}
-
-static void uniphier_cache_maint_all(u32 operation)
-{
- /* try until the command is successfully set */
- do {
- writel(SSCOQM_S_ALL | SSCOQM_CE | operation, SSCOQM);
- } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
-
- /* wait until the operation is completed */
- while (readl(SSCOLPQS) != SSCOLPQS_EF)
- ;
-
- /* clear the complete notification flag */
- writel(SSCOLPQS_EF, SSCOLPQS);
-
- uniphier_cache_sync();
-}
-
-void v7_outer_cache_flush_all(void)
-{
- uniphier_cache_maint_all(SSCOQM_CM_WB_INV);
-}
-
-void v7_outer_cache_inval_all(void)
-{
- uniphier_cache_maint_all(SSCOQM_CM_INV);
-}
-
-static void __uniphier_cache_maint_range(u32 start, u32 size, u32 operation)
-{
- /* try until the command is successfully set */
- do {
- writel(SSCOQM_S_ADDRESS | SSCOQM_CE | operation, SSCOQM);
- writel(start, SSCOQAD);
- writel(size, SSCOQSZ);
-
- } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
-
- /* wait until the operation is completed */
- while (readl(SSCOLPQS) != SSCOLPQS_EF)
- ;
-
- /* clear the complete notification flag */
- writel(SSCOLPQS_EF, SSCOLPQS);
-}
-
-static void uniphier_cache_maint_range(u32 start, u32 end, u32 operation)
-{
- u32 size;
-
- /*
- * If start address is not aligned to cache-line,
- * do cache operation for the first cache-line
- */
- start = start & ~(SSC_LINE_SIZE - 1);
-
- size = end - start;
-
- if (unlikely(size >= (u32)(-SSC_LINE_SIZE))) {
- /* this means cache operation for all range */
- uniphier_cache_maint_all(operation);
- return;
- }
-
- /*
- * If end address is not aligned to cache-line,
- * do cache operation for the last cache-line
- */
- size = ALIGN(size, SSC_LINE_SIZE);
-
- while (size) {
- u32 chunk_size = size > SSC_RANGE_OP_MAX_SIZE ?
- SSC_RANGE_OP_MAX_SIZE : size;
- __uniphier_cache_maint_range(start, chunk_size, operation);
-
- start += chunk_size;
- size -= chunk_size;
- }
-
- uniphier_cache_sync();
-}
-
-void v7_outer_cache_flush_range(u32 start, u32 end)
-{
- uniphier_cache_maint_range(start, end, SSCOQM_CM_WB_INV);
-}
-
-void v7_outer_cache_inval_range(u32 start, u32 end)
-{
- if (start & (SSC_LINE_SIZE - 1)) {
- start &= ~(SSC_LINE_SIZE - 1);
- __uniphier_cache_maint_range(start, SSC_LINE_SIZE,
- SSCOQM_CM_WB_INV);
- start += SSC_LINE_SIZE;
- }
-
- if (start >= end) {
- uniphier_cache_sync();
- return;
- }
-
- if (end & (SSC_LINE_SIZE - 1)) {
- end &= ~(SSC_LINE_SIZE - 1);
- __uniphier_cache_maint_range(end, SSC_LINE_SIZE,
- SSCOQM_CM_WB_INV);
- }
-
- if (start >= end) {
- uniphier_cache_sync();
- return;
- }
-
- uniphier_cache_maint_range(start, end, SSCOQM_CM_INV);
-}
-
-void v7_outer_cache_enable(void)
-{
- u32 tmp;
-
- writel(U32_MAX, SSCLPDAWCR); /* activate all ways */
- tmp = readl(SSCC);
- tmp |= SSCC_ON;
- writel(tmp, SSCC);
-}
-#endif
-
-void v7_outer_cache_disable(void)
-{
- u32 tmp;
- tmp = readl(SSCC);
- tmp &= ~SSCC_ON;
- writel(tmp, SSCC);
-}
-
-void enable_caches(void)
-{
- dcache_enable();
-}
diff --git a/arch/arm/mach-uniphier/arm32/late_lowlevel_init.S b/arch/arm/mach-uniphier/arm32/late_lowlevel_init.S
index cce91dfac7..001d732e39 100644
--- a/arch/arm/mach-uniphier/arm32/late_lowlevel_init.S
+++ b/arch/arm/mach-uniphier/arm32/late_lowlevel_init.S
@@ -10,9 +10,9 @@
#include "ssc-regs.h"
ENTRY(lowlevel_init)
- ldr r1, = SSCC
+ ldr r1, = UNIPHIER_SSCC
ldr r0, [r1]
- bic r0, r0, #SSCC_ON @ L2 disable
+ bic r0, r0, #UNIPHIER_SSCC_ON @ L2 disable
str r0, [r1]
mov pc, lr
ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-uniphier/arm32/lowlevel_init.S b/arch/arm/mach-uniphier/arm32/lowlevel_init.S
index cc34116baa..8e32b35723 100644
--- a/arch/arm/mach-uniphier/arm32/lowlevel_init.S
+++ b/arch/arm/mach-uniphier/arm32/lowlevel_init.S
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2012-2015 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -94,26 +96,26 @@ ENTRY(setup_init_ram)
*/
0:
/*
- * set SSCOQM, SSCOQAD, SSCOQSZ, SSCOQWN in this order
+ * set UNIPHIER_SSCOQM, UNIPHIER_SSCOQAD, UNIPHIER_SSCOQSZ, UNIPHIER_SSCOQWN in this order
*/
ldr r0, = 0x00408006 @ touch to zero with address range
- ldr r1, = SSCOQM
+ ldr r1, = UNIPHIER_SSCOQM
str r0, [r1]
ldr r0, = BOOT_RAM_BASE
- ldr r1, = SSCOQAD
+ ldr r1, = UNIPHIER_SSCOQAD
str r0, [r1]
ldr r0, = BOOT_RAM_SIZE
- ldr r1, = SSCOQSZ
+ ldr r1, = UNIPHIER_SSCOQSZ
str r0, [r1]
ldr r0, = BOOT_WAY_BITS
- ldr r1, = SSCOQWN
+ ldr r1, = UNIPHIER_SSCOQWN
str r0, [r1]
- ldr r1, = SSCOPPQSEF
+ ldr r1, = UNIPHIER_SSCOPPQSEF
ldr r0, [r1]
cmp r0, #0 @ check if the command is successfully set
bne 0b @ try again if an error occurs
- ldr r1, = SSCOLPQS
+ ldr r1, = UNIPHIER_SSCOLPQS
1:
ldr r0, [r1]
cmp r0, #0x4
diff --git a/arch/arm/mach-uniphier/arm32/ssc-regs.h b/arch/arm/mach-uniphier/arm32/ssc-regs.h
index 02fca3b6f6..8f423e92da 100644
--- a/arch/arm/mach-uniphier/arm32/ssc-regs.h
+++ b/arch/arm/mach-uniphier/arm32/ssc-regs.h
@@ -2,6 +2,7 @@
* UniPhier System Cache (L2 Cache) registers
*
* Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2016 Socionext Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -9,57 +10,59 @@
#ifndef ARCH_SSC_REGS_H
#define ARCH_SSC_REGS_H
-#define SSCC 0x500c0000
-#define SSCC_BST (0x1 << 20)
-#define SSCC_ACT (0x1 << 19)
-#define SSCC_WTG (0x1 << 18)
-#define SSCC_PRD (0x1 << 17)
-#define SSCC_WBWA (0x1 << 16)
-#define SSCC_EX (0x1 << 13)
-#define SSCC_ON (0x1 << 0)
+/* control registers */
+#define UNIPHIER_SSCC 0x500c0000 /* Control Register */
+#define UNIPHIER_SSCC_BST (0x1 << 20) /* UCWG burst read */
+#define UNIPHIER_SSCC_ACT (0x1 << 19) /* Inst-Data separate */
+#define UNIPHIER_SSCC_WTG (0x1 << 18) /* WT gathering on */
+#define UNIPHIER_SSCC_PRD (0x1 << 17) /* enable pre-fetch */
+#define UNIPHIER_SSCC_ON (0x1 << 0) /* enable cache */
+#define UNIPHIER_SSCLPDAWCR 0x500c0030 /* Unified/Data Active Way Control */
+#define UNIPHIER_SSCLPIAWCR 0x500c0034 /* Instruction Active Way Control */
-#define SSCLPDAWCR 0x500c0030
+/* revision registers */
+#define UNIPHIER_SSCID 0x503c0100 /* ID Register */
-#define SSCOPE 0x506c0244
-#define SSCOPE_CM_SYNC 0x00000008
+/* operation registers */
+#define UNIPHIER_SSCOPE 0x506c0244 /* Cache Operation Primitive Entry */
+#define UNIPHIER_SSCOPE_CM_INV 0x0 /* invalidate */
+#define UNIPHIER_SSCOPE_CM_CLEAN 0x1 /* clean */
+#define UNIPHIER_SSCOPE_CM_FLUSH 0x2 /* flush */
+#define UNIPHIER_SSCOPE_CM_SYNC 0x8 /* sync (drain bufs) */
+#define UNIPHIER_SSCOPE_CM_FLUSH_PREFETCH 0x9 /* flush p-fetch buf */
+#define UNIPHIER_SSCOQM 0x506c0248
+#define UNIPHIER_SSCOQM_TID_MASK (0x3 << 21)
+#define UNIPHIER_SSCOQM_TID_LRU_DATA (0x0 << 21)
+#define UNIPHIER_SSCOQM_TID_LRU_INST (0x1 << 21)
+#define UNIPHIER_SSCOQM_TID_WAY (0x2 << 21)
+#define UNIPHIER_SSCOQM_S_MASK (0x3 << 17)
+#define UNIPHIER_SSCOQM_S_RANGE (0x0 << 17)
+#define UNIPHIER_SSCOQM_S_ALL (0x1 << 17)
+#define UNIPHIER_SSCOQM_S_WAY (0x2 << 17)
+#define UNIPHIER_SSCOQM_CE (0x1 << 15) /* notify completion */
+#define UNIPHIER_SSCOQM_CW (0x1 << 14)
+#define UNIPHIER_SSCOQM_CM_MASK (0x7)
+#define UNIPHIER_SSCOQM_CM_INV 0x0 /* invalidate */
+#define UNIPHIER_SSCOQM_CM_CLEAN 0x1 /* clean */
+#define UNIPHIER_SSCOQM_CM_FLUSH 0x2 /* flush */
+#define UNIPHIER_SSCOQM_CM_PREFETCH 0x3 /* prefetch to cache */
+#define UNIPHIER_SSCOQM_CM_PREFETCH_BUF 0x4 /* prefetch to pf-buf */
+#define UNIPHIER_SSCOQM_CM_TOUCH 0x5 /* touch */
+#define UNIPHIER_SSCOQM_CM_TOUCH_ZERO 0x6 /* touch to zero */
+#define UNIPHIER_SSCOQM_CM_TOUCH_DIRTY 0x7 /* touch with dirty */
+#define UNIPHIER_SSCOQAD 0x506c024c /* Cache Operation Queue Address */
+#define UNIPHIER_SSCOQSZ 0x506c0250 /* Cache Operation Queue Size */
+#define UNIPHIER_SSCOQMASK 0x506c0254 /* Cache Operation Queue Address Mask */
+#define UNIPHIER_SSCOQWN 0x506c0258 /* Cache Operation Queue Way Number */
+#define UNIPHIER_SSCOPPQSEF 0x506c025c /* Cache Operation Queue Set Complete */
+#define UNIPHIER_SSCOPPQSEF_FE (0x1 << 1)
+#define UNIPHIER_SSCOPPQSEF_OE (0x1 << 0)
+#define UNIPHIER_SSCOLPQS 0x506c0260 /* Cache Operation Queue Status */
+#define UNIPHIER_SSCOLPQS_EF (0x1 << 2)
+#define UNIPHIER_SSCOLPQS_EST (0x1 << 1)
+#define UNIPHIER_SSCOLPQS_QST (0x1 << 0)
-#define SSCOQM 0x506c0248
-#define SSCOQM_TID_MASK (0x3 << 21)
-#define SSCOQM_TID_BY_WAY (0x2 << 21)
-#define SSCOQM_TID_BY_INST_WAY (0x1 << 21)
-#define SSCOQM_TID_BY_DATA_WAY (0x0 << 21)
-#define SSCOQM_S_MASK (0x3 << 17)
-#define SSCOQM_S_WAY (0x2 << 17)
-#define SSCOQM_S_ALL (0x1 << 17)
-#define SSCOQM_S_ADDRESS (0x0 << 17)
-#define SSCOQM_CE (0x1 << 15)
-#define SSCOQM_CW (0x1 << 14)
-#define SSCOQM_CM_MASK (0x7)
-#define SSCOQM_CM_DIRT_TOUCH (0x7)
-#define SSCOQM_CM_ZERO_TOUCH (0x6)
-#define SSCOQM_CM_NORM_TOUCH (0x5)
-#define SSCOQM_CM_PREF_FETCH (0x4)
-#define SSCOQM_CM_SSC_FETCH (0x3)
-#define SSCOQM_CM_WB_INV (0x2)
-#define SSCOQM_CM_WB (0x1)
-#define SSCOQM_CM_INV (0x0)
-
-#define SSCOQAD 0x506c024c
-#define SSCOQSZ 0x506c0250
-#define SSCOQWN 0x506c0258
-
-#define SSCOPPQSEF 0x506c025c
-#define SSCOPPQSEF_FE (0x1 << 1)
-#define SSCOPPQSEF_OE (0x1 << 0)
-
-#define SSCOLPQS 0x506c0260
-#define SSCOLPQS_EF (0x1 << 2)
-#define SSCOLPQS_EST (0x1 << 1)
-#define SSCOLPQS_QST (0x1 << 0)
-
-#define SSCOQCE0 0x506c0270
-
-#define SSC_LINE_SIZE 128
-#define SSC_RANGE_OP_MAX_SIZE (0x00400000 - (SSC_LINE_SIZE))
+#define UNIPHIER_SSC_LINE_SIZE 128
+#define UNIPHIER_SSC_RANGE_OP_MAX_SIZE (0x00400000 - (UNIPHIER_SSC_LINE_SIZE))
#endif /* ARCH_SSC_REGS_H */
diff --git a/arch/arm/mach-uniphier/arm64/arm-cci500.c b/arch/arm/mach-uniphier/arm64/arm-cci500.c
index 607f96a58d..f18595dc13 100644
--- a/arch/arm/mach-uniphier/arm64/arm-cci500.c
+++ b/arch/arm/mach-uniphier/arm64/arm-cci500.c
@@ -1,13 +1,12 @@
/*
* Initialization of ARM Corelink CCI-500 Cache Coherency Interconnect
*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <common.h>
-#include <mapmem.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -28,13 +27,13 @@ void cci500_init(unsigned int nr_slaves)
void __iomem *base;
u32 tmp;
- base = map_sysmem(slave_base, SZ_4K);
+ base = ioremap(slave_base, SZ_4K);
tmp = readl(base);
tmp |= CCI500_SNOOP_CTRL_EN_DVM | CCI500_SNOOP_CTRL_EN_SNOOP;
writel(tmp, base);
- unmap_sysmem(base);
+ iounmap(base);
slave_base += CCI500_SLAVE_OFFSET;
}
diff --git a/arch/arm/mach-uniphier/arm64/mem_map.c b/arch/arm/mach-uniphier/arm64/mem_map.c
index 74ef91984c..67bc4f1209 100644
--- a/arch/arm/mach-uniphier/arm64/mem_map.c
+++ b/arch/arm/mach-uniphier/arm64/mem_map.c
@@ -10,14 +10,16 @@
static struct mm_region uniphier_mem_map[] = {
{
- .base = 0x00000000,
+ .virt = 0x00000000,
+ .phys = 0x00000000,
.size = 0x80000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
{
- .base = 0x80000000,
+ .virt = 0x80000000,
+ .phys = 0x80000000,
.size = 0xc0000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
diff --git a/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c b/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c
index 5971ad256b..4f08963118 100644
--- a/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c
+++ b/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c
@@ -1,11 +1,10 @@
/*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <common.h>
-#include <mapmem.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -18,11 +17,11 @@ void uniphier_smp_kick_all_cpus(void)
{
void __iomem *rom_boot_rsv0;
- rom_boot_rsv0 = map_sysmem(UNIPHIER_SMPCTRL_ROM_RSV0, SZ_8);
+ rom_boot_rsv0 = ioremap(UNIPHIER_SMPCTRL_ROM_RSV0, SZ_8);
writeq((u64)uniphier_secondary_startup, rom_boot_rsv0);
- unmap_sysmem(rom_boot_rsv0);
+ iounmap(rom_boot_rsv0);
uniphier_smp_setup();
diff --git a/arch/arm/mach-uniphier/arm64/timer.c b/arch/arm/mach-uniphier/arm64/timer.c
index 4beab9dca8..c10903ae58 100644
--- a/arch/arm/mach-uniphier/arm64/timer.c
+++ b/arch/arm/mach-uniphier/arm64/timer.c
@@ -1,11 +1,10 @@
/*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <common.h>
-#include <mapmem.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -21,7 +20,7 @@ int timer_init(void)
void __iomem *base;
u32 tmp;
- base = map_sysmem(CNT_CONTROL_BASE, SZ_4K);
+ base = ioremap(CNT_CONTROL_BASE, SZ_4K);
/*
* Note:
@@ -32,7 +31,7 @@ int timer_init(void)
tmp |= CNTCR_EN;
writel(tmp, base + CNTCR);
- unmap_sysmem(base);
+ iounmap(base);
return 0;
}
diff --git a/arch/arm/mach-uniphier/boards.c b/arch/arm/mach-uniphier/boards.c
index ed308f3ecb..20093d8178 100644
--- a/arch/arm/mach-uniphier/boards.c
+++ b/arch/arm/mach-uniphier/boards.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -38,7 +39,6 @@ static const struct uniphier_board_data uniphier_sld3_data = {
static const struct uniphier_board_data uniphier_ld4_data = {
.dram_freq = 1600,
.dram_nr_ch = 2,
- .dram_ddr3plus = true,
.dram_ch[0] = {
.base = 0x80000000,
.size = 0x10000000,
@@ -49,6 +49,7 @@ static const struct uniphier_board_data uniphier_ld4_data = {
.size = 0x10000000,
.width = 16,
},
+ .flags = UNIPHIER_BD_DDR3PLUS,
};
#endif
@@ -90,7 +91,6 @@ static const struct uniphier_board_data uniphier_pro4_2g_data = {
static const struct uniphier_board_data uniphier_sld8_data = {
.dram_freq = 1333,
.dram_nr_ch = 2,
- .dram_ddr3plus = true,
.dram_ch[0] = {
.base = 0x80000000,
.size = 0x10000000,
@@ -101,6 +101,7 @@ static const struct uniphier_board_data uniphier_sld8_data = {
.size = 0x10000000,
.width = 16,
},
+ .flags = UNIPHIER_BD_DDR3PLUS,
};
#endif
@@ -202,6 +203,22 @@ static const struct uniphier_board_data uniphier_ld20_data = {
.width = 32,
},
};
+
+static const struct uniphier_board_data uniphier_ld21_data = {
+ .dram_freq = 1866,
+ .dram_nr_ch = 2,
+ .dram_ch[0] = {
+ .base = 0x80000000,
+ .size = 0x40000000,
+ .width = 32,
+ },
+ .dram_ch[1] = {
+ .base = 0xc0000000,
+ .size = 0x40000000,
+ .width = 32,
+ },
+ .flags = UNIPHIER_BD_PACKAGE_LD21,
+};
#endif
struct uniphier_board_id {
@@ -237,6 +254,7 @@ static const struct uniphier_board_id uniphier_boards[] = {
{ "socionext,ph1-ld11", &uniphier_ld11_data, },
#endif
#if defined(CONFIG_ARCH_UNIPHIER_LD20)
+ { "socionext,ph1-ld21", &uniphier_ld21_data, },
{ "socionext,ph1-ld20", &uniphier_ld20_data, },
#endif
};
diff --git a/arch/arm/mach-uniphier/clk/clk-pxs2.c b/arch/arm/mach-uniphier/clk/clk-pxs2.c
index 76bf856c9e..0d9240519c 100644
--- a/arch/arm/mach-uniphier/clk/clk-pxs2.c
+++ b/arch/arm/mach-uniphier/clk/clk-pxs2.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <linux/bitops.h>
#include <linux/io.h>
#include "../init.h"
@@ -32,12 +33,16 @@ void uniphier_pxs2_clk_init(void)
tmp |= SC_RSTCTRL2_NRST_USB3B1;
writel(tmp, SC_RSTCTRL2);
readl(SC_RSTCTRL2); /* dummy read */
+
+ tmp = readl(SC_RSTCTRL6);
+ tmp |= 0x37;
+ writel(tmp, SC_RSTCTRL6);
#endif
/* provide clocks */
tmp = readl(SC_CLKCTRL);
#ifdef CONFIG_USB_XHCI_UNIPHIER
- tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 |
+ tmp |= BIT(20) | BIT(19) | SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 |
SC_CLKCTRL_CEN_GIO;
#endif
#ifdef CONFIG_UNIPHIER_ETH
diff --git a/arch/arm/mach-uniphier/dram/cmd_ddrphy.c b/arch/arm/mach-uniphier/dram/cmd_ddrphy.c
index 7a9f76caeb..0a5a73d8ee 100644
--- a/arch/arm/mach-uniphier/dram/cmd_ddrphy.c
+++ b/arch/arm/mach-uniphier/dram/cmd_ddrphy.c
@@ -1,11 +1,12 @@
/*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
-#include <mapmem.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -51,7 +52,7 @@ static void dump_loop(unsigned long *base,
int p, dx;
for (p = 0; *base; base++, p++) {
- phy = map_sysmem(*base, SZ_4K);
+ phy = ioremap(*base, SZ_4K);
for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
printf("PHY%dDX%d:", p, dx);
@@ -59,7 +60,7 @@ static void dump_loop(unsigned long *base,
printf("\n");
}
- unmap_sysmem(phy);
+ iounmap(phy);
}
}
@@ -172,7 +173,7 @@ static void reg_dump(unsigned long *base)
printf("\n--- DDR PHY registers ---\n");
for (p = 0; *base; base++, p++) {
- phy = map_sysmem(*base, SZ_4K);
+ phy = ioremap(*base, SZ_4K);
printf("== PHY%d (base: %p) ==\n", p, phy);
printf(" No: Name : Address : Data\n");
@@ -206,7 +207,7 @@ static void reg_dump(unsigned long *base)
REG_DUMP(dx[1].gcr);
REG_DUMP(dx[1].gtr);
- unmap_sysmem(phy);
+ iounmap(phy);
}
}
diff --git a/arch/arm/mach-uniphier/dram/umc-ld4.c b/arch/arm/mach-uniphier/dram/umc-ld4.c
index fc75864a10..1ea6193f88 100644
--- a/arch/arm/mach-uniphier/dram/umc-ld4.c
+++ b/arch/arm/mach-uniphier/dram/umc-ld4.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -175,7 +177,7 @@ int uniphier_ld4_umc_init(const struct uniphier_board_data *bd)
for (ch = 0; ch < DRAM_CH_NR; ch++) {
ret = umc_ch_init(dc_base, ca_base, bd->dram_freq,
bd->dram_ch[ch].size,
- bd->dram_ddr3plus, ch);
+ !!(bd->flags & UNIPHIER_BD_DDR3PLUS), ch);
if (ret) {
pr_err("failed to initialize UMC ch%d\n", ch);
return ret;
diff --git a/arch/arm/mach-uniphier/dram/umc-pro4.c b/arch/arm/mach-uniphier/dram/umc-pro4.c
index 853f561cb2..f6c2d7f145 100644
--- a/arch/arm/mach-uniphier/dram/umc-pro4.c
+++ b/arch/arm/mach-uniphier/dram/umc-pro4.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -170,7 +172,7 @@ int uniphier_pro4_umc_init(const struct uniphier_board_data *bd)
ret = umc_ch_init(dc_base, ca_base, bd->dram_freq,
bd->dram_ch[ch].size,
bd->dram_ch[ch].width,
- bd->dram_ddr3plus);
+ !!(bd->flags & UNIPHIER_BD_DDR3PLUS));
if (ret) {
pr_err("failed to initialize UMC ch%d\n", ch);
return ret;
diff --git a/arch/arm/mach-uniphier/dram/umc-sld8.c b/arch/arm/mach-uniphier/dram/umc-sld8.c
index e831766583..61b1dc1a3a 100644
--- a/arch/arm/mach-uniphier/dram/umc-sld8.c
+++ b/arch/arm/mach-uniphier/dram/umc-sld8.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -178,7 +180,7 @@ int uniphier_sld8_umc_init(const struct uniphier_board_data *bd)
for (ch = 0; ch < DRAM_CH_NR; ch++) {
ret = umc_ch_init(dc_base, ca_base, bd->dram_freq,
bd->dram_ch[ch].size,
- bd->dram_ddr3plus, ch);
+ !!(bd->flags & UNIPHIER_BD_DDR3PLUS), ch);
if (ret) {
pr_err("failed to initialize UMC ch%d\n", ch);
return ret;
diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h
index cba0bc9d37..db80074fc9 100644
--- a/arch/arm/mach-uniphier/init.h
+++ b/arch/arm/mach-uniphier/init.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -20,8 +21,11 @@ struct uniphier_dram_ch {
struct uniphier_board_data {
unsigned int dram_freq;
unsigned int dram_nr_ch;
- bool dram_ddr3plus;
struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH];
+ unsigned int flags;
+#define UNIPHIER_BD_DDR3PLUS BIT(2)
+#define UNIPHIER_BD_PACKAGE_LD21 1
+#define UNIPHIER_BD_PACKAGE_TYPE(f) ((f) & 0x3)
};
const struct uniphier_board_data *uniphier_get_board_param(void);
diff --git a/arch/arm/mach-uniphier/sc-regs.h b/arch/arm/mach-uniphier/sc-regs.h
index a0955893ef..ad58e10e23 100644
--- a/arch/arm/mach-uniphier/sc-regs.h
+++ b/arch/arm/mach-uniphier/sc-regs.h
@@ -1,7 +1,9 @@
/*
* UniPhier SC (System Control) block registers
*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2015 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -68,6 +70,10 @@
#define SC_RSTCTRL4_NRST_UMC31 (0x1 << 5) /* UMC ch1 */
#define SC_RSTCTRL4_NRST_UMC30 (0x1 << 4) /* UMC ch0 */
+#define SC_RSTCTRL5 (SC_BASE_ADDR | 0x2010)
+
+#define SC_RSTCTRL6 (SC_BASE_ADDR | 0x2014)
+
#define SC_CLKCTRL (SC_BASE_ADDR | 0x2104)
#define SC_CLKCTRL_CEN_USB31 (0x1 << 17) /* USB3 #1 */
#define SC_CLKCTRL_CEN_USB30 (0x1 << 16) /* USB3 #0 */
diff --git a/arch/nds32/include/asm/io.h b/arch/nds32/include/asm/io.h
index 04708e9359..b2c4d0ef8c 100644
--- a/arch/nds32/include/asm/io.h
+++ b/arch/nds32/include/asm/io.h
@@ -344,40 +344,6 @@ static inline void writesl(unsigned int *addr, const void * data, int longlen)
#define insl_p(port, to, len) insl(port, to, len)
/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt. If you want a
- * physical address, use __ioremap instead.
- */
-extern void *__ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- * iomem_valid_addr(off,size)
- * iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off, sz, nocache) \
-({ \
- unsigned long _off = (off), _size = (sz); \
- void *_ret = (void *)0; \
- if (iomem_valid_addr(_off, _size)) \
- _ret = __ioremap(iomem_to_phys(_off), _size, 0); \
- _ret; \
-})
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off, sz) __arch_ioremap((off), (sz), 0)
-#define ioremap_nocache(off, sz) __arch_ioremap((off), (sz), 1)
-#define iounmap(_addr) __arch_iounmap(_addr)
-
-/*
* DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA
* devices. This is the "generic" version. The PCI specific version
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index 61f5639e0d..ace42799f7 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -439,7 +439,7 @@ ulong cpu_init_f(void)
#ifdef CONFIG_SYS_DCSRBAR_PHYS
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
#endif
-#if defined(CONFIG_SECURE_BOOT)
+#if defined(CONFIG_SECURE_BOOT) && !defined(CONFIG_SYS_RAMBOOT)
struct law_entry law;
#endif
#ifdef CONFIG_MPC8548
@@ -459,7 +459,7 @@ ulong cpu_init_f(void)
disable_tlb(14);
disable_tlb(15);
-#if defined(CONFIG_SECURE_BOOT)
+#if defined(CONFIG_SECURE_BOOT) && !defined(CONFIG_SYS_RAMBOOT)
/* Disable the LAW created for NOR flash by the PBI commands */
law = find_law(CONFIG_SYS_PBI_FLASH_BASE);
if (law.index != -1)
diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c
index 88c8e65930..0addf8493c 100644
--- a/arch/powerpc/cpu/mpc85xx/mp.c
+++ b/arch/powerpc/cpu/mpc85xx/mp.c
@@ -30,7 +30,7 @@ u32 get_my_id()
*/
int hold_cores_in_reset(int verbose)
{
- /* Default to no, overriden by 'y', 'yes', 'Y', 'Yes', or '1' */
+ /* Default to no, overridden by 'y', 'yes', 'Y', 'Yes', or '1' */
if (getenv_yesno("mp_holdoff") == 1) {
if (verbose) {
puts("Secondary cores are being held in reset.\n");
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index 4c51225868..c3e12349f7 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -1069,17 +1069,23 @@ create_init_ram_area:
#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
/* create a temp mapping in AS = 1 for Flash mapping
* created by PBL for ISBC code
- */
+ */
create_tlb1_entry 15, \
1, BOOKE_PAGESZ_1M, \
CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
CONFIG_SYS_PBI_FLASH_WINDOW & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
0, r6
-#elif defined(CONFIG_RAMBOOT_PBL) && defined(CONFIG_SECURE_BOOT)
+/*
+ * For Targets without CONFIG_SPL like P3, P5
+ * and for targets with CONFIG_SPL like T1, T2, T4, only for
+ * u-boot-spl i.e. CONFIG_SPL_BUILD
+ */
+#elif defined(CONFIG_RAMBOOT_PBL) && defined(CONFIG_SECURE_BOOT) && \
+ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
/* create a temp mapping in AS = 1 for mapping CONFIG_SYS_MONITOR_BASE
* to L3 Address configured by PBL for ISBC code
- */
+ */
create_tlb1_entry 15, \
1, BOOKE_PAGESZ_1M, \
CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
diff --git a/arch/powerpc/cpu/mpc86xx/config.mk b/arch/powerpc/cpu/mpc86xx/config.mk
index 69a0b96ead..aefb0f1fb4 100644
--- a/arch/powerpc/cpu/mpc86xx/config.mk
+++ b/arch/powerpc/cpu/mpc86xx/config.mk
@@ -5,4 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_CPPFLAGS += -mstring -maltivec -mabi=altivec -msoft-float
+PLATFORM_CPPFLAGS += -mcpu=7400 -mstring -maltivec -mabi=altivec -msoft-float
diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_pamu.c b/arch/powerpc/cpu/mpc8xxx/fsl_pamu.c
index 9421f1ebf6..ede8e66210 100644
--- a/arch/powerpc/cpu/mpc8xxx/fsl_pamu.c
+++ b/arch/powerpc/cpu/mpc8xxx/fsl_pamu.c
@@ -239,15 +239,23 @@ int pamu_init(void)
spaact_size = sizeof(struct paace) * NUM_SPAACT_ENTRIES;
/* Allocate space for Primary PAACT Table */
+#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_PPAACT_ADDR))
+ ppaact = (void *)CONFIG_SPL_PPAACT_ADDR;
+#else
ppaact = memalign(PAMU_TABLE_ALIGNMENT, ppaact_size);
if (!ppaact)
return -1;
+#endif
memset(ppaact, 0, ppaact_size);
/* Allocate space for Secondary PAACT Table */
+#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SPAACT_ADDR))
+ sec = (void *)CONFIG_SPL_SPAACT_ADDR;
+#else
sec = memalign(PAMU_TABLE_ALIGNMENT, spaact_size);
if (!sec)
return -1;
+#endif
memset(sec, 0, spaact_size);
ppaact_phys = virt_to_phys((void *)ppaact);
diff --git a/arch/powerpc/cpu/mpc8xxx/pamu_table.c b/arch/powerpc/cpu/mpc8xxx/pamu_table.c
index 26c5ea4fd7..a8e6f51777 100644
--- a/arch/powerpc/cpu/mpc8xxx/pamu_table.c
+++ b/arch/powerpc/cpu/mpc8xxx/pamu_table.c
@@ -28,6 +28,14 @@ void construct_pamu_addr_table(struct pamu_addr_tbl *tbl, int *num_entries)
i++;
#endif
+#if (defined(CONFIG_SPL_BUILD) && (CONFIG_SYS_INIT_L3_VADDR))
+ tbl->start_addr[i] =
+ (uint64_t)virt_to_phys((void *)CONFIG_SYS_INIT_L3_VADDR);
+ tbl->size[i] = 256 * 1024; /* 256K CPC flash */
+ tbl->end_addr[i] = tbl->start_addr[i] + tbl->size[i] - 1;
+
+ i++;
+#endif
debug("PAMU address\t\t\tsize\n");
for (j = 0; j < i ; j++)
debug("%llx \t\t\t%llx\n", tbl->start_addr[j], tbl->size[j]);
diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S
index b432b18c74..5647d712d6 100644
--- a/arch/powerpc/cpu/ppc4xx/start.S
+++ b/arch/powerpc/cpu/ppc4xx/start.S
@@ -144,7 +144,7 @@
#endif
/*
- * Unless otherwise overriden, enable two 128MB cachable instruction regions
+ * Unless otherwise overridden, enable two 128MB cachable instruction regions
* at CONFIG_SYS_SDRAM_BASE and another 128MB cacheable instruction region covering
* NOR flash at CONFIG_SYS_FLASH_BASE. Disable all cacheable data regions.
*/
diff --git a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
index 41b6677bba..76faa22c8b 100644
--- a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
+++ b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
@@ -18,4 +18,10 @@
#include <asm/mpc85xx_gpio.h>
#endif
+struct mpc85xx_gpio_plat {
+ ulong addr;
+ unsigned long size;
+ uint ngpios;
+};
+
#endif
diff --git a/arch/powerpc/include/asm/fsl_secure_boot.h b/arch/powerpc/include/asm/fsl_secure_boot.h
index 826f9c960e..2e937f0364 100644
--- a/arch/powerpc/include/asm/fsl_secure_boot.h
+++ b/arch/powerpc/include/asm/fsl_secure_boot.h
@@ -35,7 +35,9 @@
defined(CONFIG_T104xD4RDB) || \
defined(CONFIG_PPC_T1023) || \
defined(CONFIG_PPC_T1024)
+#ifndef CONFIG_SYS_RAMBOOT
#define CONFIG_SYS_CPC_REINIT_F
+#endif
#define CONFIG_KEY_REVOCATION
#undef CONFIG_SYS_INIT_L3_ADDR
#define CONFIG_SYS_INIT_L3_ADDR 0xbff00000
@@ -43,7 +45,13 @@
#if defined(CONFIG_RAMBOOT_PBL)
#undef CONFIG_SYS_INIT_L3_ADDR
-#define CONFIG_SYS_INIT_L3_ADDR 0xbff00000
+#ifdef CONFIG_SYS_INIT_L3_VADDR
+#define CONFIG_SYS_INIT_L3_ADDR \
+ (CONFIG_SYS_INIT_L3_VADDR & ~0xFFF00000) | \
+ 0xbff00000
+#else
+#define CONFIG_SYS_INIT_L3_ADDR 0xbff00000
+#endif
#endif
#if defined(CONFIG_C29XPCIE)
@@ -72,6 +80,32 @@
#ifdef CONFIG_CHAIN_OF_TRUST
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SPL_DM 1
+#define CONFIG_SPL_CRYPTO_SUPPORT
+#define CONFIG_SPL_HASH_SUPPORT
+#define CONFIG_SPL_RSA
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+/*
+ * PPAACT and SPAACT table for PAMU must be placed on DDR after DDR init
+ * due to space crunch on CPC and thus malloc will not work.
+ */
+#define CONFIG_SPL_PPAACT_ADDR 0x2e000000
+#define CONFIG_SPL_SPAACT_ADDR 0x2f000000
+#define CONFIG_SPL_JR0_LIODN_S 454
+#define CONFIG_SPL_JR0_LIODN_NS 458
+/*
+ * Define the key hash for U-Boot here if public/private key pair used to
+ * sign U-boot are different from the SRK hash put in the fuse
+ * Example of defining KEY_HASH is
+ * #define CONFIG_SPL_UBOOT_KEY_HASH \
+ * "41066b564c6ffcef40ccbc1e0a5d0d519604000c785d97bbefd25e4d288d1c8b"
+ * else leave it defined as NULL
+ */
+
+#define CONFIG_SPL_UBOOT_KEY_HASH NULL
+#endif /* ifdef CONFIG_SPL_BUILD */
+
#define CONFIG_CMD_ESBC_VALIDATE
#define CONFIG_CMD_BLOB
#define CONFIG_FSL_SEC_MON
@@ -82,7 +116,9 @@
#define CONFIG_FSL_CAAM
#endif
-/* fsl_setenv_chain_of_trust() must be called from
+#ifndef CONFIG_SPL_BUILD
+/*
+ * fsl_setenv_chain_of_trust() must be called from
* board_late_init()
*/
#ifndef CONFIG_BOARD_LATE_INIT
@@ -92,10 +128,10 @@
/* If Boot Script is not on NOR and is required to be copied on RAM */
#ifdef CONFIG_BOOTSCRIPT_COPY_RAM
#define CONFIG_BS_HDR_ADDR_RAM 0x00010000
-#define CONFIG_BS_HDR_ADDR_FLASH 0x00800000
+#define CONFIG_BS_HDR_ADDR_DEVICE 0x00800000
#define CONFIG_BS_HDR_SIZE 0x00002000
#define CONFIG_BS_ADDR_RAM 0x00012000
-#define CONFIG_BS_ADDR_FLASH 0x00802000
+#define CONFIG_BS_ADDR_DEVICE 0x00802000
#define CONFIG_BS_SIZE 0x00001000
#define CONFIG_BOOTSCRIPT_HDR_ADDR CONFIG_BS_HDR_ADDR_RAM
@@ -119,5 +155,6 @@
#endif /* #ifdef CONFIG_BOOTSCRIPT_COPY_RAM */
#include <config_fsl_chain_trust.h>
+#endif /* #ifndef CONFIG_SPL_BUILD */
#endif /* #ifdef CONFIG_CHAIN_OF_TRUST */
#endif
diff --git a/arch/powerpc/include/asm/status_led.h b/arch/powerpc/include/asm/status_led.h
index 441619042d..260a8319ce 100644
--- a/arch/powerpc/include/asm/status_led.h
+++ b/arch/powerpc/include/asm/status_led.h
@@ -7,7 +7,7 @@
#ifndef __ASM_STATUS_LED_H__
#define __ASM_STATUS_LED_H__
-/* if not overriden */
+/* if not overridden */
#ifndef CONFIG_BOARD_SPECIFIC_LED
# if defined(CONFIG_8xx)
# include <mpc8xx.h>
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index a8a90cb7a4..d4c1ee0662 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -10,8 +10,13 @@ config SYS_BOARD
config SYS_CPU
default "sandbox"
+config SANDBOX_SPL
+ bool "Enable SPL for sandbox"
+ select SUPPORT_SPL
+
config SYS_CONFIG_NAME
- default "sandbox"
+ default "sandbox_spl" if SANDBOX_SPL
+ default "sandbox" if !SANDBOX_SPL
config PCI
bool "PCI support"
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 16fd6d508a..6d62abb035 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -20,4 +20,9 @@ cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds \
-Wl,--start-group $(u-boot-main) -Wl,--end-group \
$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map
+cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \
+ -Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
+ $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \
+ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections)
+
CONFIG_ARCH_DEVICE_TREE := sandbox
diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile
index 1b42fee141..db4363358a 100644
--- a/arch/sandbox/cpu/Makefile
+++ b/arch/sandbox/cpu/Makefile
@@ -8,6 +8,7 @@
#
obj-y := cpu.o os.o start.o state.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
obj-$(CONFIG_ETH_SANDBOX_RAW) += eth-raw-os.o
obj-$(CONFIG_SANDBOX_SDL) += sdl.o
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 196f3e1191..2def72212d 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -4,10 +4,12 @@
*/
#define DEBUG
#include <common.h>
-#include <dm/root.h>
+#include <errno.h>
+#include <libfdt.h>
#include <os.h>
#include <asm/io.h>
#include <asm/state.h>
+#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -55,7 +57,7 @@ int cleanup_before_linux_select(int flags)
void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_SPL_BUILD)
unsigned long plen = len;
void *ptr;
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 8a4d719835..2d63dd88f1 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -541,6 +541,57 @@ int os_jump_to_image(const void *dest, int size)
return unlink(fname);
}
+int os_find_u_boot(char *fname, int maxlen)
+{
+ struct sandbox_state *state = state_get_current();
+ const char *progname = state->argv[0];
+ int len = strlen(progname);
+ char *p;
+ int fd;
+
+ if (len >= maxlen || len < 4)
+ return -ENOSPC;
+
+ /* Look for 'u-boot' in the same directory as 'u-boot-spl' */
+ strcpy(fname, progname);
+ if (!strcmp(fname + len - 4, "-spl")) {
+ fname[len - 4] = '\0';
+ fd = os_open(fname, O_RDONLY);
+ if (fd >= 0) {
+ close(fd);
+ return 0;
+ }
+ }
+
+ /* Look for 'u-boot' in the parent directory of spl/ */
+ p = strstr(fname, "/spl/");
+ if (p) {
+ strcpy(p, p + 4);
+ fd = os_open(fname, O_RDONLY);
+ if (fd >= 0) {
+ close(fd);
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+int os_spl_to_uboot(const char *fname)
+{
+ struct sandbox_state *state = state_get_current();
+ char *argv[state->argc + 1];
+ int ret;
+
+ memcpy(argv, state->argv, sizeof(char *) * (state->argc + 1));
+ argv[0] = (char *)fname;
+ ret = execv(fname, argv);
+ if (ret)
+ return ret;
+
+ return unlink(fname);
+}
+
void os_localtime(struct rtc_time *rt)
{
time_t t = time(NULL);
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
new file mode 100644
index 0000000000..e8349c0b93
--- /dev/null
+++ b/arch/sandbox/cpu/spl.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <os.h>
+#include <spl.h>
+#include <asm/spl.h>
+#include <asm/state.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_init_f(ulong flag)
+{
+ struct sandbox_state *state = state_get_current();
+
+ gd->arch.ram_buf = state->ram_buf;
+ gd->ram_size = state->ram_size;
+}
+
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_BOARD;
+}
+
+void spl_board_announce_boot_device(void)
+{
+ char fname[256];
+ int ret;
+
+ ret = os_find_u_boot(fname, sizeof(fname));
+ if (ret) {
+ printf("(%s not found, error %d)\n", fname, ret);
+ return;
+ }
+ printf("%s\n", fname);
+}
+
+int spl_board_load_image(void)
+{
+ char fname[256];
+ int ret;
+
+ ret = os_find_u_boot(fname, sizeof(fname));
+ if (ret)
+ return ret;
+
+ /* Hopefully this will not return */
+ return os_spl_to_uboot(fname);
+}
+
+void spl_board_init(void)
+{
+ struct udevice *dev;
+
+ preloader_console_init();
+
+ /*
+ * Scan all the devices so that we can output their platform data. See
+ * sandbox_spl_probe().
+ */
+ for (uclass_first_device(UCLASS_MISC, &dev);
+ dev;
+ uclass_next_device(&dev))
+ ;
+}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 969618ef87..6e4ec017cc 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -73,6 +73,7 @@ static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)
}
SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
+#ifndef CONFIG_SPL_BUILD
int sandbox_main_loop_init(void)
{
struct sandbox_state *state = state_get_current();
@@ -97,6 +98,7 @@ int sandbox_main_loop_init(void)
return 0;
}
+#endif
static int sandbox_cmdline_cb_boot(struct sandbox_state *state,
const char *arg)
diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds
new file mode 100644
index 0000000000..7e92b4ac66
--- /dev/null
+++ b/arch/sandbox/cpu/u-boot-spl.lds
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+SECTIONS
+{
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ __u_boot_sandbox_option_start = .;
+ _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) }
+ __u_boot_sandbox_option_end = .;
+
+ __bss_start = .;
+}
+
+INSERT BEFORE .data;
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 2ae40148b0..e6d336f16a 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -172,6 +172,37 @@
};
};
+ spl-test {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ boolval;
+ intval = <1>;
+ intarray = <2 3 4>;
+ byteval = [05];
+ bytearray = [06];
+ longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
+ stringval = "message";
+ stringarray = "multi-word", "message";
+ };
+
+ spl-test2 {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ intval = <3>;
+ intarray = <5>;
+ byteval = [08];
+ bytearray = [01 23 34];
+ longbytearray = [09 0a 0b 0c];
+ stringval = "message2";
+ stringarray = "another", "multi-word", "message";
+ };
+
+ spl-test3 {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ stringarray = "one";
+ };
+
square {
compatible = "demo-shape";
colour = "blue";
diff --git a/arch/sandbox/include/asm/spl.h b/arch/sandbox/include/asm/spl.h
new file mode 100644
index 0000000000..59f2401170
--- /dev/null
+++ b/arch/sandbox/include/asm/spl.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __asm_spl_h
+#define __asm_spl_h
+
+#define CONFIG_SPL_BOARD_LOAD_IMAGE
+
+/**
+ * Board-specific load method for boards that have a special way of loading
+ * U-Boot, which does not fit with the existing SPL code.
+ *
+ * @return 0 on success, negative errno value on failure.
+ */
+int spl_board_load_image(void);
+
+enum {
+ BOOT_DEVICE_BOARD,
+};
+
+#endif
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index 96761e27f7..7820c55c85 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -8,5 +8,7 @@
#
obj-y += interrupts.o
+ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_PCI) += pci_io.o
+endif
obj-$(CONFIG_CMD_BOOTM) += bootm.o
diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c
index d49c927b34..0c9a7979d2 100644
--- a/arch/sandbox/lib/bootm.c
+++ b/arch/sandbox/lib/bootm.c
@@ -56,7 +56,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
printf("## Transferring control to Linux (at address %08lx)...\n",
images->ep);
- reset_cpu(0);
+ printf("sandbox: continuing, as we cannot run Linux\n");
}
return 0;
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 0a00db3617..5dc27bebd5 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -128,39 +128,6 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
#define in_8(port) inb(port)
#define in_le16(port) inw(port)
#define in_le32(port) inl(port)
-/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt. If you want a
- * physical address, use __ioremap instead.
- */
-extern void *__ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- * iomem_valid_addr(off,size)
- * iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off, sz, nocache) \
-({ \
- unsigned long _off = (off), _size = (sz); \
- void *_ret = (void *)0; \
- if (iomem_valid_addr(_off, _size)) \
- _ret = __ioremap(iomem_to_phys(_off), _size, 0); \
- _ret; \
-})
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off, sz) __arch_ioremap((off), (sz), 0)
-#define ioremap_nocache(off, sz) __arch_ioremap((off), (sz), 1)
-#define iounmap(_addr) __arch_iounmap(_addr)
/*
* DMA-consistent mapping functions. These allocate/free a region of
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 29d2307fa5..29d112097a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -8,6 +8,9 @@ choice
prompt "Mainboard vendor"
default VENDOR_EMULATION
+config VENDOR_ADVANTECH
+ bool "advantech"
+
config VENDOR_CONGATEC
bool "congatec"
@@ -29,6 +32,7 @@ config VENDOR_INTEL
endchoice
# board-specific options below
+source "board/advantech/Kconfig"
source "board/congatec/Kconfig"
source "board/coreboot/Kconfig"
source "board/efi/Kconfig"
diff --git a/arch/x86/cpu/baytrail/Kconfig b/arch/x86/cpu/baytrail/Kconfig
index 407feb214b..1c8ac370b3 100644
--- a/arch/x86/cpu/baytrail/Kconfig
+++ b/arch/x86/cpu/baytrail/Kconfig
@@ -7,3 +7,14 @@
config INTEL_BAYTRAIL
bool
select HAVE_FSP if !EFI
+
+if INTEL_BAYTRAIL
+config INTERNAL_UART
+ bool "Enable the SoC integrated legacy UART"
+ help
+ There is a legacy UART integrated into the Bay Trail SoC.
+ A maximum baud rate of 115200 bps is supported. For this
+ reason, it is recommended that the UART port be used for
+ debug purposes only, eg: U-Boot console.
+
+endif
diff --git a/arch/x86/cpu/baytrail/acpi.c b/arch/x86/cpu/baytrail/acpi.c
index 5ee4868cf8..fa92d8852e 100644
--- a/arch/x86/cpu/baytrail/acpi.c
+++ b/arch/x86/cpu/baytrail/acpi.c
@@ -5,10 +5,14 @@
*/
#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
#include <asm/acpi_table.h>
#include <asm/ioapic.h>
#include <asm/mpspec.h>
#include <asm/tables.h>
+#include <asm/arch/global_nvs.h>
#include <asm/arch/iomap.h>
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
@@ -161,3 +165,25 @@ u32 acpi_fill_madt(u32 current)
return current;
}
+
+void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+{
+ struct udevice *dev;
+ int ret;
+
+ /* at least we have one processor */
+ gnvs->pcnt = 1;
+ /* override the processor count with actual number */
+ ret = uclass_find_first_device(UCLASS_CPU, &dev);
+ if (ret == 0 && dev != NULL) {
+ ret = cpu_get_count(dev);
+ if (ret > 0)
+ gnvs->pcnt = ret;
+ }
+
+ /* determine whether internal uart is on */
+ if (IS_ENABLED(CONFIG_INTERNAL_UART))
+ gnvs->iuart_en = 1;
+ else
+ gnvs->iuart_en = 0;
+}
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index ff1faa5014..4e0be2a88b 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -424,8 +424,6 @@ static void set_spi_speed(void)
static int lpc_init_extra(struct udevice *dev)
{
struct udevice *pch = dev->parent;
- const void *blob = gd->fdt_blob;
- int node;
debug("pch: lpc_init\n");
dm_pci_write_bar32(pch, 0, 0);
@@ -434,10 +432,6 @@ static int lpc_init_extra(struct udevice *dev)
dm_pci_write_bar32(pch, 3, 0x800);
dm_pci_write_bar32(pch, 4, 0x900);
- node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
- if (node < 0)
- return -ENOENT;
-
/* Set the value for PCI command register. */
dm_pci_write_config16(pch, PCI_COMMAND, 0x000f);
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 9d9f63d70c..e0b06b5ada 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -458,6 +458,11 @@ int dram_init(void)
struct udevice *dev, *me_dev;
int ret;
+ /* We need the pinctrl set up early */
+ ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &dev);
+ if (ret)
+ return ret;
+
ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev);
if (ret)
return ret;
diff --git a/arch/x86/cpu/quark/acpi.c b/arch/x86/cpu/quark/acpi.c
index 8f69829608..3968f7a8bf 100644
--- a/arch/x86/cpu/quark/acpi.c
+++ b/arch/x86/cpu/quark/acpi.c
@@ -9,6 +9,7 @@
#include <asm/ioapic.h>
#include <asm/mpspec.h>
#include <asm/tables.h>
+#include <asm/arch/global_nvs.h>
#include <asm/arch/iomap.h>
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
@@ -161,3 +162,9 @@ u32 acpi_fill_madt(u32 current)
return current;
}
+
+void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+{
+ /* quark is a uni-processor */
+ gnvs->pcnt = 1;
+}
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
index 23156bb231..4f07f41042 100644
--- a/arch/x86/dts/Makefile
+++ b/arch/x86/dts/Makefile
@@ -14,7 +14,8 @@ dtb-y += bayleybay.dtb \
minnowmax.dtb \
qemu-x86_i440fx.dtb \
qemu-x86_q35.dtb \
- broadwell_som-6896.dtb
+ broadwell_som-6896.dtb \
+ baytrail_som-db5800-som-6867.dtb
targets += $(dtb-y)
diff --git a/arch/x86/dts/baytrail_som-db5800-som-6867.dts b/arch/x86/dts/baytrail_som-db5800-som-6867.dts
new file mode 100644
index 0000000000..64e2e528e9
--- /dev/null
+++ b/arch/x86/dts/baytrail_som-db5800-som-6867.dts
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ * Copyright (C) 2016, George McCollister <george.mccollister@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/x86-gpio.h>
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/include/ "skeleton.dtsi"
+/include/ "serial.dtsi"
+/include/ "rtc.dtsi"
+/include/ "tsc_timer.dtsi"
+
+/ {
+ model = "Advantech SOM-DB5800-SOM-6867";
+ compatible = "advantech,som-db5800-som-6867", "intel,baytrail";
+
+ aliases {
+ serial0 = &serial;
+ spi0 = &spi;
+ };
+
+ config {
+ silent_console = <0>;
+ };
+
+ pch_pinctrl {
+ compatible = "intel,x86-pinctrl";
+ reg = <0 0>;
+
+ /* HDA_RSTB */
+ soc_gpio_s0_8@0 {
+ pad-offset = <0x220>;
+ mode-func = <2>;
+ };
+
+ /* HDA_SYNC */
+ soc_gpio_s0_9@0 {
+ pad-offset = <0x250>;
+ mode-func = <2>;
+ pull-assign = <1>;
+ };
+
+ /* HDA_CLK */
+ soc_gpio_s0_10@0 {
+ pad-offset = <0x240>;
+ mode-func = <2>;
+ };
+
+ /* HDA_SDO */
+ soc_gpio_s0_11@0 {
+ pad-offset = <0x260>;
+ mode-func = <2>;
+ pull-assign = <1>;
+ };
+
+ /* HDA_SDI0 */
+ soc_gpio_s0_12@0 {
+ pad-offset = <0x270>;
+ mode-func = <2>;
+ };
+ };
+
+ chosen {
+ stdout-path = "/serial";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <0>;
+ intel,apic-id = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <1>;
+ intel,apic-id = <2>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <2>;
+ intel,apic-id = <4>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <3>;
+ intel,apic-id = <6>;
+ };
+
+ };
+
+ pci {
+ compatible = "intel,pci-baytrail", "pci-x86";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ u-boot,dm-pre-reloc;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x40000000
+ 0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
+ 0x01000000 0x0 0x2000 0x2000 0 0xe000>;
+
+ pch@1f,0 {
+ reg = <0x0000f800 0 0 0 0>;
+ compatible = "pci8086,0f1c", "intel,pch9";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ irq-router {
+ compatible = "intel,irq-router";
+ intel,pirq-config = "ibase";
+ intel,ibase-offset = <0x50>;
+ intel,actl-addr = <0>;
+ intel,pirq-link = <8 8>;
+ intel,pirq-mask = <0xdee0>;
+ intel,pirq-routing = <
+ /* BayTrail PCI devices */
+ PCI_BDF(0, 2, 0) INTA PIRQA
+ PCI_BDF(0, 3, 0) INTA PIRQA
+ PCI_BDF(0, 16, 0) INTA PIRQA
+ PCI_BDF(0, 17, 0) INTA PIRQA
+ PCI_BDF(0, 18, 0) INTA PIRQA
+ PCI_BDF(0, 19, 0) INTA PIRQA
+ PCI_BDF(0, 20, 0) INTA PIRQA
+ PCI_BDF(0, 21, 0) INTA PIRQA
+ PCI_BDF(0, 22, 0) INTA PIRQA
+ PCI_BDF(0, 23, 0) INTA PIRQA
+ PCI_BDF(0, 24, 0) INTA PIRQA
+ PCI_BDF(0, 24, 1) INTC PIRQC
+ PCI_BDF(0, 24, 2) INTD PIRQD
+ PCI_BDF(0, 24, 3) INTB PIRQB
+ PCI_BDF(0, 24, 4) INTA PIRQA
+ PCI_BDF(0, 24, 5) INTC PIRQC
+ PCI_BDF(0, 24, 6) INTD PIRQD
+ PCI_BDF(0, 24, 7) INTB PIRQB
+ PCI_BDF(0, 26, 0) INTA PIRQA
+ PCI_BDF(0, 27, 0) INTA PIRQA
+ PCI_BDF(0, 28, 0) INTA PIRQA
+ PCI_BDF(0, 28, 1) INTB PIRQB
+ PCI_BDF(0, 28, 2) INTC PIRQC
+ PCI_BDF(0, 28, 3) INTD PIRQD
+ PCI_BDF(0, 29, 0) INTA PIRQA
+ PCI_BDF(0, 30, 0) INTA PIRQA
+ PCI_BDF(0, 30, 1) INTD PIRQD
+ PCI_BDF(0, 30, 2) INTB PIRQB
+ PCI_BDF(0, 30, 3) INTC PIRQC
+ PCI_BDF(0, 30, 4) INTD PIRQD
+ PCI_BDF(0, 30, 5) INTB PIRQB
+ PCI_BDF(0, 31, 3) INTB PIRQB
+
+ /*
+ * PCIe root ports downstream
+ * interrupts
+ */
+ PCI_BDF(1, 0, 0) INTA PIRQA
+ PCI_BDF(1, 0, 0) INTB PIRQB
+ PCI_BDF(1, 0, 0) INTC PIRQC
+ PCI_BDF(1, 0, 0) INTD PIRQD
+ PCI_BDF(2, 0, 0) INTA PIRQB
+ PCI_BDF(2, 0, 0) INTB PIRQC
+ PCI_BDF(2, 0, 0) INTC PIRQD
+ PCI_BDF(2, 0, 0) INTD PIRQA
+ PCI_BDF(3, 0, 0) INTA PIRQC
+ PCI_BDF(3, 0, 0) INTB PIRQD
+ PCI_BDF(3, 0, 0) INTC PIRQA
+ PCI_BDF(3, 0, 0) INTD PIRQB
+ PCI_BDF(4, 0, 0) INTA PIRQD
+ PCI_BDF(4, 0, 0) INTB PIRQA
+ PCI_BDF(4, 0, 0) INTC PIRQB
+ PCI_BDF(4, 0, 0) INTD PIRQC
+ >;
+ };
+
+ spi: spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ich9-spi";
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ compatible = "macronix,mx25l6405d",
+ "spi-flash";
+ memory-map = <0xff800000 0x00800000>;
+ rw-mrc-cache {
+ label = "rw-mrc-cache";
+ reg = <0x006f0000 0x00010000>;
+ };
+ };
+ };
+
+ gpioa {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0 0x20>;
+ bank-name = "A";
+ };
+
+ gpiob {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x20 0x20>;
+ bank-name = "B";
+ };
+
+ gpioc {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x40 0x20>;
+ bank-name = "C";
+ };
+
+ gpiod {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x60 0x20>;
+ bank-name = "D";
+ };
+
+ gpioe {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x80 0x20>;
+ bank-name = "E";
+ };
+
+ gpiof {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0xA0 0x20>;
+ bank-name = "F";
+ };
+ };
+ };
+
+ fsp {
+ compatible = "intel,baytrail-fsp";
+ fsp,mrc-init-tseg-size = <0>;
+ fsp,mrc-init-mmio-size = <0x800>;
+ fsp,mrc-init-spd-addr1 = <0xa0>;
+ fsp,mrc-init-spd-addr2 = <0xa2>;
+ fsp,enable-spi;
+ fsp,enable-sata;
+ fsp,sata-mode = <1>;
+ fsp,enable-azalia;
+ fsp,lpss-sio-enable-pci-mode;
+ fsp,enable-dma0;
+ fsp,enable-dma1;
+ fsp,enable-i2c0;
+ fsp,enable-i2c1;
+ fsp,enable-i2c2;
+ fsp,enable-i2c3;
+ fsp,enable-i2c4;
+ fsp,enable-i2c5;
+ fsp,enable-i2c6;
+ fsp,enable-pwm0;
+ fsp,enable-pwm1;
+ fsp,igd-dvmt50-pre-alloc = <2>;
+ fsp,aperture-size = <2>;
+ fsp,gtt-size = <2>;
+ fsp,scc-enable-pci-mode;
+ fsp,os-selection = <4>;
+ fsp,enable-igd;
+ fsp,serial-debug-port-address = <0x3f8>;
+ fsp,serial-debug-port-type = <1>;
+ };
+
+ microcode {
+ update@0 {
+#include "microcode/m0130673325.dtsi"
+ };
+ update@1 {
+#include "microcode/m0130679907.dtsi"
+ };
+ };
+
+};
diff --git a/arch/x86/include/asm/acpi/global_nvs.h b/arch/x86/include/asm/acpi/global_nvs.h
new file mode 100644
index 0000000000..7f2ffd49ec
--- /dev/null
+++ b/arch/x86/include/asm/acpi/global_nvs.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ACPI_GNVS_H_
+#define _ACPI_GNVS_H_
+
+/*
+ * This file provides two ACPI global NVS macros: ACPI_GNVS_ADDR and
+ * ACPI_GNVS_SIZE. They are to be used in platform's global_nvs.asl file
+ * to declare the GNVS OperationRegion, as well as write_acpi_tables()
+ * for the GNVS address runtime fix up.
+ */
+#define ACPI_GNVS_ADDR 0xdeadbeef
+#define ACPI_GNVS_SIZE 0x100
+
+#endif /* _ACPI_GNVS_H_ */
diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h
index 56aa282127..caff4d8a1e 100644
--- a/arch/x86/include/asm/acpi_table.h
+++ b/arch/x86/include/asm/acpi_table.h
@@ -299,6 +299,9 @@ struct acpi_mcfg_mmconfig {
/* PM1_CNT bit defines */
#define PM1_CNT_SCI_EN (1 << 0)
+/* ACPI global NVS structure */
+struct acpi_global_nvs;
+
/* These can be used by the target port */
void acpi_fill_header(struct acpi_table_header *header, char *signature);
@@ -312,4 +315,5 @@ int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
u8 cpu, u16 flags, u8 lint);
u32 acpi_fill_madt(u32 current);
+void acpi_create_gnvs(struct acpi_global_nvs *gnvs);
u32 write_acpi_tables(u32 start);
diff --git a/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl b/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl
new file mode 100644
index 0000000000..a28d4dfade
--- /dev/null
+++ b/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/acpi/global_nvs.h>
+
+OperationRegion(GNVS, SystemMemory, ACPI_GNVS_ADDR, ACPI_GNVS_SIZE)
+Field(GNVS, ByteAcc, NoLock, Preserve)
+{
+ Offset (0x00),
+ PCNT, 8, /* processor count */
+ IURE, 8, /* internal UART enabled */
+}
diff --git a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
index 22f0d68f4d..fe34d3271c 100644
--- a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
+++ b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
@@ -119,17 +119,14 @@ Device (LPCB)
Method(_STA, 0, Serialized)
{
- /*
- * TODO:
- *
- * Need to hide the internal UART depending on whether
- * internal UART is enabled or not so that external
- * SuperIO UART can be exposed to system.
- */
- Store(1, UI3E)
- Store(1, UI4E)
- Store(1, C1EN)
- Return (STA_VISIBLE)
+ If (LEqual(IURE, 1)) {
+ Store(1, UI3E)
+ Store(1, UI4E)
+ Store(1, C1EN)
+ Return (STA_VISIBLE)
+ } Else {
+ Return (STA_MISSING)
+ }
}
diff --git a/arch/x86/include/asm/arch-baytrail/acpi/platform.asl b/arch/x86/include/asm/arch-baytrail/acpi/platform.asl
index 6bc82ecfe1..a80d2c0e51 100644
--- a/arch/x86/include/asm/arch-baytrail/acpi/platform.asl
+++ b/arch/x86/include/asm/arch-baytrail/acpi/platform.asl
@@ -22,6 +22,9 @@ Method(_WAK, 1)
Return (Package() {0, 0})
}
+/* ACPI global NVS */
+#include "global_nvs.asl"
+
/* TODO: add CPU ASL support */
Scope (\_SB)
diff --git a/arch/x86/include/asm/arch-baytrail/global_nvs.h b/arch/x86/include/asm/arch-baytrail/global_nvs.h
new file mode 100644
index 0000000000..56e362633f
--- /dev/null
+++ b/arch/x86/include/asm/arch-baytrail/global_nvs.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _GLOBAL_NVS_H_
+#define _GLOBAL_NVS_H_
+
+struct __packed acpi_global_nvs {
+ u8 pcnt; /* processor count */
+ u8 iuart_en; /* internal UART enabled */
+
+ /*
+ * Add padding so sizeof(struct acpi_global_nvs) == 0x100.
+ * This must match the size defined in the global_nvs.asl.
+ */
+ u8 rsvd[254];
+};
+
+#endif /* _GLOBAL_NVS_H_ */
diff --git a/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl b/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl
new file mode 100644
index 0000000000..6f0435e1de
--- /dev/null
+++ b/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/acpi/global_nvs.h>
+
+OperationRegion(GNVS, SystemMemory, ACPI_GNVS_ADDR, ACPI_GNVS_SIZE)
+Field(GNVS, ByteAcc, NoLock, Preserve)
+{
+ Offset (0x00),
+ PCNT, 8, /* processor count */
+}
diff --git a/arch/x86/include/asm/arch-quark/acpi/platform.asl b/arch/x86/include/asm/arch-quark/acpi/platform.asl
index bd72842dd6..1ecf153c0f 100644
--- a/arch/x86/include/asm/arch-quark/acpi/platform.asl
+++ b/arch/x86/include/asm/arch-quark/acpi/platform.asl
@@ -22,6 +22,9 @@ Method(_WAK, 1)
Return (Package() {0, 0})
}
+/* ACPI global NVS */
+#include "global_nvs.asl"
+
/* TODO: add CPU ASL support */
Scope (\_SB)
diff --git a/arch/x86/include/asm/arch-quark/global_nvs.h b/arch/x86/include/asm/arch-quark/global_nvs.h
new file mode 100644
index 0000000000..0231da0bcd
--- /dev/null
+++ b/arch/x86/include/asm/arch-quark/global_nvs.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _GLOBAL_NVS_H_
+#define _GLOBAL_NVS_H_
+
+struct __packed acpi_global_nvs {
+ u8 pcnt; /* processor count */
+
+ /*
+ * Add padding so sizeof(struct acpi_global_nvs) == 0x100.
+ * This must match the size defined in the global_nvs.asl.
+ */
+ u8 rsvd[255];
+};
+
+#endif /* _GLOBAL_NVS_H_ */
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index bb71286dba..7001e8ba34 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -11,10 +11,12 @@
#include <cpu.h>
#include <dm.h>
#include <dm/uclass-internal.h>
+#include <asm/acpi/global_nvs.h>
#include <asm/acpi_table.h>
#include <asm/io.h>
#include <asm/lapic.h>
#include <asm/tables.h>
+#include <asm/arch/global_nvs.h>
/*
* IASL compiles the dsdt entries and writes the hex values
@@ -336,6 +338,7 @@ u32 write_acpi_tables(u32 start)
struct acpi_fadt *fadt;
struct acpi_mcfg *mcfg;
struct acpi_madt *madt;
+ int i;
current = start;
@@ -383,6 +386,25 @@ u32 write_acpi_tables(u32 start)
current += dsdt->length - sizeof(struct acpi_table_header);
current = ALIGN(current, 16);
+ /* Pack GNVS into the ACPI table area */
+ for (i = 0; i < dsdt->length; i++) {
+ u32 *gnvs = (u32 *)((u32)dsdt + i);
+ if (*gnvs == ACPI_GNVS_ADDR) {
+ debug("Fix up global NVS in DSDT to 0x%08x\n", current);
+ *gnvs = current;
+ break;
+ }
+ }
+
+ /* Update DSDT checksum since we patched the GNVS address */
+ dsdt->checksum = 0;
+ dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
+
+ /* Fill in platform-specific global NVS variables */
+ acpi_create_gnvs((struct acpi_global_nvs *)current);
+ current += sizeof(struct acpi_global_nvs);
+ current = ALIGN(current, 16);
+
debug("ACPI: * FADT\n");
fadt = (struct acpi_fadt *)current;
current += sizeof(struct acpi_fadt);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
index b05dcede0c..a480361211 100644
--- a/arch/x86/lib/fsp/fsp_support.c
+++ b/arch/x86/lib/fsp/fsp_support.c
@@ -110,7 +110,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
struct upd_region *fsp_upd;
#endif
-#ifdef CONFIG_DEBUG_UART
+#ifdef CONFIG_INTERNAL_UART
setup_internal_uart(1);
#endif