diff options
Diffstat (limited to 'arch')
119 files changed, 3207 insertions, 199 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1fc887ba59..150320c6af 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -255,6 +255,10 @@ config ARCH_ZYNQ bool "Xilinx Zynq-based boards" select HAS_DEBUG_LL +config ARCH_QEMU + bool "ARM QEMU boards" + select HAS_DEBUG_LL + endchoice source arch/arm/cpu/Kconfig @@ -280,6 +284,7 @@ source arch/arm/mach-vexpress/Kconfig source arch/arm/mach-tegra/Kconfig source arch/arm/mach-uemd/Kconfig source arch/arm/mach-zynq/Kconfig +source arch/arm/mach-qemu/Kconfig config ARM_ASM_UNIFIED bool @@ -313,8 +318,41 @@ config ARM_BOARD_APPEND_ATAG This option is purely to start some vendor provided kernels. ** DO NOT USE FOR YOUR OWN DESIGNS! ** +config ARM_BOARD_PREPEND_ATAG + bool "Prepend the board specific ATAGs" + depends on ARM_BOARD_APPEND_ATAG + help + Choose this option if your kernel crops the passed ATAG list e.g. at + ATAG_MEM, also cropping off the board specific ATAGs. This option + will pass all board specific ATAGs in front of all other ATAGs. + This option is purely to start some vendor provided kernels. + ** DO NOT USE FOR YOUR OWN DESIGNS! ** + endmenu +choice + prompt "Barebox code model" + help + You should only select this option if you have a workload that + actually benefits from 64-bit processing or if your machine has + large memory. You will only be presented a single option in this + menu if your system does not support both 32-bit and 64-bit modes. + +config 32BIT + bool "32-bit barebox" + depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL + help + Select this option if you want to build a 32-bit barebox. + +config 64BIT + bool "64-bit barebox" + depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL + select ARCH_DMA_ADDR_T_64BIT + help + Select this option if you want to build a 64-bit barebox. + +endchoice + menu "ARM specific settings" config ARM_OPTIMZED_STRING_FUNCTIONS diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 5ccdb83dc7..9fc3cd3deb 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -1,7 +1,11 @@ CPPFLAGS += -D__ARM__ -fno-strict-aliasing # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: +ifeq ($(CONFIG_CPU_V8),y) +CPPFLAGS +=$(call cc-option,-maarch64,) +else CPPFLAGS +=$(call cc-option,-marm,) +endif ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) CPPFLAGS += -mbig-endian @@ -17,13 +21,16 @@ endif # at least some of the code would be executed with MMU off, lets be # conservative and instruct the compiler not to generate any unaligned # accesses +ifeq ($(CONFIG_CPU_V8),n) CFLAGS += -mno-unaligned-access +endif # This selects which instruction set is used. # Note that GCC does not numerically define an architecture version # macro, but instead defines a whole series of macros which makes # testing for a specific architecture or later rather impossible. +arch-$(CONFIG_CPU_64v8) := -D__LINUX_ARM_ARCH__=8 $(call cc-option,-march=armv8-a) arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) @@ -34,11 +41,15 @@ tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale +ifeq ($(CONFIG_CPU_V8), y) +CFLAGS_ABI :=-mabi=lp64 +else ifeq ($(CONFIG_AEABI),y) CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork else CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) endif +endif ifeq ($(CONFIG_ARM_UNWIND),y) CFLAGS_ABI +=-funwind-tables @@ -51,8 +62,13 @@ CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb endif +ifeq ($(CONFIG_CPU_V8), y) +CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) +AFLAGS += -include asm/unified.h +else CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float $(CFLAGS_THUMB2) AFLAGS += -include asm/unified.h -msoft-float $(AFLAGS_THUMB2) +endif # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. @@ -78,6 +94,7 @@ machine-$(CONFIG_ARCH_VEXPRESS) := vexpress machine-$(CONFIG_ARCH_TEGRA) := tegra machine-$(CONFIG_ARCH_UEMD) := uemd machine-$(CONFIG_ARCH_ZYNQ) := zynq +machine-$(CONFIG_ARCH_QEMU) := qemu # Board directory name. This list is sorted alphanumerically @@ -235,6 +252,7 @@ imxcfg-$(CONFIG_MACH_FREESCALE_MX35_3STACK) += $(boarddir)/freescale-mx35-3ds/fl imxcfg-$(CONFIG_MACH_TQMA53) += $(boarddir)/tqma53/flash-header.imxcfg imxcfg-$(CONFIG_MACH_EUKREA_CPUIMX25) += $(boarddir)/eukrea_cpuimx25/flash-header.imxcfg imxcfg-$(CONFIG_MACH_EUKREA_CPUIMX35) += $(boarddir)/eukrea_cpuimx35/flash-header.imxcfg +imxcfg-$(CONFIG_MACH_KINDLE3) += $(boarddir)/kindle3/flash-header.imxcfg imxcfg-$(CONFIG_TX53_REV_1011) += $(boarddir)/karo-tx53/flash-header-tx53-rev1011.imxcfg imxcfg-$(CONFIG_TX53_REV_XX30) += $(boarddir)/karo-tx53/flash-header-tx53-revxx30.imxcfg ifneq ($(imxcfg-y),) @@ -275,13 +293,29 @@ MACH := endif common-y += $(BOARD) arch/arm/boards/ $(MACH) -common-y += arch/arm/lib/ arch/arm/cpu/ -common-y += arch/arm/crypto/ +common-y += arch/arm/cpu/ +common-y += arch/arm/lib/ + +ifeq ($(CONFIG_CPU_V8), y) +common-y += arch/arm/lib64/ +else +common-y += arch/arm/lib32/ arch/arm/crypto/ +endif common-$(CONFIG_OFTREE) += arch/arm/dts/ -lds-y := arch/arm/lib/barebox.lds +ifeq ($(CONFIG_CPU_V8), y) +lds-y := arch/arm/lib64/barebox.lds +else +lds-y := arch/arm/lib32/barebox.lds +endif common- += $(patsubst %,arch/arm/boards/%/,$(board-)) -CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds barebox-flash-image +CLEAN_FILES += include/generated/mach-types.h barebox-flash-image + +ifeq ($(CONFIG_CPU_V8), y) +CLEAN_FILES += arch/arm/lib64/barebox.lds +else +CLEAN_FILES += arch/arm/lib32/barebox.lds +endif diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 9241b664c9..e3dcc6a615 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_MACH_HIGHBANK) += highbank/ obj-$(CONFIG_MACH_IMX21ADS) += freescale-mx21-ads/ obj-$(CONFIG_MACH_IMX233_OLINUXINO) += imx233-olinuxino/ obj-$(CONFIG_MACH_IMX27ADS) += freescale-mx27-ads/ +obj-$(CONFIG_MACH_KINDLE3) += kindle3/ obj-$(CONFIG_MACH_LENOVO_IX4_300D) += lenovo-ix4-300d/ obj-$(CONFIG_MACH_LUBBOCK) += lubbock/ obj-$(CONFIG_MACH_MAINSTONE) += mainstone/ @@ -135,3 +136,4 @@ obj-$(CONFIG_MACH_VIRT2REAL) += virt2real/ obj-$(CONFIG_MACH_ZEDBOARD) += avnet-zedboard/ obj-$(CONFIG_MACH_ZYLONITE) += zylonite/ obj-$(CONFIG_MACH_VARISCITE_MX6) += variscite-mx6/ +obj-$(CONFIG_MACH_QEMU_VIRT64) += qemu-virt64/ diff --git a/arch/arm/boards/ccxmx53/lowlevel.c b/arch/arm/boards/ccxmx53/lowlevel.c index 55f6f366ac..22492140d8 100644 --- a/arch/arm/boards/ccxmx53/lowlevel.c +++ b/arch/arm/boards/ccxmx53/lowlevel.c @@ -17,6 +17,7 @@ #include <common.h> #include <linux/sizes.h> #include <io.h> +#include <mach/imx53-regs.h> #include <mach/esdctl.h> #include <mach/generic.h> #include <image-metadata.h> @@ -36,7 +37,7 @@ ENTRY_FUNCTION(start_ccxmx53_512mb, r0, r1, r2) void *fdt; imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); IMD_USED(ccxmx53_memsize_SZ_512M); @@ -50,7 +51,7 @@ ENTRY_FUNCTION(start_ccxmx53_1gib, r0, r1, r2) void *fdt; imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); IMD_USED(ccxmx53_memsize_SZ_1G); diff --git a/arch/arm/boards/efika-mx-smartbook/board.c b/arch/arm/boards/efika-mx-smartbook/board.c index d1d020e762..d7c11dc2fc 100644 --- a/arch/arm/boards/efika-mx-smartbook/board.c +++ b/arch/arm/boards/efika-mx-smartbook/board.c @@ -122,9 +122,13 @@ static void efikamx_power_init(struct mc13xxx *mc) /* Set VDIG to 1.8V, VGEN3 to 1.8V, VCAM to 2.6V */ mc13xxx_reg_read(mc, MC13892_REG_SETTING_0, &val); val &= ~(MC13892_SETTING_0_VCAM_MASK | + MC13892_SETTING_0_VGEN1_MASK | + MC13892_SETTING_0_VGEN2_MASK | MC13892_SETTING_0_VGEN3_MASK | MC13892_SETTING_0_VDIG_MASK); val |= MC13892_SETTING_0_VDIG_1_8 | + MC13892_SETTING_0_VGEN1_1_2 | + MC13892_SETTING_0_VGEN2_3_15 | MC13892_SETTING_0_VGEN3_1_8 | MC13892_SETTING_0_VCAM_2_6; mc13xxx_reg_write(mc, MC13892_REG_SETTING_0, val); @@ -136,9 +140,7 @@ static void efikamx_power_init(struct mc13xxx *mc) MC13892_SETTING_1_VAUDIO_MASK); val |= MC13892_SETTING_1_VSD_3_15 | MC13892_SETTING_1_VAUDIO_3_0 | - MC13892_SETTING_1_VVIDEO_2_775 | - MC13892_SETTING_1_VGEN1_1_2 | - MC13892_SETTING_1_VGEN2_3_15; + MC13892_SETTING_1_VVIDEO_2_775; mc13xxx_reg_write(mc, MC13892_REG_SETTING_1, val); /* Enable VGEN1, VGEN2, VDIG, VPLL */ diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c index 9c4ea13d8e..04ef9b2e00 100644 --- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c +++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c @@ -232,10 +232,12 @@ static int eukrea_cpuimx35_core_init(void) { u32 reg; - /* enable clock for I2C1, SDHC1, USB and FEC */ + /* enable clock for I2C1, ESDHC1, USB and FEC */ + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR0); + reg |= 0x3 << MX35_CCM_CGR0_ESDHC1_SHIFT; + reg = writel(reg, MX35_CCM_BASE_ADDR + MX35_CCM_CGR0); reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); reg |= 0x3 << MX35_CCM_CGR1_FEC_SHIFT; - reg |= 0x3 << MX35_CCM_CGR1_SDHC1_SHIFT; reg |= 0x3 << MX35_CCM_CGR1_I2C1_SHIFT, reg = writel(reg, MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR2); @@ -318,9 +320,6 @@ static int eukrea_cpuimx35_core_init(void) core_initcall(eukrea_cpuimx35_core_init); -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) - static int do_cpufreq(int argc, char *argv[]) { unsigned long freq; diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c index 83c25feb41..aca77a7fbf 100644 --- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c +++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c @@ -30,11 +30,6 @@ #include <asm-generic/memory_layout.h> #include <asm/system.h> -/* Assuming 24MHz input clock */ -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) -#define PPCTL_PARAM_300 (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) - void __bare_init __naked barebox_arm_reset_vector(void) { uint32_t r, s; @@ -92,17 +87,18 @@ void __bare_init __naked barebox_arm_reset_vector(void) writel(0x00001000, ccm_base + MX35_CCM_PDR0); r = readl(ccm_base + MX35_CCM_CGR0); - r |= 0x00300000; + r |= 0x3 << MX35_CCM_CGR0_EPIT1_SHIFT; writel(r, ccm_base + MX35_CCM_CGR0); r = readl(ccm_base + MX35_CCM_CGR1); - r |= 0x00030C00; - r |= 0x00000003; + r |= 0x3 << MX35_CCM_CGR1_FEC_SHIFT; + r |= 0x3 << MX35_CCM_CGR1_I2C1_SHIFT; + r |= 0x3 << MX35_CCM_CGR1_IOMUX_SHIFT; writel(r, ccm_base + MX35_CCM_CGR1); /* enable watchdog asap */ r = readl(ccm_base + MX35_CCM_CGR2); - r |= 0x03000000; + r |= 0x3 << MX35_CCM_CGR2_WDOG_SHIFT; writel(r, ccm_base + MX35_CCM_CGR2); r = readl(MX35_L2CC_BASE_ADDR + L2X0_AUX_CTRL); diff --git a/arch/arm/boards/freescale-mx25-3ds/lowlevel_init.S b/arch/arm/boards/freescale-mx25-3ds/lowlevel_init.S index a5d54e8d01..bf3830d8d6 100644 --- a/arch/arm/boards/freescale-mx25-3ds/lowlevel_init.S +++ b/arch/arm/boards/freescale-mx25-3ds/lowlevel_init.S @@ -35,9 +35,8 @@ strb r1, [r0]; /* Assuming 24MHz input clock */ -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 (IMX_PLL_PD(1) | IMX_PLL_MFD(0) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) -#define PPCTL_PARAM_300 (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) +#define MPCTL_PARAM_532_MX25 \ + (IMX_PLL_PD(1) | IMX_PLL_MFD(0) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) .section ".text_bare_init","ax" @@ -46,7 +45,7 @@ L2CACHE_PARAM: .word 0x00030024 CCM_CCMR_W: .word 0x003F4208 CCM_PDR0_W: .word 0x00801000 MPCTL_PARAM_399_W: .word MPCTL_PARAM_399 -MPCTL_PARAM_532_W: .word MPCTL_PARAM_532 +MPCTL_PARAM_532_W: .word MPCTL_PARAM_532_MX25 PPCTL_PARAM_W: .word PPCTL_PARAM_300 CCM_BASE_ADDR_W: .word MX25_CCM_BASE_ADDR diff --git a/arch/arm/boards/freescale-mx35-3ds/lowlevel_init.S b/arch/arm/boards/freescale-mx35-3ds/lowlevel_init.S index 0f9e813191..011de6dadf 100644 --- a/arch/arm/boards/freescale-mx35-3ds/lowlevel_init.S +++ b/arch/arm/boards/freescale-mx35-3ds/lowlevel_init.S @@ -40,11 +40,6 @@ ldr r1, =val; \ strb r1, [r0]; -/* Assuming 24MHz input clock */ -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) -#define PPCTL_PARAM_300 (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) - .section ".text_bare_init","ax" ARM_PPMRR: .word 0x40000015 diff --git a/arch/arm/boards/freescale-mx53-qsb/lowlevel.c b/arch/arm/boards/freescale-mx53-qsb/lowlevel.c index ce6a290ca2..bed886357c 100644 --- a/arch/arm/boards/freescale-mx53-qsb/lowlevel.c +++ b/arch/arm/boards/freescale-mx53-qsb/lowlevel.c @@ -1,4 +1,5 @@ #include <common.h> +#include <mach/imx53-regs.h> #include <mach/esdctl.h> #include <mach/generic.h> #include <asm/barebox-arm-head.h> @@ -12,7 +13,7 @@ ENTRY_FUNCTION(start_imx53_loco, r0, r1, r2) void *fdt; imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); fdt = __dtb_imx53_qsb_start - get_runtime_offset(); @@ -26,7 +27,7 @@ ENTRY_FUNCTION(start_imx53_loco_r, r0, r1, r2) void *fdt; imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); fdt = __dtb_imx53_qsrb_start - get_runtime_offset(); diff --git a/arch/arm/boards/freescale-mx53-smd/lowlevel.c b/arch/arm/boards/freescale-mx53-smd/lowlevel.c index 5ad0312e82..88c461da73 100644 --- a/arch/arm/boards/freescale-mx53-smd/lowlevel.c +++ b/arch/arm/boards/freescale-mx53-smd/lowlevel.c @@ -1,4 +1,5 @@ #include <common.h> +#include <mach/imx53-regs.h> #include <mach/esdctl.h> #include <mach/generic.h> #include <asm/barebox-arm-head.h> @@ -6,6 +7,6 @@ void __naked barebox_arm_reset_vector(void) { imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); imx53_barebox_entry(NULL); } diff --git a/arch/arm/boards/guf-cupid/board.c b/arch/arm/boards/guf-cupid/board.c index 6ec74eb49b..d1b285cfaf 100644 --- a/arch/arm/boards/guf-cupid/board.c +++ b/arch/arm/boards/guf-cupid/board.c @@ -318,9 +318,6 @@ static int cupid_core_setup(void) core_initcall(cupid_core_setup); -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) - static int do_cpufreq(int argc, char *argv[]) { unsigned long freq; diff --git a/arch/arm/boards/guf-cupid/lowlevel.c b/arch/arm/boards/guf-cupid/lowlevel.c index bcd2a24f8f..66d76ae795 100644 --- a/arch/arm/boards/guf-cupid/lowlevel.c +++ b/arch/arm/boards/guf-cupid/lowlevel.c @@ -30,11 +30,6 @@ #include <asm-generic/memory_layout.h> #include <asm/system.h> -/* Assuming 24MHz input clock */ -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) -#define PPCTL_PARAM_300 (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) - #define SDRAM_MODE_BL_8 0x0003 #define SDRAM_MODE_BSEQ 0x0000 #define SDRAM_MODE_CL_3 0x0030 @@ -294,11 +289,12 @@ void __bare_init __naked barebox_arm_reset_vector(void) /* configure clock-gates */ r0 = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR0); - r0 |= 0x00300000; + r0 |= 0x3 << MX35_CCM_CGR0_EPIT1_SHIFT; writel(r0, MX35_CCM_BASE_ADDR + MX35_CCM_CGR0); r0 = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); - r0 |= 0x00000c03; + r0 |= 0x3 << MX35_CCM_CGR1_FEC_SHIFT; + r0 |= 0x3 << MX35_CCM_CGR1_I2C1_SHIFT; writel(r0, MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); /* Configure SDRAM */ diff --git a/arch/arm/boards/guf-vincell/lowlevel.c b/arch/arm/boards/guf-vincell/lowlevel.c index a72eaf8b81..af7c65d9be 100644 --- a/arch/arm/boards/guf-vincell/lowlevel.c +++ b/arch/arm/boards/guf-vincell/lowlevel.c @@ -129,7 +129,7 @@ static noinline void imx53_guf_vincell_init(void *fdt) u32 r; imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); writel(0x0088494c, ccm + MX5_CCM_CBCDR); writel(0x02b12f0a, ccm + MX5_CCM_CSCMR2); diff --git a/arch/arm/boards/karo-tx53/lowlevel.c b/arch/arm/boards/karo-tx53/lowlevel.c index fdfb1b7573..9f584fa256 100644 --- a/arch/arm/boards/karo-tx53/lowlevel.c +++ b/arch/arm/boards/karo-tx53/lowlevel.c @@ -2,13 +2,14 @@ #include <asm/barebox-arm-head.h> #include <asm/barebox-arm.h> #include <mach/imx5.h> +#include <mach/imx53-regs.h> #include <mach/esdctl.h> #include <mach/generic.h> void __naked barebox_arm_reset_vector(void) { imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); /* * For the TX53 rev 8030 the SDRAM setup is not stable without diff --git a/arch/arm/boards/karo-tx6x/flash-header-tx6dl-512m.imxcfg b/arch/arm/boards/karo-tx6x/flash-header-tx6dl-512m.imxcfg new file mode 100644 index 0000000000..dd1ae6e5e9 --- /dev/null +++ b/arch/arm/boards/karo-tx6x/flash-header-tx6dl-512m.imxcfg @@ -0,0 +1,136 @@ +soc imx6 +loadaddr 0x20000000 +dcdofs 0x400 + +wm 32 0x020e0158 0x00000016 +wm 32 0x020e0174 0x00000011 +wm 32 0x020e0528 0x0000f079 +wm 32 0x020e0544 0x0000f079 +wm 32 0x020e0868 0x00000001 +wm 32 0x020e086c 0x00000001 +wm 32 0x020e0214 0x00000012 +wm 32 0x020e031c 0x00000015 +wm 32 0x020e0704 0x000030b0 +wm 32 0x020e0154 0x00000015 +wm 32 0x020e0524 0x000030b0 +wm 32 0x020e0218 0x00000005 +wm 32 0x020e05e8 0x000030b0 +wm 32 0x020c402c 0x006336c1 +wm 32 0x020c4034 0x00012093 +wm 32 0x020c4038 0x00012090 +wm 32 0x020c80e0 0x00002001 +wm 32 0x020c80a0 0x80082029 +wm 32 0x020c80b0 0x00065b9a +wm 32 0x020c80c0 0x000f4240 +wm 32 0x020e0004 0x48640005 +wm 32 0x020e0330 0x00000001 +wm 32 0x020e032c 0x00000001 +wm 32 0x020e08fc 0x00000002 +wm 32 0x020e0314 0x00000001 +wm 32 0x020e0318 0x00000001 +wm 32 0x020e08f8 0x00000003 +wm 32 0x020e027c 0x00000000 +wm 32 0x020e0470 0x00020030 +wm 32 0x020e0474 0x00020030 +wm 32 0x020e0478 0x00020030 +wm 32 0x020e047c 0x00020030 +wm 32 0x020e0424 0x00020200 +wm 32 0x020e0428 0x00020200 +wm 32 0x020e0444 0x00020200 +wm 32 0x020e0448 0x00020200 +wm 32 0x020e044c 0x00020200 +wm 32 0x020e0450 0x00020200 +wm 32 0x020e0454 0x00020200 +wm 32 0x020e0458 0x00020200 +wm 32 0x020e045c 0x00020200 +wm 32 0x020e0460 0x00020200 +wm 32 0x020e042c 0x00020200 +wm 32 0x020e0430 0x00020200 +wm 32 0x020e0434 0x00020200 +wm 32 0x020e0438 0x00020200 +wm 32 0x020e043c 0x00020200 +wm 32 0x020e0440 0x00020200 +wm 32 0x020e0464 0x00020030 +wm 32 0x020e0490 0x00020030 +wm 32 0x020e04ac 0x00020030 +wm 32 0x020e04b0 0x00020030 +wm 32 0x020e0494 0x00020030 +wm 32 0x020e04a4 0x00003000 +wm 32 0x020e04a8 0x00003000 +wm 32 0x020e0498 0x00000000 +wm 32 0x020e049c 0x00000000 +wm 32 0x020e04a0 0x00000000 +wm 32 0x020e04b4 0x00003030 +wm 32 0x020e04b8 0x00003030 +wm 32 0x020e0784 0x00000030 +wm 32 0x020e0788 0x00000030 +wm 32 0x020e0794 0x00000030 +wm 32 0x020e079c 0x00000030 +wm 32 0x020e074c 0x00000030 +wm 32 0x020e0750 0x00020000 +wm 32 0x020e0754 0x00000000 +wm 32 0x020e0760 0x00020000 +wm 32 0x020e078c 0x00000030 +wm 32 0x020e0798 0x000c0000 +wm 32 0x020e0758 0x00002000 +wm 32 0x020e075c 0x00000000 +wm 32 0x021b001c 0x04008010 +wm 32 0x021b001c 0x04008040 +wm 32 0x021b0800 0xa1390001 +wm 32 0x021b080c 0x001e001e +wm 32 0x021b0810 0x001e001e +wm 32 0x021b083c 0x42490244 +wm 32 0x021b0840 0x022f0238 +wm 32 0x021b0848 0x40404040 +wm 32 0x021b0850 0x40404040 +wm 32 0x021b081c 0x33333333 +wm 32 0x021b0820 0x33333333 +wm 32 0x021b0824 0x33333333 +wm 32 0x021b0828 0x33333333 +wm 32 0x021b08b8 0x00000800 +wm 32 0x021b0018 0x00000742 +check 32 while_all_bits_clear 0x021b0018 0x00000002 +wm 32 0x021b001c 0x00008000 +check 32 while_any_bit_clear 0x021b001c 0x00004000 +wm 32 0x021b0000 0x83190000 +check 32 while_any_bit_clear 0x021b0018 0x40000000 +wm 32 0x021b000c 0x3f435333 +wm 32 0x021b0010 0xb66e8a63 +wm 32 0x021b0014 0x01ff00db +wm 32 0x021b002c 0x000026d2 +wm 32 0x021b0030 0x00431023 +wm 32 0x021b0008 0x1b333030 +wm 32 0x021b0004 0x0002006d +wm 32 0x021b0040 0x00000017 +wm 32 0x021b001c 0x05208030 +wm 32 0x021b001c 0x00048031 +wm 32 0x021b001c 0x00408032 +wm 32 0x021b001c 0x00008033 +wm 32 0x021b0020 0x0000c000 +wm 32 0x021b001c 0x00008020 +wm 32 0x021b0818 0x00022222 +wm 32 0x021b0890 0x00000003 +wm 32 0x021b0404 0x00000001 +wm 32 0x021b001c 0x04008010 +wm 32 0x021b001c 0x04008040 +wm 32 0x021b0800 0xa1390001 +check 32 while_all_bits_clear 0x021b0800 0x00010000 +wm 32 0x021b0800 0xa1380000 +wm 32 0x021b001c 0x00048033 +wm 32 0x020e04bc 0x00000030 +wm 32 0x020e04c0 0x00000030 +wm 32 0x020e04c4 0x00000030 +wm 32 0x020e04c8 0x00000030 +wm 32 0x021b001c 0x04008050 +wm 32 0x021b0860 0x00000030 +check 32 while_all_bits_clear 0x021b0860 0x0000001f +wm 32 0x021b001c 0x04008050 +wm 32 0x021b0864 0x00000030 +check 32 while_all_bits_clear 0x021b0864 0x0000001f +wm 32 0x021b001c 0x00008033 +wm 32 0x021b0800 0xa138002b +wm 32 0x021b0020 0x00001800 +wm 32 0x021b0404 0x00001000 +wm 32 0x021b0004 0x0002556d +wm 32 0x021b001c 0x00000000 +check 32 while_all_bits_clear 0x021b001c 0x00004000 diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c index 459c44b845..f2643efb05 100644 --- a/arch/arm/boards/karo-tx6x/lowlevel.c +++ b/arch/arm/boards/karo-tx6x/lowlevel.c @@ -38,6 +38,26 @@ static inline void setup_uart(void) extern char __dtb_imx6dl_tx6u_start[]; +BAREBOX_IMD_TAG_STRING(tx6x_mx6_memsize_512M, IMD_TYPE_PARAMETER, "memsize=512", 0); + +ENTRY_FUNCTION(start_imx6dl_tx6x_512m, r0, r1, r2) +{ + void *fdt; + + imx6_cpu_lowlevel_init(); + + arm_setup_stack(0x00920000 - 8); + + IMD_USED(tx6x_mx6_memsize_512M); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); + + fdt = __dtb_imx6dl_tx6u_start - get_runtime_offset(); + + barebox_arm_entry(0x10000000, SZ_512M, fdt); +} + BAREBOX_IMD_TAG_STRING(tx6x_mx6_memsize_1G, IMD_TYPE_PARAMETER, "memsize=1024", 0); ENTRY_FUNCTION(start_imx6dl_tx6x_1g, r0, r1, r2) diff --git a/arch/arm/boards/kindle3/Makefile b/arch/arm/boards/kindle3/Makefile new file mode 100644 index 0000000000..86c746240e --- /dev/null +++ b/arch/arm/boards/kindle3/Makefile @@ -0,0 +1,2 @@ +obj-y += kindle3.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/kindle3/env/boot/mmc_kernel b/arch/arm/boards/kindle3/env/boot/mmc_kernel new file mode 100644 index 0000000000..c6145b85ac --- /dev/null +++ b/arch/arm/boards/kindle3/env/boot/mmc_kernel @@ -0,0 +1,7 @@ +#!/bin/sh +# Boot the Amazon factory-shipped kernel uimage stored on +# the eMMC at MOVINAND_OFFSET_KERNEL=266240. + +global linux.bootargs.dyn.root="root=/dev/mmcblk0p1 ro" + +bootm -c -a 0x80008000 /dev/disk0.kernel diff --git a/arch/arm/boards/kindle3/env/init/serials b/arch/arm/boards/kindle3/env/init/serials new file mode 100644 index 0000000000..76580aeece --- /dev/null +++ b/arch/arm/boards/kindle3/env/init/serials @@ -0,0 +1,21 @@ +#!/bin/sh + +global board.serial16 +global board.revision16 + +# 16-byte alphanumeric containing the serial number +# SN is the first 16 bytes before the bootloader +if test -b /dev/disk0.serial; then + if memcpy -s /dev/disk0.serial -d tmp_serial16 -b 0 0 16; then + readf tmp_serial16 global.board.serial16 + fi +fi +[ -f tmp_serial16 ] && rm tmp_serial16 + +# 16-byte alphanumeric containing the board revision +if test -b /dev/disk0.imx_header; then + if memcpy -s /dev/disk0.imx_header -d tmp_revision16 -b 2032 0 16; then + readf tmp_revision16 global.board.revision16 + fi +fi +[ -f tmp_revision16 ] && rm tmp_revision16 diff --git a/arch/arm/boards/kindle3/env/init/usbconsole b/arch/arm/boards/kindle3/env/init/usbconsole new file mode 100644 index 0000000000..87a8f9bf8c --- /dev/null +++ b/arch/arm/boards/kindle3/env/init/usbconsole @@ -0,0 +1,8 @@ +#!/bin/sh + +# Fiveway device select key activates usbserial access for 60s +echo +if gpio_get_value 63; then + usbserial + global.autoboot_timeout=60 +fi diff --git a/arch/arm/boards/kindle3/env/nv/autoboot_timeout b/arch/arm/boards/kindle3/env/nv/autoboot_timeout new file mode 100644 index 0000000000..00750edc07 --- /dev/null +++ b/arch/arm/boards/kindle3/env/nv/autoboot_timeout @@ -0,0 +1 @@ +3 diff --git a/arch/arm/boards/kindle3/env/nv/boot.default b/arch/arm/boards/kindle3/env/nv/boot.default new file mode 100644 index 0000000000..3118b7af45 --- /dev/null +++ b/arch/arm/boards/kindle3/env/nv/boot.default @@ -0,0 +1 @@ +mmc_kernel diff --git a/arch/arm/boards/kindle3/env/nv/linux.bootargs.base b/arch/arm/boards/kindle3/env/nv/linux.bootargs.base new file mode 100644 index 0000000000..3a940d88fa --- /dev/null +++ b/arch/arm/boards/kindle3/env/nv/linux.bootargs.base @@ -0,0 +1 @@ +mem=256M ip=none diff --git a/arch/arm/boards/kindle3/env/nv/linux.bootargs.console b/arch/arm/boards/kindle3/env/nv/linux.bootargs.console new file mode 100644 index 0000000000..d775310b40 --- /dev/null +++ b/arch/arm/boards/kindle3/env/nv/linux.bootargs.console @@ -0,0 +1 @@ +console=ttymxc0,115200 diff --git a/arch/arm/boards/kindle3/env/nv/linux.bootargs.lpj b/arch/arm/boards/kindle3/env/nv/linux.bootargs.lpj new file mode 100644 index 0000000000..aa3ba59e55 --- /dev/null +++ b/arch/arm/boards/kindle3/env/nv/linux.bootargs.lpj @@ -0,0 +1 @@ +lpj=2555904 diff --git a/arch/arm/boards/kindle3/flash-header.imxcfg b/arch/arm/boards/kindle3/flash-header.imxcfg new file mode 100644 index 0000000000..cb56acf9cd --- /dev/null +++ b/arch/arm/boards/kindle3/flash-header.imxcfg @@ -0,0 +1,24 @@ +soc imx35 +loadaddr 0x87eff400 +dcdofs 0x400 + +wm 32 0x53f80004 0x00821000 +wm 32 0x53f80004 0x00821000 +wm 32 0xb8001010 0x00000002 +wm 32 0xb8001010 0x00000004 +wm 32 0xb8001004 0x0019672f +wm 32 0xb8001000 0x93100000 +wm 8 0x80000400 0xda +wm 32 0xb8001000 0xa3100000 +wm 32 0x80000000 0x12344321 +wm 32 0x80000000 0x12344321 +wm 32 0xb8001000 0xb3100000 +wm 8 0x80000033 0xda +wm 8 0x82000000 0xff +wm 32 0xb8001000 0x83226080 +wm 32 0xb8001010 0x0000000c +wm 32 0x80000000 0xdeadbeef +wm 32 0xb8001030 0x00e78000 +wm 32 0x43fac004 0x00000004 +wm 32 0x43fac328 0x00002100 +wm 32 0x43fac7d0 0x00000000 diff --git a/arch/arm/boards/kindle3/kindle3.c b/arch/arm/boards/kindle3/kindle3.c new file mode 100644 index 0000000000..e06b3d70ce --- /dev/null +++ b/arch/arm/boards/kindle3/kindle3.c @@ -0,0 +1,318 @@ +/* + * (C) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> + * (C) 2016 Alexander Kurz <akurz@blala.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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 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. + * + * Board support for the Amazon Kindle 3rd generation + */ + +#include <common.h> +#include <command.h> +#include <driver.h> +#include <init.h> +#include <bootsource.h> +#include <io.h> +#include <environment.h> +#include <generated/mach-types.h> +#include <asm/armlinux.h> +#include <asm/mmu.h> +#include <asm/setup.h> +#include <mach/imx35-regs.h> +#include <mach/imx-pll.h> +#include <mach/iomux-mx35.h> +#include <mach/devices-imx35.h> +#include <mach/generic.h> +#include <usb/fsl_usb2.h> +#include <mach/usb.h> +#include <mach/spi.h> +#include <spi/spi.h> +#include <magicvar.h> + +/* 16 byte id for serial number */ +#define ATAG_SERIAL16 0x5441000a +/* 16 byte id for a board revision */ +#define ATAG_REVISION16 0x5441000b + +struct char16_tag { + char data[16]; +}; + +static struct tag *setup_16char_tag(struct tag *params, uint32_t tag, + const char *value) +{ + struct char16_tag *target; + target = ((void *) params) + sizeof(struct tag_header); + params->hdr.tag = tag; + params->hdr.size = tag_size(char16_tag); + memcpy(target->data, value, sizeof target->data); + return tag_next(params); +} + +static const char *get_env_16char_tag(const char *tag) +{ + static const char *default16 = "0000000000000000"; + const char *value; + value = getenv(tag); + if (!value) { + printf("env var %s not found, using default\n", tag); + return default16; + } + if (strlen(value) != 16) { + printf("env var %s: expecting 16 characters, using default\n", + tag); + return default16; + } + printf("%s: %s\n", tag, value); + return value; +} + +BAREBOX_MAGICVAR_NAMED(global_atags_serial16, global.board.serial16, + "Pass the kindle Serial as vendor-specific ATAG to linux"); +BAREBOX_MAGICVAR_NAMED(global_atags_revision16, global.board.revision16, + "Pass the kindle BoardId as vendor-specific ATAG to linux"); + +/* The Kindle3 Kernel expects two custom ATAGs, ATAG_REVISION16 describing + * the board and ATAG_SERIAL16 to identify the individual device. + */ +struct tag *kindle3_append_atags(struct tag *params) +{ + params = setup_16char_tag(params, ATAG_SERIAL16, + get_env_16char_tag("global.board.serial16")); + params = setup_16char_tag(params, ATAG_REVISION16, + get_env_16char_tag("global.board.revision16")); + return params; +} + +static struct fsl_usb2_platform_data kindle3_usb_info = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_UTMI, +}; + +/* SPI master devices. */ +static int kindle3_spi0_internal_chipselect[] = { + IMX_GPIO_NR(1, 18), +}; + +static struct spi_imx_master kindle3_spi0_info = { + .chipselect = kindle3_spi0_internal_chipselect, + .num_chipselect = ARRAY_SIZE(kindle3_spi0_internal_chipselect), +}; + +static const struct spi_board_info kindle3_spi_board_info[] = { + { + .name = "mc13892", + .bus_num = 0, + .chip_select = 0, + .mode = SPI_CS_HIGH, + }, +}; + +static int kindle3_mmu_init(void) +{ + l2x0_init((void __iomem *)0x30000000, 0x00030024, 0x00000000); + + return 0; +} +postmmu_initcall(kindle3_mmu_init); + +static int kindle3_devices_init(void) +{ + imx35_add_mmc0(NULL); + + if (IS_ENABLED(CONFIG_USB_GADGET)) { + unsigned int tmp; + /* Workaround ENGcm09152 */ + tmp = readl(MX35_USB_OTG_BASE_ADDR + 0x608); + writel(tmp | (1 << 23), MX35_USB_OTG_BASE_ADDR + 0x608); + add_generic_device("fsl-udc", DEVICE_ID_DYNAMIC, NULL, + MX35_USB_OTG_BASE_ADDR, 0x200, + IORESOURCE_MEM, &kindle3_usb_info); + } + + /* The kindle3 related linux patch published by amazon bluntly + * renamed MACH_MX35_3DS to MACH_MX35_LUIGI + */ + armlinux_set_architecture(MACH_TYPE_MX35_3DS); + + /* Compatibility ATAGs for original kernel */ + armlinux_set_atag_appender(kindle3_append_atags); + return 0; +} +device_initcall(kindle3_devices_init); + +static iomux_v3_cfg_t kindle3_pads[] = { + /* UART1 */ + MX35_PAD_RXD1__UART1_RXD_MUX, + MX35_PAD_TXD1__UART1_TXD_MUX, + + /* eMMC */ + MX35_PAD_SD1_CMD__ESDHC1_CMD, + MX35_PAD_SD1_CLK__ESDHC1_CLK, + MX35_PAD_SD1_DATA0__ESDHC1_DAT0, + MX35_PAD_SD1_DATA1__ESDHC1_DAT1, + MX35_PAD_SD1_DATA2__ESDHC1_DAT2, + MX35_PAD_SD1_DATA3__ESDHC1_DAT3, + + /* USB */ + MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, + MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, + + /* I2C 1+2 */ + MX35_PAD_I2C1_CLK__I2C1_SCL, + MX35_PAD_I2C1_DAT__I2C1_SDA, + MX35_PAD_I2C2_CLK__I2C2_SCL, + MX35_PAD_I2C2_DAT__I2C2_SDA, + + /* SPI */ + MX35_PAD_CSPI1_SS0__GPIO1_18, + MX35_PAD_CSPI1_SCLK__CSPI1_SCLK, + MX35_PAD_CSPI1_MOSI__CSPI1_MOSI, + MX35_PAD_CSPI1_MISO__CSPI1_MISO, + MX35_PAD_CSPI1_SPI_RDY__CSPI1_RDY, + + /* fiveway device: up, down, left, right, select */ + MX35_PAD_ATA_DATA14__GPIO2_27, + MX35_PAD_ATA_DATA15__GPIO2_28, + MX35_PAD_TX5_RX0__GPIO1_10, + MX35_PAD_ATA_BUFF_EN__GPIO2_30, + IOMUX_PAD(0x728, 0x2c4, 5, 0x8c8, 1, + PAD_CTL_PUS_100K_UP | PAD_CTL_HYS | PAD_CTL_DVS), + + /* Volume keys: up, down */ + MX35_PAD_SCKR__GPIO1_4, + MX35_PAD_FSR__GPIO1_5, + +}; + +static int kindle3_part_init(void) +{ + devfs_add_partition("disk0", SZ_1K, 2 * SZ_1K, + DEVFS_PARTITION_FIXED, "disk0.imx_header"); + devfs_add_partition("disk0", 4 * SZ_1K, (192 - 1) * SZ_1K, + DEVFS_PARTITION_FIXED, "disk0.self"); + devfs_add_partition("disk0", (192 + 3) * SZ_1K, SZ_64K, + DEVFS_PARTITION_FIXED, "env0"); + devfs_add_partition("disk0", (256 + 3) * SZ_1K, SZ_1K, + DEVFS_PARTITION_FIXED, "disk0.serial"); + devfs_add_partition("disk0", (256 + 4) * SZ_1K, 3407872, + DEVFS_PARTITION_FIXED, "disk0.kernel"); + devfs_add_partition("disk0", 3674112, SZ_256K, + DEVFS_PARTITION_FIXED, "disk0.waveform"); + return 0; +} + +late_initcall(kindle3_part_init); + +static int imx35_console_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(kindle3_pads, + ARRAY_SIZE(kindle3_pads)); + + barebox_set_model("Kindle3"); + barebox_set_hostname("kindle3"); + + imx35_add_uart0(); + + spi_register_board_info(kindle3_spi_board_info, + ARRAY_SIZE(kindle3_spi_board_info)); + imx35_add_spi0(&kindle3_spi0_info); + + imx35_add_i2c0(NULL); + imx35_add_i2c1(NULL); + return 0; +} +console_initcall(imx35_console_init); + +static int kindle3_core_setup(void) +{ + u32 tmp; + + /* AIPS setup - Only setup MPROTx registers. + * The PACR default values are good. + */ + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + writel(0x77777777, MX35_AIPS1_BASE_ADDR); + writel(0x77777777, MX35_AIPS1_BASE_ADDR + 0x4); + writel(0x77777777, MX35_AIPS2_BASE_ADDR); + writel(0x77777777, MX35_AIPS2_BASE_ADDR + 0x4); + + /* + * Clear the on and off peripheral modules Supervisor Protect bit + * for SDMA to access them. Did not change the AIPS control registers + * (offset 0x20) access type + */ + writel(0x0, MX35_AIPS1_BASE_ADDR + 0x40); + writel(0x0, MX35_AIPS1_BASE_ADDR + 0x44); + writel(0x0, MX35_AIPS1_BASE_ADDR + 0x48); + writel(0x0, MX35_AIPS1_BASE_ADDR + 0x4C); + tmp = readl(MX35_AIPS1_BASE_ADDR + 0x50); + tmp &= 0x00FFFFFF; + writel(tmp, MX35_AIPS1_BASE_ADDR + 0x50); + + writel(0x0, MX35_AIPS2_BASE_ADDR + 0x40); + writel(0x0, MX35_AIPS2_BASE_ADDR + 0x44); + writel(0x0, MX35_AIPS2_BASE_ADDR + 0x48); + writel(0x0, MX35_AIPS2_BASE_ADDR + 0x4C); + tmp = readl(MX35_AIPS2_BASE_ADDR + 0x50); + tmp &= 0x00FFFFFF; + writel(tmp, MX35_AIPS2_BASE_ADDR + 0x50); + + /* MAX (Multi-Layer AHB Crossbar Switch) setup */ + + /* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */ +#define MAX_PARAM1 0x00302154 + writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x0); /* for S0 */ + writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x100); /* for S1 */ + writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x200); /* for S2 */ + writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x300); /* for S3 */ + writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x400); /* for S4 */ + + /* SGPCR - always park on last master */ + writel(0x10, MX35_MAX_BASE_ADDR + 0x10); /* for S0 */ + writel(0x10, MX35_MAX_BASE_ADDR + 0x110); /* for S1 */ + writel(0x10, MX35_MAX_BASE_ADDR + 0x210); /* for S2 */ + writel(0x10, MX35_MAX_BASE_ADDR + 0x310); /* for S3 */ + writel(0x10, MX35_MAX_BASE_ADDR + 0x410); /* for S4 */ + + /* MGPCR - restore default values */ + writel(0x0, MX35_MAX_BASE_ADDR + 0x800); /* for M0 */ + writel(0x0, MX35_MAX_BASE_ADDR + 0x900); /* for M1 */ + writel(0x0, MX35_MAX_BASE_ADDR + 0xa00); /* for M2 */ + writel(0x0, MX35_MAX_BASE_ADDR + 0xb00); /* for M3 */ + writel(0x0, MX35_MAX_BASE_ADDR + 0xc00); /* for M4 */ + writel(0x0, MX35_MAX_BASE_ADDR + 0xd00); /* for M5 */ + + /* + * M3IF Control Register (M3IFCTL) + * MRRP[0] = L2CC0 not on priority list (0 << 0) = 0x00000000 + * MRRP[1] = MAX1 not on priority list (0 << 0) = 0x00000000 + * MRRP[2] = L2CC1 not on priority list (0 << 0) = 0x00000000 + * MRRP[3] = USB not on priority list (0 << 0) = 0x00000000 + * MRRP[4] = SDMA not on priority list (0 << 0) = 0x00000000 + * MRRP[5] = GPU not on priority list (0 << 0) = 0x00000000 + * MRRP[6] = IPU1 on priority list (1 << 6) = 0x00000040 + * MRRP[7] = IPU2 not on priority list (0 << 0) = 0x00000000 + * ------------ + * 0x00000040 + */ + writel(0x40, MX35_M3IF_BASE_ADDR); + + return 0; +} + +core_initcall(kindle3_core_setup); diff --git a/arch/arm/boards/kindle3/lowlevel.c b/arch/arm/boards/kindle3/lowlevel.c new file mode 100644 index 0000000000..58e6318f65 --- /dev/null +++ b/arch/arm/boards/kindle3/lowlevel.c @@ -0,0 +1,142 @@ +/* + * + * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> + * (c) 2016 Alexander Kurz <akurz@blala.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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 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. + * + */ +#include <common.h> +#include <init.h> +#include <mach/imx35-regs.h> +#include <mach/imx-pll.h> +#include <mach/esdctl.h> +#include <asm/cache-l2x0.h> +#include <io.h> +#include <mach/imx-nand.h> +#include <asm/barebox-arm.h> +#include <asm/barebox-arm-head.h> +#include <asm/sections.h> +#include <asm-generic/memory_layout.h> +#include <asm/system.h> + +void __bare_init __naked barebox_arm_reset_vector(void) +{ + uint32_t r, s; + unsigned long ccm_base = MX35_CCM_BASE_ADDR; + register uint32_t loops = 0x20000; + + arm_cpu_lowlevel_init(); + + arm_setup_stack(MX35_IRAM_BASE_ADDR + MX35_IRAM_SIZE - 8); + + r = get_cr(); + r |= CR_Z; /* Flow prediction (Z) */ + r |= CR_U; /* unaligned accesses */ + r |= CR_FI; /* Low Int Latency */ + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1" : "=r"(s)); + s |= 0x7; + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1" : : "r"(s)); + + set_cr(r); + + r = 0; + __asm__ __volatile__("mcr p15, 0, %0, c15, c2, 4" : : "r"(r)); + + /* + * Branch predicition is now enabled. Flush the BTAC to ensure a valid + * starting point. Don't flush BTAC while it is disabled to avoid + * ARM1136 erratum 408023. + */ + __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 6" : : "r"(r)); + + /* invalidate I cache and D cache */ + __asm__ __volatile__("mcr p15, 0, %0, c7, c7, 0" : : "r"(r)); + + /* invalidate TLBs */ + __asm__ __volatile__("mcr p15, 0, %0, c8, c7, 0" : : "r"(r)); + + /* Drain the write buffer */ + __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(r)); + + /* Also setup the Peripheral Port Remap register inside the core */ + r = 0x40000015; /* start from AIPS 2GB region */ + __asm__ __volatile__("mcr p15, 0, %0, c15, c2, 4" : : "r"(r)); + + /* + * End of ARM1136 init + */ + + writel(0x003F4208, ccm_base + MX35_CCM_CCMR); + + /* Set MPLL , arm clock and ahb clock*/ + writel(MPCTL_PARAM_532, ccm_base + MX35_CCM_MPCTL); + + writel(PPCTL_PARAM_300, ccm_base + MX35_CCM_PPCTL); + writel(0x00001000, ccm_base + MX35_CCM_PDR0); + + r = readl(ccm_base + MX35_CCM_CGR0); + r |= 0x3 << MX35_CCM_CGR0_CSPI1_SHIFT; + r |= 0x3 << MX35_CCM_CGR0_EPIT1_SHIFT; + r |= 0x3 << MX35_CCM_CGR0_ESDHC1_SHIFT; + writel(r, ccm_base + MX35_CCM_CGR0); + + r = readl(ccm_base + MX35_CCM_CGR1); + r |= 0x3 << MX35_CCM_CGR1_IOMUX_SHIFT; + r |= 0x3 << MX35_CCM_CGR1_I2C1_SHIFT; + r |= 0x3 << MX35_CCM_CGR1_I2C2_SHIFT; + r |= 0x3 << MX35_CCM_CGR1_GPIO1_SHIFT; + r |= 0x3 << MX35_CCM_CGR1_GPIO2_SHIFT; + writel(r, ccm_base + MX35_CCM_CGR1); + + r = readl(MX35_L2CC_BASE_ADDR + L2X0_AUX_CTRL); + r |= 0x1000; + writel(r, MX35_L2CC_BASE_ADDR + L2X0_AUX_CTRL); + + /* Skip SDRAM initialization if we run from RAM */ + r = get_pc(); + if (r > 0x80000000 && r < 0x90000000) + goto out; + + /* Init Mobile DDR */ + writel(0x0000000E, MX35_ESDCTL_BASE_ADDR + IMX_ESDMISC); + /* ESD_MISC: Enable DDR SDRAM */ + writel(0x00000004, MX35_ESDCTL_BASE_ADDR + IMX_ESDMISC); + __asm__ volatile ("1:\n" + "subs %0, %1, #1\n" + "bne 1b" : "=r" (loops) : "0" (loops)); + + writel(0x0019672f, MX35_ESDCTL_BASE_ADDR + IMX_ESDCFG0); + /* ESD_ESDCTL0 : select Prechare-All mode */ + writel(0x93220000, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); + writeb(0xda, MX35_CSD0_BASE_ADDR + 0x400); + /* ESD_ESDCTL0: Auto Refresh command */ + writel(0xA3220000, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); + writeb(0xda, MX35_CSD0_BASE_ADDR); + writeb(0xda, MX35_CSD0_BASE_ADDR); + /* ESD_ESDCTL0: Load Mode Register */ + writel(0xB3220000, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); + writeb(0xda, MX35_CSD0_BASE_ADDR + 0x33); + writeb(0xff, MX35_CSD0_BASE_ADDR + 0x2000000); + /* ESD_ESDCTL0: enable Auto-Refresh */ + writel(0x83228080, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); + + writel(0x0000000c, MX35_ESDCTL_BASE_ADDR + IMX_ESDMISC); + writel(0xdeadbeef, MX35_CSD0_BASE_ADDR); + writel(0x00e78000, MX35_CSD0_BASE_ADDR + 0x1030); + +out: + imx35_barebox_entry(NULL); +} diff --git a/arch/arm/boards/phytec-phycore-imx35/lowlevel.c b/arch/arm/boards/phytec-phycore-imx35/lowlevel.c index 1ad5439c28..5e2f335efa 100644 --- a/arch/arm/boards/phytec-phycore-imx35/lowlevel.c +++ b/arch/arm/boards/phytec-phycore-imx35/lowlevel.c @@ -30,11 +30,6 @@ #include <asm-generic/memory_layout.h> #include <asm/system.h> -/* Assuming 24MHz input clock */ -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) -#define PPCTL_PARAM_300 (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) - #define IMX35_CHIP_REVISION_2_1 0x11 #define CCM_PDR0_399 0x00011000 @@ -104,12 +99,12 @@ void __bare_init __naked barebox_arm_reset_vector(void) writel(CCM_PDR0_399, ccm_base + MX35_CCM_PDR0); r = readl(ccm_base + MX35_CCM_CGR0); - r |= 0x00300000; + r |= 0x3 << MX35_CCM_CGR0_EPIT1_SHIFT; writel(r, ccm_base + MX35_CCM_CGR0); r = readl(ccm_base + MX35_CCM_CGR1); - r |= 0x00000C00; - r |= 0x00000003; + r |= 0x3 << MX35_CCM_CGR1_FEC_SHIFT; + r |= 0x3 << MX35_CCM_CGR1_I2C1_SHIFT; writel(r, ccm_base + MX35_CCM_CGR1); r = readl(MX35_L2CC_BASE_ADDR + L2X0_AUX_CTRL); diff --git a/arch/arm/boards/phytec-phycore-imx35/pcm043.c b/arch/arm/boards/phytec-phycore-imx35/pcm043.c index b83698b90a..65b592d0b5 100644 --- a/arch/arm/boards/phytec-phycore-imx35/pcm043.c +++ b/arch/arm/boards/phytec-phycore-imx35/pcm043.c @@ -295,9 +295,6 @@ static int pcm043_core_setup(void) core_initcall(pcm043_core_setup); -#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) -#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) - static int do_cpufreq(int argc, char *argv[]) { unsigned long freq; diff --git a/arch/arm/boards/qemu-virt64/Kconfig b/arch/arm/boards/qemu-virt64/Kconfig new file mode 100644 index 0000000000..b7bee3a245 --- /dev/null +++ b/arch/arm/boards/qemu-virt64/Kconfig @@ -0,0 +1,8 @@ + +if MACH_QEMU + +config ARCH_TEXT_BASE + hex + default 0x40000000 + +endif diff --git a/arch/arm/boards/qemu-virt64/Makefile b/arch/arm/boards/qemu-virt64/Makefile new file mode 100644 index 0000000000..2da0494d49 --- /dev/null +++ b/arch/arm/boards/qemu-virt64/Makefile @@ -0,0 +1,2 @@ +obj-y += init.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/qemu-virt64/env/config b/arch/arm/boards/qemu-virt64/env/config new file mode 100644 index 0000000000..781dbfefa6 --- /dev/null +++ b/arch/arm/boards/qemu-virt64/env/config @@ -0,0 +1,8 @@ +#!/bin/sh + +autoboot_timeout=3 + +bootargs="console=ttyAMA0,115200" + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;31m[barebox@\h]:\w\e[0m\n# " diff --git a/arch/arm/boards/qemu-virt64/init.c b/arch/arm/boards/qemu-virt64/init.c new file mode 100644 index 0000000000..58dba0f68a --- /dev/null +++ b/arch/arm/boards/qemu-virt64/init.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2016 Raphaël Poggi <poggi.raph@gmail.com> + * + * GPLv2 only + */ + +#include <common.h> +#include <init.h> +#include <asm/armlinux.h> +#include <asm/system_info.h> +#include <mach/devices.h> +#include <environment.h> +#include <linux/sizes.h> +#include <io.h> +#include <globalvar.h> +#include <asm/mmu.h> + +static int virt_mem_init(void) +{ + virt_add_ddram(SZ_2G); + + return 0; +} +mem_initcall(virt_mem_init); + +static int virt_env_init(void) +{ + add_cfi_flash_device(0, 0x00000000, SZ_128M, 0); + + devfs_add_partition("nor0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self0"); + devfs_add_partition("nor0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0"); + + return 0; +} +device_initcall(virt_env_init); + +static int virt_console_init(void) +{ + virt_register_uart(0); + + return 0; +} +console_initcall(virt_console_init); + +static int virt_core_init(void) +{ + char *hostname = "virt64"; + + if (cpu_is_cortex_a53()) + hostname = "virt64-a53"; + else if (cpu_is_cortex_a57()) + hostname = "virt64-a57"; + + barebox_set_model("ARM QEMU virt64"); + barebox_set_hostname(hostname); + + return 0; +} +postcore_initcall(virt_core_init); + +#ifdef CONFIG_MMU +static int virt_mmu_enable(void) +{ + /* Mapping all periph and flash range */ + arch_remap_range((void *)0x00000000, 0x40000000, DEV_MEM); + + mmu_enable(); + + return 0; +} +postmmu_initcall(virt_mmu_enable); +#endif diff --git a/arch/arm/boards/qemu-virt64/lowlevel.c b/arch/arm/boards/qemu-virt64/lowlevel.c new file mode 100644 index 0000000000..a60c4b0426 --- /dev/null +++ b/arch/arm/boards/qemu-virt64/lowlevel.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * GPLv2 only + */ + +#include <common.h> +#include <linux/sizes.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <asm/system_info.h> + +void barebox_arm_reset_vector(void) +{ + arm_cpu_lowlevel_init(); + arm_setup_stack(0x40000000 + SZ_2G - SZ_16K); + + barebox_arm_entry(0x40000000, SZ_2G, NULL); +} diff --git a/arch/arm/boards/tqma53/lowlevel.c b/arch/arm/boards/tqma53/lowlevel.c index 4e129e49f6..0cb5952608 100644 --- a/arch/arm/boards/tqma53/lowlevel.c +++ b/arch/arm/boards/tqma53/lowlevel.c @@ -5,6 +5,7 @@ #include <asm/barebox-arm-head.h> #include <asm/barebox-arm.h> #include <mach/imx5.h> +#include <mach/imx53-regs.h> #include <mach/generic.h> #include <image-metadata.h> @@ -44,7 +45,7 @@ ENTRY_FUNCTION(start_imx53_mba53_512mib, r0, r1, r2) imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); IMD_USED(tqma53_memsize_512M); @@ -63,7 +64,7 @@ ENTRY_FUNCTION(start_imx53_mba53_1gib, r0, r1, r2) imx5_cpu_lowlevel_init(); - arm_setup_stack(0xf8020000 - 8); + arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); IMD_USED(tqma53_memsize_1G); diff --git a/arch/arm/boards/variscite-mx6/board.c b/arch/arm/boards/variscite-mx6/board.c index 3585debb51..267f68c6da 100644 --- a/arch/arm/boards/variscite-mx6/board.c +++ b/arch/arm/boards/variscite-mx6/board.c @@ -47,24 +47,19 @@ static int setup_pmic_voltages(void) { unsigned char value, rev_id = 0 ; - struct i2c_adapter *adapter = NULL; + struct i2c_adapter *adapter; struct i2c_client client; - int addr = -1, bus = 0; /* I2C2 bus (2-1 = 1 in barebox numbering) */ - bus = 1; - - /* PFUZE100 device address is 0x08 */ - addr = 0x08; - - adapter = i2c_get_adapter(bus); + adapter = i2c_get_adapter(1); if (!adapter) { - pr_err("i2c bus %d not found\n", bus); + pr_err("i2c2 bus not found\n"); return -ENODEV; } client.adapter = adapter; - client.addr = addr; + /* PFUZE100 device address is 0x08 */ + client.addr = 0x08; /* Attempt to locate the PFUZE100 chip. */ if (i2c_read_reg(&client, 0x00, &value, 1) != 1) { diff --git a/arch/arm/configs/imx_defconfig b/arch/arm/configs/imx_defconfig index 886bcefd9b..69ab021e25 100644 --- a/arch/arm/configs/imx_defconfig +++ b/arch/arm/configs/imx_defconfig @@ -19,6 +19,10 @@ CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y +CONFIG_BOOTM_SHOW_TYPE=y +CONFIG_BOOTM_VERBOSE=y +CONFIG_BOOTM_INITRD=y +CONFIG_BOOTM_OFTREE=y CONFIG_BLSPEC=y CONFIG_CONSOLE_ACTIVATE_NONE=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y @@ -26,10 +30,6 @@ CONFIG_RESET_SOURCE=y CONFIG_LONGHELP=y CONFIG_CMD_IOMEM=y CONFIG_CMD_MEMINFO=y -CONFIG_BOOTM_SHOW_TYPE=y -CONFIG_BOOTM_VERBOSE=y -CONFIG_BOOTM_INITRD=y -CONFIG_BOOTM_OFTREE=y # CONFIG_CMD_BOOTU is not set CONFIG_CMD_GO=y CONFIG_CMD_RESET=y @@ -79,7 +79,6 @@ CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_NET_FEC_IMX=y CONFIG_NET_USB=y CONFIG_NET_USB_ASIX=y -CONFIG_DRIVER_SPI_IMX=y CONFIG_I2C=y CONFIG_I2C_IMX=y CONFIG_MTD=y @@ -89,7 +88,9 @@ CONFIG_CFI_BUFFER_WRITE=y CONFIG_NAND=y # CONFIG_NAND_ECC_SOFT is not set # CONFIG_NAND_ECC_HW_SYNDROME is not set +CONFIG_NAND_ALLOW_ERASE_BAD=y CONFIG_NAND_IMX=y +CONFIG_NAND_IMX_BBM=y CONFIG_MTD_UBI=y CONFIG_MTD_UBI_FASTMAP=y CONFIG_USB_HOST=y @@ -97,7 +98,6 @@ CONFIG_USB_EHCI=y CONFIG_USB_ULPI=y CONFIG_MCI=y CONFIG_MCI_IMX=y -CONFIG_MFD_MC13XXX=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_LED_GPIO_OF=y diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig index 5ab343392c..8594965b54 100644 --- a/arch/arm/configs/imx_v7_defconfig +++ b/arch/arm/configs/imx_v7_defconfig @@ -164,6 +164,7 @@ CONFIG_MFD_MC9SDZ60=y CONFIG_MFD_STMPE=y CONFIG_LED=y CONFIG_LED_GPIO=y +CONFIG_LED_GPIO_OF=y CONFIG_LED_TRIGGERS=y CONFIG_EEPROM_AT25=y CONFIG_EEPROM_AT24=y diff --git a/arch/arm/configs/kindle3_defconfig b/arch/arm/configs/kindle3_defconfig new file mode 100644 index 0000000000..0b7088e867 --- /dev/null +++ b/arch/arm/configs/kindle3_defconfig @@ -0,0 +1,65 @@ +CONFIG_ARCH_IMX=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x30000 +CONFIG_MACH_KINDLE3=y +CONFIG_ARCH_IMX_USBLOADER=y +CONFIG_IMX_IIM=y +CONFIG_AEABI=y +CONFIG_ARM_BOARD_APPEND_ATAG=y +CONFIG_ARM_BOARD_PREPEND_ATAG=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PBL_IMAGE=y +CONFIG_PBL_RELOCATABLE=y +CONFIG_IMAGE_COMPRESSION_XZKERN=y +CONFIG_MALLOC_SIZE=0x2000000 +CONFIG_MALLOC_TLSF=y +CONFIG_RELOCATABLE=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_BOOTM_OFTREE=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/kindle3/env/" +CONFIG_RESET_SOURCE=y +CONFIG_CMD_DMESG=y +CONFIG_LONGHELP=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MMC_EXTCSD=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_GO=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_RESET=y +CONFIG_CMD_UIMAGE=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_DEFAULTENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_READF=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USBGADGET=y +CONFIG_DRIVER_SPI_IMX=y +CONFIG_I2C=y +CONFIG_I2C_IMX=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_SERIAL=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_IMX_ESDHC=y +CONFIG_MFD_MC13XXX=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/configs/qemu_virt64_defconfig b/arch/arm/configs/qemu_virt64_defconfig new file mode 100644 index 0000000000..ed5abef195 --- /dev/null +++ b/arch/arm/configs/qemu_virt64_defconfig @@ -0,0 +1,47 @@ +CONFIG_ARCH_QEMU=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x05000000 +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_MMU=y +# CONFIG_MMU_EARLY is not set +CONFIG_TEXT_BASE=0x41000000 +CONFIG_BAREBOX_MAX_BARE_INIT_SIZE=0x01000000 +CONFIG_PROMPT="qemu-virt64: " +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qemu-virt64/env" +CONFIG_DEBUG_INFO=y +CONFIG_LONGHELP=y +CONFIG_CMD_MEMINFO=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_GO=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_RESET=y +CONFIG_CMD_UIMAGE=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_LOGIN=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_PASSWD=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_OFTREE=y +CONFIG_SERIAL_AMBA_PL011=y +# CONFIG_SPI is not set +CONFIG_MTD=y +CONFIG_DRIVER_CFI=y +CONFIG_CFI_BUFFER_WRITE=y +CONFIG_DIGEST_SHA1_GENERIC=y +CONFIG_DIGEST_SHA256_GENERIC=y diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig index 4f5d9b6e16..450a6d593a 100644 --- a/arch/arm/cpu/Kconfig +++ b/arch/arm/cpu/Kconfig @@ -1,8 +1,14 @@ comment "Processor Type" +config PHYS_ADDR_T_64BIT + bool + config CPU_32 bool - default y + +config CPU_64 + bool + select PHYS_ADDR_T_64BIT # Select CPU types depending on the architecture selected. This selects # which CPUs we support in the kernel image, and the compiler instruction @@ -69,6 +75,12 @@ config CPU_V7 bool select CPU_32v7 +# ARMv8 +config CPU_V8 + bool + select CPU_64v8 + select CPU_SUPPORTS_64BIT_KERNEL + config CPU_XSC3 bool select CPU_32v4T @@ -84,15 +96,23 @@ config CPU_XSCALE # This defines the compiler instruction set which depends on the machine type. config CPU_32v4T bool + select CPU_32 config CPU_32v5 bool + select CPU_32 config CPU_32v6 bool + select CPU_32 config CPU_32v7 bool + select CPU_32 + +config CPU_64v8 + bool + select CPU_64 comment "processor features" @@ -124,3 +144,14 @@ config CACHE_L2X0 bool "Enable L2x0 PrimeCell" depends on MMU && ARCH_HAS_L2X0 +config SYS_SUPPORTS_32BIT_KERNEL + bool + +config SYS_SUPPORTS_64BIT_KERNEL + bool + +config CPU_SUPPORTS_32BIT_KERNEL + bool + +config CPU_SUPPORTS_64BIT_KERNEL + bool diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index 854df60ebb..331c1cd8bc 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -1,7 +1,24 @@ obj-y += cpu.o + +ifeq ($(CONFIG_CPU_64v8), y) +obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions_64.o +obj-$(CONFIG_MMU) += mmu_64.o +lwl-y += lowlevel_64.o +else obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions.o +obj-$(CONFIG_MMU) += mmu.o mmu-early.o +pbl-$(CONFIG_MMU) += mmu-early.o +lwl-y += lowlevel.o +endif + obj-$(CONFIG_ARM_EXCEPTIONS) += interrupts.o -obj-y += start.o setupc.o entry.o +obj-y += start.o entry.o + +ifeq ($(CONFIG_CPU_64v8), y) +obj-y += setupc_64.o +else +obj-y += setupc.o +endif # # Any variants can be called as start-armxyz.S @@ -9,8 +26,7 @@ obj-y += start.o setupc.o entry.o obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o obj-$(CONFIG_OFDEVICE) += dtb.o -obj-$(CONFIG_MMU) += mmu.o cache.o mmu-early.o -pbl-$(CONFIG_MMU) += mmu-early.o +obj-$(CONFIG_MMU) += cache.o ifeq ($(CONFIG_MMU),) obj-y += no-mmu.o @@ -27,6 +43,10 @@ obj-$(CONFIG_CPU_32v7) += cache-armv7.o AFLAGS_pbl-cache-armv7.o :=-Wa,-march=armv7-a pbl-$(CONFIG_CPU_32v7) += cache-armv7.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o +AFLAGS_cache-armv8.o :=-Wa,-march=armv8-a +obj-$(CONFIG_CPU_64v8) += cache-armv8.o +AFLAGS_pbl-cache-armv8.o :=-Wa,-march=armv8-a +pbl-$(CONFIG_CPU_64v8) += cache-armv8.o pbl-y += setupc.o entry.o pbl-$(CONFIG_PBL_SINGLE_IMAGE) += start-pbl.o @@ -34,5 +54,3 @@ pbl-$(CONFIG_PBL_MULTI_IMAGES) += uncompress.o obj-y += common.o cache.o pbl-y += common.o cache.o - -lwl-y += lowlevel.o diff --git a/arch/arm/cpu/cache-armv8.S b/arch/arm/cpu/cache-armv8.S new file mode 100644 index 0000000000..82b2f81778 --- /dev/null +++ b/arch/arm/cpu/cache-armv8.S @@ -0,0 +1,168 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * This file is based on sample code from ARMv8 ARM. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/linkage.h> +#include <init.h> + +/* + * void v8_flush_dcache_level(level) + * + * clean and invalidate one level cache. + * + * x0: cache level + * x1: 0 flush & invalidate, 1 invalidate only + * x2~x9: clobbered + */ +.section .text.v8_flush_dcache_level +ENTRY(v8_flush_dcache_level) + lsl x12, x0, #1 + msr csselr_el1, x12 /* select cache level */ + isb /* sync change of cssidr_el1 */ + mrs x6, ccsidr_el1 /* read the new cssidr_el1 */ + and x2, x6, #7 /* x2 <- log2(cache line size)-4 */ + add x2, x2, #4 /* x2 <- log2(cache line size) */ + mov x3, #0x3ff + and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */ + clz w5, w3 /* bit position of #ways */ + mov x4, #0x7fff + and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */ + /* x12 <- cache level << 1 */ + /* x2 <- line length offset */ + /* x3 <- number of cache ways - 1 */ + /* x4 <- number of cache sets - 1 */ + /* x5 <- bit position of #ways */ + +loop_set: + mov x6, x3 /* x6 <- working copy of #ways */ +loop_way: + lsl x7, x6, x5 + orr x9, x12, x7 /* map way and level to cisw value */ + lsl x7, x4, x2 + orr x9, x9, x7 /* map set number to cisw value */ + tbz w1, #0, 1f + dc isw, x9 + b 2f +1: dc cisw, x9 /* clean & invalidate by set/way */ +2: subs x6, x6, #1 /* decrement the way */ + b.ge loop_way + subs x4, x4, #1 /* decrement the set */ + b.ge loop_set + + ret +ENDPROC(v8_flush_dcache_level) + +/* + * void v8_flush_dcache_all(int invalidate_only) + * + * x0: 0 flush & invalidate, 1 invalidate only + * + * clean and invalidate all data cache by SET/WAY. + */ +.section .text.v8_dcache_all +ENTRY(v8_dcache_all) + mov x1, x0 + dsb sy + mrs x10, clidr_el1 /* read clidr_el1 */ + lsr x11, x10, #24 + and x11, x11, #0x7 /* x11 <- loc */ + cbz x11, finished /* if loc is 0, exit */ + mov x15, x30 + mov x0, #0 /* start flush at cache level 0 */ + /* x0 <- cache level */ + /* x10 <- clidr_el1 */ + /* x11 <- loc */ + /* x15 <- return address */ + +loop_level: + lsl x12, x0, #1 + add x12, x12, x0 /* x0 <- tripled cache level */ + lsr x12, x10, x12 + and x12, x12, #7 /* x12 <- cache type */ + cmp x12, #2 + b.lt skip /* skip if no cache or icache */ + bl v8_flush_dcache_level /* x1 = 0 flush, 1 invalidate */ +skip: + add x0, x0, #1 /* increment cache level */ + cmp x11, x0 + b.gt loop_level + + mov x0, #0 + msr csselr_el1, x0 /* restore csselr_el1 */ + dsb sy + isb + mov x30, x15 + +finished: + ret +ENDPROC(v8_dcache_all) + +.section .text.v8_flush_dcache_all +ENTRY(v8_flush_dcache_all) + mov x16, x30 + mov x0, #0 + bl v8_dcache_all + mov x30, x16 + ret +ENDPROC(v8_flush_dcache_all) + +.section .text.v8_invalidate_dcache_all +ENTRY(v8_invalidate_dcache_all) + mov x16, x30 + mov x0, #0x1 + bl v8_dcache_all + mov x30, x16 + ret +ENDPROC(v8_invalidate_dcache_all) + +/* + * void v8_flush_dcache_range(start, end) + * + * clean & invalidate data cache in the range + * + * x0: start address + * x1: end address + */ +.section .text.v8_flush_dcache_range +ENTRY(v8_flush_dcache_range) + mrs x3, ctr_el0 + lsr x3, x3, #16 + and x3, x3, #0xf + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 +1: dc civac, x0 /* clean & invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(v8_flush_dcache_range) + +/* + * void v8_invalidate_icache_all(void) + * + * invalidate all tlb entries. + */ +.section .text.v8_invalidate_icache_all +ENTRY(v8_invalidate_icache_all) + ic ialluis + isb sy + ret +ENDPROC(v8_invalidate_icache_all) + +.section .text.v8_flush_l3_cache +ENTRY(v8_flush_l3_cache) + mov x0, #0 /* return status as success */ + ret +ENDPROC(v8_flush_l3_cache) + .weak v8_flush_l3_cache diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c index 27ead1c177..929c385df5 100644 --- a/arch/arm/cpu/cache.c +++ b/arch/arm/cpu/cache.c @@ -36,6 +36,7 @@ DEFINE_CPU_FNS(v4) DEFINE_CPU_FNS(v5) DEFINE_CPU_FNS(v6) DEFINE_CPU_FNS(v7) +DEFINE_CPU_FNS(v8) void __dma_clean_range(unsigned long start, unsigned long end) { @@ -101,6 +102,11 @@ int arm_set_cache_functions(void) cache_fns = &cache_fns_armv7; break; #endif +#ifdef CONFIG_CPU_64v8 + case CPU_ARCH_ARMv8: + cache_fns = &cache_fns_armv8; + break; +#endif default: while(1); } @@ -138,6 +144,11 @@ void arm_early_mmu_cache_flush(void) v7_mmu_cache_flush(); return; #endif +#ifdef CONFIG_CPU_64v8 + case CPU_ARCH_ARMv8: + v8_dcache_all(); + return; +#endif } } @@ -146,6 +157,7 @@ void v7_mmu_cache_invalidate(void); void arm_early_mmu_cache_invalidate(void) { switch (arm_early_get_cpu_architecture()) { +#if __LINUX_ARM_ARCH__ <= 7 case CPU_ARCH_ARMv4T: case CPU_ARCH_ARMv5: case CPU_ARCH_ARMv5T: @@ -159,5 +171,12 @@ void arm_early_mmu_cache_invalidate(void) v7_mmu_cache_invalidate(); return; #endif +#else +#ifdef CONFIG_CPU_64v8 + case CPU_ARCH_ARMv8: + v8_invalidate_icache_all(); + return; +#endif +#endif } } diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c index eb12166c16..b4804634b7 100644 --- a/arch/arm/cpu/cpu.c +++ b/arch/arm/cpu/cpu.c @@ -68,6 +68,7 @@ int icache_status(void) return (get_cr () & CR_I) != 0; } +#if __LINUX_ARM_ARCH__ <= 7 /* * SoC like the ux500 have the l2x0 always enable * with or without MMU enable @@ -86,6 +87,7 @@ void mmu_disable(void) } __mmu_cache_off(); } +#endif /** * Disable MMU and D-cache, flush caches @@ -98,8 +100,12 @@ static void arch_shutdown(void) { uint32_t r; +#ifdef CONFIG_MMU mmu_disable(); +#endif flush_icache(); + +#if __LINUX_ARM_ARCH__ <= 7 /* * barebox normally does not use interrupts, but some functionalities * (eg. OMAP4_USBBOOT) require them enabled. So be sure interrupts are @@ -108,6 +114,7 @@ static void arch_shutdown(void) __asm__ __volatile__("mrs %0, cpsr" : "=r"(r)); r |= PSR_I_BIT; __asm__ __volatile__("msr cpsr, %0" : : "r"(r)); +#endif } archshutdown_exitcall(arch_shutdown); diff --git a/arch/arm/cpu/cpuinfo.c b/arch/arm/cpu/cpuinfo.c index 8b22e9bb50..86e19d9780 100644 --- a/arch/arm/cpu/cpuinfo.c +++ b/arch/arm/cpu/cpuinfo.c @@ -30,12 +30,15 @@ #define CPU_ARCH_ARMv5TEJ 7 #define CPU_ARCH_ARMv6 8 #define CPU_ARCH_ARMv7 9 +#define CPU_ARCH_ARMv8 10 #define ARM_CPU_PART_CORTEX_A5 0xC050 #define ARM_CPU_PART_CORTEX_A7 0xC070 #define ARM_CPU_PART_CORTEX_A8 0xC080 #define ARM_CPU_PART_CORTEX_A9 0xC090 #define ARM_CPU_PART_CORTEX_A15 0xC0F0 +#define ARM_CPU_PART_CORTEX_A53 0xD030 +#define ARM_CPU_PART_CORTEX_A57 0xD070 static void decode_cache(unsigned long size) { @@ -60,6 +63,25 @@ static int do_cpuinfo(int argc, char *argv[]) int i; int cpu_arch; +#ifdef CONFIG_CPU_64v8 + __asm__ __volatile__( + "mrs %0, midr_el1\n" + : "=r" (mainid) + : + : "memory"); + + __asm__ __volatile__( + "mrs %0, ctr_el0\n" + : "=r" (cache) + : + : "memory"); + + __asm__ __volatile__( + "mrs %0, sctlr_el1\n" + : "=r" (cr) + : + : "memory"); +#else __asm__ __volatile__( "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n" : "=r" (mainid) @@ -74,9 +96,10 @@ static int do_cpuinfo(int argc, char *argv[]) __asm__ __volatile__( "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" - : "=r" (cr) - : - : "memory"); + : "=r" (cr) + : + : "memory"); +#endif switch (mainid >> 24) { case 0x41: @@ -107,6 +130,23 @@ static int do_cpuinfo(int argc, char *argv[]) if (cpu_arch) cpu_arch += CPU_ARCH_ARMv3; } else if ((mainid & 0x000f0000) == 0x000f0000) { +#ifdef CONFIG_CPU_64v8 + unsigned int isar2; + + __asm__ __volatile__( + "mrs %0, id_isar2_el1\n" + : "=r" (isar2) + : + : "memory"); + + + /* Check Load/Store acquire to check if ARMv8 or not */ + + if (isar2 & 0x2) + cpu_arch = CPU_ARCH_ARMv8; + else + cpu_arch = CPU_ARCH_UNKNOWN; +#else unsigned int mmfr0; /* Revised CPUID format. Read the Memory Model Feature @@ -121,6 +161,7 @@ static int do_cpuinfo(int argc, char *argv[]) cpu_arch = CPU_ARCH_ARMv6; else cpu_arch = CPU_ARCH_UNKNOWN; +#endif } else cpu_arch = CPU_ARCH_UNKNOWN; @@ -152,6 +193,9 @@ static int do_cpuinfo(int argc, char *argv[]) case CPU_ARCH_ARMv7: architecture = "v7"; break; + case CPU_ARCH_ARMv8: + architecture = "v8"; + break; case CPU_ARCH_UNKNOWN: default: architecture = "Unknown"; @@ -160,7 +204,7 @@ static int do_cpuinfo(int argc, char *argv[]) printf("implementer: %s\narchitecture: %s\n", implementer, architecture); - if (cpu_arch == CPU_ARCH_ARMv7) { + if (cpu_arch >= CPU_ARCH_ARMv7) { unsigned int major, minor; char *part; major = (mainid >> 20) & 0xf; @@ -181,6 +225,12 @@ static int do_cpuinfo(int argc, char *argv[]) case ARM_CPU_PART_CORTEX_A15: part = "Cortex-A15"; break; + case ARM_CPU_PART_CORTEX_A53: + part = "Cortex-A53"; + break; + case ARM_CPU_PART_CORTEX_A57: + part = "Cortex-A57"; + break; default: part = "unknown"; } diff --git a/arch/arm/cpu/exceptions_64.S b/arch/arm/cpu/exceptions_64.S new file mode 100644 index 0000000000..58120253a1 --- /dev/null +++ b/arch/arm/cpu/exceptions_64.S @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/ptrace.h> +#include <linux/linkage.h> + +/* + * Enter Exception. + * This will save the processor state that is ELR/X0~X30 + * to the stack frame. + */ +.macro exception_entry + stp x29, x30, [sp, #-16]! + stp x27, x28, [sp, #-16]! + stp x25, x26, [sp, #-16]! + stp x23, x24, [sp, #-16]! + stp x21, x22, [sp, #-16]! + stp x19, x20, [sp, #-16]! + stp x17, x18, [sp, #-16]! + stp x15, x16, [sp, #-16]! + stp x13, x14, [sp, #-16]! + stp x11, x12, [sp, #-16]! + stp x9, x10, [sp, #-16]! + stp x7, x8, [sp, #-16]! + stp x5, x6, [sp, #-16]! + stp x3, x4, [sp, #-16]! + stp x1, x2, [sp, #-16]! + + /* Could be running at EL3/EL2/EL1 */ + mrs x11, CurrentEL + cmp x11, #0xC /* Check EL3 state */ + b.eq 1f + cmp x11, #0x8 /* Check EL2 state */ + b.eq 2f + cmp x11, #0x4 /* Check EL1 state */ + b.eq 3f +3: mrs x1, esr_el3 + mrs x2, elr_el3 + b 0f +2: mrs x1, esr_el2 + mrs x2, elr_el2 + b 0f +1: mrs x1, esr_el1 + mrs x2, elr_el1 +0: + stp x2, x0, [sp, #-16]! + mov x0, sp +.endm + +/* + * Exception vectors. + */ + .align 11 + .globl vectors +vectors: + .align 7 + b _do_bad_sync /* Current EL Synchronous Thread */ + + .align 7 + b _do_bad_irq /* Current EL IRQ Thread */ + + .align 7 + b _do_bad_fiq /* Current EL FIQ Thread */ + + .align 7 + b _do_bad_error /* Current EL Error Thread */ + + .align 7 + b _do_sync /* Current EL Synchronous Handler */ + + .align 7 + b _do_irq /* Current EL IRQ Handler */ + + .align 7 + b _do_fiq /* Current EL FIQ Handler */ + + .align 7 + b _do_error /* Current EL Error Handler */ + + +_do_bad_sync: + exception_entry + bl do_bad_sync + +_do_bad_irq: + exception_entry + bl do_bad_irq + +_do_bad_fiq: + exception_entry + bl do_bad_fiq + +_do_bad_error: + exception_entry + bl do_bad_error + +_do_sync: + exception_entry + bl do_sync + +_do_irq: + exception_entry + bl do_irq + +_do_fiq: + exception_entry + bl do_fiq + +_do_error: + exception_entry + bl do_error + +.section .data +.align 4 +.global arm_ignore_data_abort +arm_ignore_data_abort: +.word 0 /* When != 0 data aborts are ignored */ +.global arm_data_abort_occurred +arm_data_abort_occurred: +.word 0 /* set != 0 by the data abort handler */ +abort_stack: +.space 8 diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c index fb4bb78dae..c34108a4f8 100644 --- a/arch/arm/cpu/interrupts.c +++ b/arch/arm/cpu/interrupts.c @@ -27,6 +27,8 @@ #include <asm/ptrace.h> #include <asm/unwind.h> + +#if __LINUX_ARM_ARCH__ <= 7 /** * Display current register set content * @param[in] regs Guess what @@ -70,10 +72,13 @@ void show_regs (struct pt_regs *regs) unwind_backtrace(regs); #endif } +#endif static void __noreturn do_exception(struct pt_regs *pt_regs) { +#if __LINUX_ARM_ARCH__ <= 7 show_regs(pt_regs); +#endif panic(""); } @@ -121,6 +126,8 @@ void do_prefetch_abort (struct pt_regs *pt_regs) */ void do_data_abort (struct pt_regs *pt_regs) { + +#if __LINUX_ARM_ARCH__ <= 7 u32 far; asm volatile ("mrc p15, 0, %0, c6, c0, 0" : "=r" (far) : : "cc"); @@ -128,6 +135,7 @@ void do_data_abort (struct pt_regs *pt_regs) printf("unable to handle %s at address 0x%08x\n", far < PAGE_SIZE ? "NULL pointer dereference" : "paging request", far); +#endif do_exception(pt_regs); } @@ -156,6 +164,45 @@ void do_irq (struct pt_regs *pt_regs) do_exception(pt_regs); } +#ifdef CONFIG_CPU_64v8 +void do_bad_sync(struct pt_regs *pt_regs) +{ + printf("bad sync\n"); + do_exception(pt_regs); +} + +void do_bad_irq(struct pt_regs *pt_regs) +{ + printf("bad irq\n"); + do_exception(pt_regs); +} + +void do_bad_fiq(struct pt_regs *pt_regs) +{ + printf("bad fiq\n"); + do_exception(pt_regs); +} + +void do_bad_error(struct pt_regs *pt_regs) +{ + printf("bad error\n"); + do_exception(pt_regs); +} + +void do_sync(struct pt_regs *pt_regs) +{ + printf("sync exception\n"); + do_exception(pt_regs); +} + + +void do_error(struct pt_regs *pt_regs) +{ + printf("error exception\n"); + do_exception(pt_regs); +} +#endif + extern volatile int arm_ignore_data_abort; extern volatile int arm_data_abort_occurred; diff --git a/arch/arm/cpu/lowlevel_64.S b/arch/arm/cpu/lowlevel_64.S new file mode 100644 index 0000000000..4850895169 --- /dev/null +++ b/arch/arm/cpu/lowlevel_64.S @@ -0,0 +1,40 @@ +#include <linux/linkage.h> +#include <init.h> +#include <asm/system.h> + +.section ".text_bare_init_","ax" +ENTRY(arm_cpu_lowlevel_init) + adr x0, vectors + mrs x1, CurrentEL + cmp x1, #0xC /* Check EL3 state */ + b.eq 1f + cmp x1, #0x8 /* Check EL2 state */ + b.eq 2f + cmp x1, #0x4 /* Check EL1 state */ + b.eq 3f + +1: + msr vbar_el3, x0 + mov x0, #1 /* Non-Secure EL0/1 */ + orr x0, x0, #(1 << 10) /* 64-bit EL2 */ + msr scr_el3, x0 + msr cptr_el3, xzr + b done + +2: + msr vbar_el2, x0 + mov x0, #0x33ff /* Enable FP/SIMD */ + msr cptr_el2, x0 + b done + + +3: + msr vbar_el1, x0 + mov x0, #(3 << 20) /* Enable FP/SIMD */ + msr cpacr_el1, x0 + b done + +done: + ret + +ENDPROC(arm_cpu_lowlevel_init) diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h index 79ebc80d7d..186d408ead 100644 --- a/arch/arm/cpu/mmu.h +++ b/arch/arm/cpu/mmu.h @@ -1,6 +1,60 @@ #ifndef __ARM_MMU_H #define __ARM_MMU_H +#ifdef CONFIG_CPU_64v8 + +#define TCR_FLAGS (TCR_TG0_4K | \ + TCR_SHARED_OUTER | \ + TCR_SHARED_INNER | \ + TCR_IRGN_WBWA | \ + TCR_ORGN_WBWA | \ + TCR_T0SZ(BITS_PER_VA)) + +#ifndef __ASSEMBLY__ + +static inline void set_ttbr_tcr_mair(int el, uint64_t table, uint64_t tcr, uint64_t attr) +{ + asm volatile("dsb sy"); + if (el == 1) { + asm volatile("msr ttbr0_el1, %0" : : "r" (table) : "memory"); + asm volatile("msr tcr_el1, %0" : : "r" (tcr) : "memory"); + asm volatile("msr mair_el1, %0" : : "r" (attr) : "memory"); + } else if (el == 2) { + asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory"); + asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory"); + asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory"); + } else if (el == 3) { + asm volatile("msr ttbr0_el3, %0" : : "r" (table) : "memory"); + asm volatile("msr tcr_el3, %0" : : "r" (tcr) : "memory"); + asm volatile("msr mair_el3, %0" : : "r" (attr) : "memory"); + } else { + hang(); + } + asm volatile("isb"); +} + +static inline uint64_t get_ttbr(int el) +{ + uint64_t val; + if (el == 1) { + asm volatile("mrs %0, ttbr0_el1" : "=r" (val)); + } else if (el == 2) { + asm volatile("mrs %0, ttbr0_el2" : "=r" (val)); + } else if (el == 3) { + asm volatile("mrs %0, ttbr0_el3" : "=r" (val)); + } else { + hang(); + } + + return val; +} + +void mmu_early_enable(uint64_t membase, uint64_t memsize, uint64_t _ttb); + +#endif + +#endif /* CONFIG_CPU_64v8 */ + #ifdef CONFIG_MMU void __mmu_cache_on(void); void __mmu_cache_off(void); diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c new file mode 100644 index 0000000000..bfd80c0913 --- /dev/null +++ b/arch/arm/cpu/mmu_64.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2009-2013 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * Copyright (c) 2016 Raphaël Poggi <poggi.raph@gmail.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + */ + +#define pr_fmt(fmt) "mmu: " fmt + +#include <common.h> +#include <dma-dir.h> +#include <init.h> +#include <mmu.h> +#include <errno.h> +#include <linux/sizes.h> +#include <asm/memory.h> +#include <asm/barebox-arm.h> +#include <asm/system.h> +#include <asm/cache.h> +#include <memory.h> +#include <asm/system_info.h> + +#include "mmu.h" + +static uint64_t *ttb; +static int free_idx; + +static void arm_mmu_not_initialized_error(void) +{ + /* + * This means: + * - one of the MMU functions like dma_alloc_coherent + * or remap_range is called too early, before the MMU is initialized + * - Or the MMU initialization has failed earlier + */ + panic("MMU not initialized\n"); +} + + +/* + * Do it the simple way for now and invalidate the entire + * tlb + */ +static inline void tlb_invalidate(void) +{ + unsigned int el = current_el(); + + dsb(); + + if (el == 1) + __asm__ __volatile__("tlbi vmalle1\n\t" : : : "memory"); + else if (el == 2) + __asm__ __volatile__("tlbi alle2\n\t" : : : "memory"); + else if (el == 3) + __asm__ __volatile__("tlbi alle3\n\t" : : : "memory"); + + dsb(); + isb(); +} + +static int level2shift(int level) +{ + /* Page is 12 bits wide, every level translates 9 bits */ + return (12 + 9 * (3 - level)); +} + +static uint64_t level2mask(int level) +{ + uint64_t mask = -EINVAL; + + if (level == 1) + mask = L1_ADDR_MASK; + else if (level == 2) + mask = L2_ADDR_MASK; + else if (level == 3) + mask = L3_ADDR_MASK; + + return mask; +} + +static int pte_type(uint64_t *pte) +{ + return *pte & PMD_TYPE_MASK; +} + +static void set_table(uint64_t *pt, uint64_t *table_addr) +{ + uint64_t val; + + val = PMD_TYPE_TABLE | (uint64_t)table_addr; + *pt = val; +} + +static uint64_t *create_table(void) +{ + uint64_t *new_table = ttb + free_idx * GRANULE_SIZE; + + /* Mark all entries as invalid */ + memset(new_table, 0, GRANULE_SIZE); + + free_idx++; + + return new_table; +} + +static uint64_t *get_level_table(uint64_t *pte) +{ + uint64_t *table = (uint64_t *)(*pte & XLAT_ADDR_MASK); + + if (pte_type(pte) != PMD_TYPE_TABLE) { + table = create_table(); + set_table(pte, table); + } + + return table; +} + +static uint64_t *find_pte(uint64_t addr) +{ + uint64_t *pte; + uint64_t block_shift; + uint64_t idx; + int i; + + pte = ttb; + + for (i = 1; i < 4; i++) { + block_shift = level2shift(i); + idx = (addr & level2mask(i)) >> block_shift; + pte += idx; + + if ((pte_type(pte) != PMD_TYPE_TABLE) || (block_shift <= GRANULE_SIZE_SHIFT)) + break; + else + pte = (uint64_t *)(*pte & XLAT_ADDR_MASK); + } + + return pte; +} + +static void map_region(uint64_t virt, uint64_t phys, uint64_t size, uint64_t attr) +{ + uint64_t block_size; + uint64_t block_shift; + uint64_t *pte; + uint64_t idx; + uint64_t addr; + uint64_t *table; + int level; + + if (!ttb) + arm_mmu_not_initialized_error(); + + addr = virt; + + attr &= ~(PMD_TYPE_SECT); + + while (size) { + table = ttb; + for (level = 1; level < 4; level++) { + block_shift = level2shift(level); + idx = (addr & level2mask(level)) >> block_shift; + block_size = (1 << block_shift); + + pte = table + idx; + + if (level == 3) + attr |= PTE_TYPE_PAGE; + else + attr |= PMD_TYPE_SECT; + + if (size >= block_size && IS_ALIGNED(addr, block_size)) { + *pte = phys | attr; + addr += block_size; + phys += block_size; + size -= block_size; + break; + + } + + table = get_level_table(pte); + } + + } +} + +static void create_sections(uint64_t virt, uint64_t phys, uint64_t size_m, uint64_t flags) +{ + + map_region(virt, phys, size_m, flags); + tlb_invalidate(); +} + +void *map_io_sections(unsigned long phys, void *_start, size_t size) +{ + + map_region((uint64_t)_start, phys, (uint64_t)size, UNCACHED_MEM); + + tlb_invalidate(); + return _start; +} + + +int arch_remap_range(void *_start, size_t size, unsigned flags) +{ + map_region((uint64_t)_start, (uint64_t)_start, (uint64_t)size, flags); + tlb_invalidate(); + + return 0; +} + +/* + * Prepare MMU for usage enable it. + */ +static int mmu_init(void) +{ + struct memory_bank *bank; + + if (list_empty(&memory_banks)) + /* + * If you see this it means you have no memory registered. + * This can be done either with arm_add_mem_device() in an + * initcall prior to mmu_initcall or via devicetree in the + * memory node. + */ + panic("MMU: No memory bank found! Cannot continue\n"); + + if (get_cr() & CR_M) { + ttb = (uint64_t *)get_ttbr(current_el()); + if (!request_sdram_region("ttb", (unsigned long)ttb, SZ_16K)) + /* + * This can mean that: + * - the early MMU code has put the ttb into a place + * which we don't have inside our available memory + * - Somebody else has occupied the ttb region which means + * the ttb will get corrupted. + */ + pr_crit("Critical Error: Can't request SDRAM region for ttb at %p\n", + ttb); + } else { + ttb = memalign(GRANULE_SIZE, SZ_16K); + free_idx = 1; + + memset(ttb, 0, GRANULE_SIZE); + + set_ttbr_tcr_mair(current_el(), (uint64_t)ttb, TCR_FLAGS, UNCACHED_MEM); + } + + pr_debug("ttb: 0x%p\n", ttb); + + /* create a flat mapping using 1MiB sections */ + create_sections(0, 0, GRANULE_SIZE, UNCACHED_MEM); + + /* Map sdram cached. */ + for_each_memory_bank(bank) + create_sections(bank->start, bank->start, bank->size, CACHED_MEM); + + return 0; +} +mmu_initcall(mmu_init); + +void mmu_enable(void) +{ + if (!ttb) + arm_mmu_not_initialized_error(); + + if (!(get_cr() & CR_M)) { + + isb(); + set_cr(get_cr() | CR_M | CR_C | CR_I); + } +} + +void mmu_disable(void) +{ + unsigned int cr; + + if (!ttb) + arm_mmu_not_initialized_error(); + + cr = get_cr(); + cr &= ~(CR_M | CR_C | CR_I); + + tlb_invalidate(); + + dsb(); + isb(); + + set_cr(cr); + + dsb(); + isb(); +} + +void mmu_early_enable(uint64_t membase, uint64_t memsize, uint64_t _ttb) +{ + ttb = (uint64_t *)_ttb; + + memset(ttb, 0, GRANULE_SIZE); + free_idx = 1; + + set_ttbr_tcr_mair(current_el(), (uint64_t)ttb, TCR_FLAGS, UNCACHED_MEM); + + create_sections(0, 0, 4096, UNCACHED_MEM); + + create_sections(membase, membase, memsize, CACHED_MEM); + + isb(); + set_cr(get_cr() | CR_M); +} + +unsigned long virt_to_phys(volatile void *virt) +{ + return (unsigned long)virt; +} + +void *phys_to_virt(unsigned long phys) +{ + return (void *)phys; +} diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S new file mode 100644 index 0000000000..3515854784 --- /dev/null +++ b/arch/arm/cpu/setupc_64.S @@ -0,0 +1,18 @@ +#include <linux/linkage.h> +#include <asm/sections.h> + +.section .text.setupc + +/* + * setup_c: clear bss + */ +ENTRY(setup_c) + mov x15, x30 + ldr x0, =__bss_start + mov x1, #0 + ldr x2, =__bss_stop + sub x2, x2, x0 + bl memset /* clear bss */ + mov x30, x15 + ret +ENDPROC(setup_c) diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index e037d91f9c..f25e5928cb 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -34,9 +34,9 @@ #include "mmu-early.h" unsigned long arm_stack_top; -static unsigned long arm_head_bottom; static unsigned long arm_barebox_size; static void *barebox_boarddata; +static unsigned long barebox_boarddata_size; static bool blob_is_fdt(const void *blob) { @@ -73,6 +73,10 @@ void *barebox_arm_boot_dtb(void) void *data; int ret; struct barebox_arm_boarddata_compressed_dtb *compressed_dtb; + static void *boot_dtb; + + if (boot_dtb) + return boot_dtb; if (barebox_boarddata && blob_is_fdt(barebox_boarddata)) { pr_debug("%s: using barebox_boarddata\n", __func__); @@ -101,9 +105,9 @@ void *barebox_arm_boot_dtb(void) return NULL; } - barebox_boarddata = dtb; + boot_dtb = dtb; - return barebox_boarddata; + return boot_dtb; } static inline unsigned long arm_mem_boarddata(unsigned long membase, @@ -126,11 +130,9 @@ EXPORT_SYMBOL_GPL(arm_mem_ramoops_get); static int barebox_memory_areas_init(void) { - unsigned long start = arm_head_bottom; - unsigned long size = arm_mem_barebox_image(0, arm_stack_top, - arm_barebox_size) - - arm_head_bottom; - request_sdram_region("board data", start, size); + if(barebox_boarddata) + request_sdram_region("board data", (unsigned long)barebox_boarddata, + barebox_boarddata_size); return 0; } @@ -159,7 +161,7 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, arm_stack_top = endmem; arm_barebox_size = barebox_size; - arm_head_bottom = arm_mem_barebox_image(membase, endmem, + malloc_end = arm_mem_barebox_image(membase, endmem, arm_barebox_size); if (IS_ENABLED(CONFIG_MMU_EARLY)) { @@ -197,12 +199,11 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, name, mem); barebox_boarddata = memcpy((void *)mem, boarddata, totalsize); - arm_head_bottom = mem; + barebox_boarddata_size = totalsize; + malloc_end = mem; } } - malloc_end = arm_head_bottom; - /* * Maximum malloc space is the Kconfig value if given * or 1GB. diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index 138ebe2d8c..b51225efe5 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -177,6 +177,11 @@ static inline unsigned long ffz(unsigned long word) #include <asm-generic/bitops/ffs.h> #include <asm-generic/bitops/fls.h> #endif /* __ARM__USE_GENERIC_FF */ + +#if __LINUX_ARM_ARCH__ == 8 +#include <asm-generic/bitops/__fls.h> +#endif + #include <asm-generic/bitops/fls64.h> #include <asm-generic/bitops/hweight.h> diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 2f6eab0e82..8fcdb64f74 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -1,9 +1,18 @@ #ifndef __ASM_CACHE_H #define __ASM_CACHE_H +#ifdef CONFIG_CPU_64v8 +extern void v8_invalidate_icache_all(void); +extern void v8_dcache_all(void); +#endif + static inline void flush_icache(void) { +#if __LINUX_ARM_ARCH__ <= 7 asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); +#else + v8_invalidate_icache_all(); +#endif } int arm_set_cache_functions(void); diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index 8de6544657..f68ab37143 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -6,16 +6,24 @@ #include <malloc.h> #include <xfuncs.h> +#ifdef CONFIG_CPU_64v8 +#include <asm/pgtable64.h> + +#define DEV_MEM (PMD_ATTRINDX(MT_DEVICE_nGnRnE) | PMD_SECT_AF | PMD_TYPE_SECT) +#define CACHED_MEM (PMD_ATTRINDX(MT_NORMAL) | PMD_SECT_S | PMD_SECT_AF | PMD_TYPE_SECT) +#define UNCACHED_MEM (PMD_ATTRINDX(MT_NORMAL_NC) | PMD_SECT_S | PMD_SECT_AF | PMD_TYPE_SECT) +#else #include <asm/pgtable.h> #define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT) #define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED) +#endif + + struct arm_memory; -static inline void mmu_enable(void) -{ -} +void mmu_enable(void); void mmu_disable(void); static inline void arm_create_section(unsigned long virt, unsigned long phys, int size_m, unsigned int flags) diff --git a/arch/arm/include/asm/pgtable64.h b/arch/arm/include/asm/pgtable64.h new file mode 100644 index 0000000000..20bea5b28a --- /dev/null +++ b/arch/arm/include/asm/pgtable64.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * + * 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/>. + */ +#ifndef __ASM_PGTABLE64_H +#define __ASM_PGTABLE64_H + +#define UL(x) _AC(x, UL) + +#define UNUSED_DESC 0x6EbAAD0BBADbA6E0 + +#define VA_START 0x0 +#define BITS_PER_VA 33 + +/* Granule size of 4KB is being used */ +#define GRANULE_SIZE_SHIFT 12 +#define GRANULE_SIZE (1 << GRANULE_SIZE_SHIFT) +#define XLAT_ADDR_MASK ((1UL << BITS_PER_VA) - GRANULE_SIZE) +#define GRANULE_SIZE_MASK ((1 << GRANULE_SIZE_SHIFT) - 1) + +#define BITS_RESOLVED_PER_LVL (GRANULE_SIZE_SHIFT - 3) +#define L1_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 2) +#define L2_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 1) +#define L3_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 0) + + +#define L1_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L1_ADDR_SHIFT) +#define L2_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L2_ADDR_SHIFT) +#define L3_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L3_ADDR_SHIFT) + +/* These macros give the size of the region addressed by each entry of a xlat + table at any given level */ +#define L3_XLAT_SIZE (1UL << L3_ADDR_SHIFT) +#define L2_XLAT_SIZE (1UL << L2_ADDR_SHIFT) +#define L1_XLAT_SIZE (1UL << L1_ADDR_SHIFT) + +#define GRANULE_MASK GRANULE_SIZE + + +/* + * Level 2 descriptor (PMD). + */ +#define PMD_TYPE_MASK (3 << 0) +#define PMD_TYPE_FAULT (0 << 0) +#define PMD_TYPE_TABLE (3 << 0) +#define PMD_TYPE_SECT (1 << 0) +#define PMD_TABLE_BIT (1 << 1) + +/* + * Section + */ +#define PMD_SECT_VALID (1 << 0) +#define PMD_SECT_USER (1 << 6) /* AP[1] */ +#define PMD_SECT_RDONLY (1 << 7) /* AP[2] */ +#define PMD_SECT_S (3 << 8) +#define PMD_SECT_AF (1 << 10) +#define PMD_SECT_NG (1 << 11) +#define PMD_SECT_CONT (1 << 52) +#define PMD_SECT_PXN (1 << 53) +#define PMD_SECT_UXN (1 << 54) + +/* + * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). + */ +#define PMD_ATTRINDX(t) ((t) << 2) +#define PMD_ATTRINDX_MASK (7 << 2) + +/* + * Level 3 descriptor (PTE). + */ +#define PTE_TYPE_MASK (3 << 0) +#define PTE_TYPE_FAULT (0 << 0) +#define PTE_TYPE_PAGE (3 << 0) +#define PTE_TABLE_BIT (1 << 1) +#define PTE_USER (1 << 6) /* AP[1] */ +#define PTE_RDONLY (1 << 7) /* AP[2] */ +#define PTE_SHARED (3 << 8) /* SH[1:0], inner shareable */ +#define PTE_AF (1 << 10) /* Access Flag */ +#define PTE_NG (1 << 11) /* nG */ +#define PTE_DBM (1 << 51) /* Dirty Bit Management */ +#define PTE_CONT (1 << 52) /* Contiguous range */ +#define PTE_PXN (1 << 53) /* Privileged XN */ +#define PTE_UXN (1 << 54) /* User XN */ + +/* + * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). + */ +#define PTE_ATTRINDX(t) ((t) << 2) +#define PTE_ATTRINDX_MASK (7 << 2) + +/* + * Memory types available. + */ +#define MT_DEVICE_nGnRnE 0 +#define MT_DEVICE_nGnRE 1 +#define MT_DEVICE_GRE 2 +#define MT_NORMAL_NC 3 +#define MT_NORMAL 4 +#define MT_NORMAL_WT 5 + +/* + * TCR flags. + */ +#define TCR_T0SZ(x) ((64 - (x)) << 0) +#define TCR_IRGN_NC (0 << 8) +#define TCR_IRGN_WBWA (1 << 8) +#define TCR_IRGN_WT (2 << 8) +#define TCR_IRGN_WBNWA (3 << 8) +#define TCR_IRGN_MASK (3 << 8) +#define TCR_ORGN_NC (0 << 10) +#define TCR_ORGN_WBWA (1 << 10) +#define TCR_ORGN_WT (2 << 10) +#define TCR_ORGN_WBNWA (3 << 10) +#define TCR_ORGN_MASK (3 << 10) +#define TCR_SHARED_NON (0 << 12) +#define TCR_SHARED_OUTER (2 << 12) +#define TCR_SHARED_INNER (3 << 12) +#define TCR_TG0_4K (0 << 14) +#define TCR_TG0_64K (1 << 14) +#define TCR_TG0_16K (2 << 14) +#define TCR_EL1_IPS_BITS (UL(3) << 32) /* 42 bits physical address */ +#define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ +#define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */ + +#define TCR_EL1_RSVD (1 << 31) +#define TCR_EL2_RSVD (1 << 31 | 1 << 23) +#define TCR_EL3_RSVD (1 << 31 | 1 << 23) + +#endif diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h index 9997ad20ef..3795437831 100644 --- a/arch/arm/include/asm/swab.h +++ b/arch/arm/include/asm/swab.h @@ -33,7 +33,11 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x) static inline __attribute_const__ __u32 __arch_swab32(__u32 x) { +#if __LINUX_ARM_ARCH__ == 8 + __asm__ ("rev %w0, %w1" : "=r" (x) : "r" (x)); +#else __asm__ ("rev %0, %1" : "=r" (x) : "r" (x)); +#endif return x; } #define __arch_swab32 __arch_swab32 diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index b118a42609..57c76186b4 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -3,7 +3,11 @@ #if __LINUX_ARM_ARCH__ >= 7 #define isb() __asm__ __volatile__ ("isb" : : : "memory") +#ifdef CONFIG_CPU_64v8 +#define dsb() __asm__ __volatile__ ("dsb sy" : : : "memory") +#else #define dsb() __asm__ __volatile__ ("dsb" : : : "memory") +#endif #define dmb() __asm__ __volatile__ ("dmb" : : : "memory") #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 #define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ @@ -57,17 +61,58 @@ #define CR_TE (1 << 30) /* Thumb exception enable */ #ifndef __ASSEMBLY__ +#if __LINUX_ARM_ARCH__ >= 7 +static inline unsigned int current_el(void) +{ + unsigned int el; + asm volatile("mrs %0, CurrentEL" : "=r" (el) : : "cc"); + return el >> 2; +} + +static inline unsigned long read_mpidr(void) +{ + unsigned long val; + + asm volatile("mrs %0, mpidr_el1" : "=r" (val)); + + return val; +} +#endif static inline unsigned int get_cr(void) { unsigned int val; + +#ifdef CONFIG_CPU_64v8 + unsigned int el = current_el(); + if (el == 1) + asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc"); + else if (el == 2) + asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc"); + else + asm volatile("mrs %0, sctlr_el3" : "=r" (val) : : "cc"); +#else asm volatile ("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); +#endif + return val; } static inline void set_cr(unsigned int val) { +#ifdef CONFIG_CPU_64v8 + unsigned int el; + + el = current_el(); + if (el == 1) + asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc"); + else if (el == 2) + asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc"); + else + asm volatile("msr sctlr_el3, %0" : : "r" (val) : "cc"); +#else asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (val) : "cc"); +#endif isb(); } @@ -90,7 +135,6 @@ static inline void set_vbar(unsigned int vbar) static inline unsigned int get_vbar(void) { return 0; } static inline void set_vbar(unsigned int vbar) {} #endif - #endif #endif /* __ASM_ARM_SYSTEM_H */ diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h index 0761848a1a..25fffd2681 100644 --- a/arch/arm/include/asm/system_info.h +++ b/arch/arm/include/asm/system_info.h @@ -13,6 +13,7 @@ #define CPU_ARCH_ARMv5TEJ 7 #define CPU_ARCH_ARMv6 8 #define CPU_ARCH_ARMv7 9 +#define CPU_ARCH_ARMv8 10 #define CPU_IS_ARM720 0x41007200 #define CPU_IS_ARM720_MASK 0xff00fff0 @@ -41,6 +42,12 @@ #define CPU_IS_CORTEX_A15 0x410fc0f0 #define CPU_IS_CORTEX_A15_MASK 0xff0ffff0 +#define CPU_IS_CORTEX_A53 0x410fd034 +#define CPU_IS_CORTEX_A53_MASK 0xff0ffff0 + +#define CPU_IS_CORTEX_A57 0x411fd070 +#define CPU_IS_CORTEX_A57_MASK 0xff0ffff0 + #define CPU_IS_PXA250 0x69052100 #define CPU_IS_PXA250_MASK 0xfffff7f0 @@ -112,6 +119,19 @@ #define cpu_is_cortex_a15() (0) #endif +#ifdef CONFIG_CPU_64v8 +#ifdef ARM_ARCH +#define ARM_MULTIARCH +#else +#define ARM_ARCH CPU_ARCH_ARMv8 +#endif +#define cpu_is_cortex_a53() cpu_is_arm(CORTEX_A53) +#define cpu_is_cortex_a57() cpu_is_arm(CORTEX_A57) +#else +#define cpu_is_cortex_a53() (0) +#define cpu_is_cortex_a57() (0) +#endif + #ifndef __ASSEMBLY__ #ifdef ARM_MULTIARCH @@ -133,6 +153,23 @@ static inline int arm_early_get_cpu_architecture(void) if (cpu_arch) cpu_arch += CPU_ARCH_ARMv3; } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { +#ifdef CONFIG_CPU_64v8 + unsigned int isar2; + + __asm__ __volatile__( + "mrs %0, id_isar2_el1\n" + : "=r" (isar2) + : + : "memory"); + + + /* Check Load/Store acquire to check if ARMv8 or not */ + + if (isar2 & 0x2) + cpu_arch = CPU_ARCH_ARMv8; + else + cpu_arch = CPU_ARCH_UNKNOWN; +#else unsigned int mmfr0; /* Revised CPUID format. Read the Memory Model Feature @@ -149,6 +186,7 @@ static inline int arm_early_get_cpu_architecture(void) cpu_arch = CPU_ARCH_UNKNOWN; } else cpu_arch = CPU_ARCH_UNKNOWN; +#endif return cpu_arch; } diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index e1c6f5bfd3..33db7350f8 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -1,29 +1,2 @@ -obj-$(CONFIG_ARM_LINUX) += armlinux.o obj-$(CONFIG_BOOTM) += bootm.o -obj-$(CONFIG_CMD_BOOTZ) += bootz.o obj-$(CONFIG_CMD_BOOTU) += bootu.o -obj-y += div0.o -obj-y += findbit.o -obj-y += io.o -obj-y += io-readsb.o -obj-y += io-readsw-armv4.o -obj-y += io-readsl.o -obj-y += io-writesb.o -obj-y += io-writesw-armv4.o -obj-y += io-writesl.o -obj-y += lib1funcs.o -obj-y += ashrdi3.o -obj-y += ashldi3.o -obj-y += lshrdi3.o -obj-y += runtime-offset.o -pbl-y += runtime-offset.o -obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o -obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o -obj-$(CONFIG_ARM_UNWIND) += unwind.o -obj-$(CONFIG_ARM_SEMIHOSTING) += semihosting-trap.o semihosting.o -obj-$(CONFIG_MODULES) += module.o -extra-y += barebox.lds - -pbl-y += lib1funcs.o -pbl-y += ashldi3.o -pbl-y += div0.o diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 803aa94490..252946ce5a 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -81,10 +81,15 @@ static int get_kernel_addresses(size_t image_size, return ret; /* - * We don't know the exact decompressed size so just use a conservative - * default of 4 times the size of the compressed image. + * The kernel documentation "Documentation/arm/Booting" advises + * to place the compressed image outside of the lowest 32 MiB to + * avoid relocation. We should do this if we have at least 64 MiB + * of ram. If we have less space, we assume a maximum + * compression factor of 5. */ - image_decomp_size = PAGE_ALIGN(image_size * 4); + image_decomp_size = PAGE_ALIGN(image_size * 5); + if (mem_size >= SZ_64M) + image_decomp_size = max_t(size_t, image_decomp_size, SZ_32M); /* * By default put oftree/initrd close behind compressed kernel image to @@ -113,6 +118,13 @@ static int get_kernel_addresses(size_t image_size, *mem_free = PAGE_ALIGN(*load_address + image_size + spacing); + /* + * Place oftree/initrd outside of the first 128 MiB, if we have space + * for it. This avoids potential conflicts with the kernel decompressor. + */ + if (mem_size > SZ_256M) + *mem_free = max(*mem_free, mem_start + SZ_128M); + return 0; } diff --git a/arch/arm/lib/.gitignore b/arch/arm/lib32/.gitignore index d1165788c9..d1165788c9 100644 --- a/arch/arm/lib/.gitignore +++ b/arch/arm/lib32/.gitignore diff --git a/arch/arm/lib32/Makefile b/arch/arm/lib32/Makefile new file mode 100644 index 0000000000..cdd07322cf --- /dev/null +++ b/arch/arm/lib32/Makefile @@ -0,0 +1,27 @@ +obj-$(CONFIG_ARM_LINUX) += armlinux.o +obj-$(CONFIG_CMD_BOOTZ) += bootz.o +obj-y += div0.o +obj-y += findbit.o +obj-y += io.o +obj-y += io-readsb.o +obj-y += io-readsw-armv4.o +obj-y += io-readsl.o +obj-y += io-writesb.o +obj-y += io-writesw-armv4.o +obj-y += io-writesl.o +obj-y += lib1funcs.o +obj-y += ashrdi3.o +obj-y += ashldi3.o +obj-y += lshrdi3.o +obj-y += runtime-offset.o +pbl-y += runtime-offset.o +obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o +obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o +obj-$(CONFIG_ARM_UNWIND) += unwind.o +obj-$(CONFIG_ARM_SEMIHOSTING) += semihosting-trap.o semihosting.o +obj-$(CONFIG_MODULES) += module.o +extra-y += barebox.lds + +pbl-y += lib1funcs.o +pbl-y += ashldi3.o +pbl-y += div0.o diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib32/armlinux.c index 47b9bd33ed..6c7bd101c2 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib32/armlinux.c @@ -107,8 +107,9 @@ static struct tag *armlinux_get_bootparams(void) BUG(); } -#ifdef CONFIG_ARM_BOARD_APPEND_ATAG static struct tag *(*atag_appender)(struct tag *); + +#if defined CONFIG_ARM_BOARD_APPEND_ATAG void armlinux_set_atag_appender(struct tag *(*func)(struct tag *)) { atag_appender = func; @@ -234,6 +235,9 @@ static void setup_tags(unsigned long initrd_address, const char *commandline = linux_bootargs_get(); setup_start_tag(); + if (IS_ENABLED(CONFIG_ARM_BOARD_PREPEND_ATAG) && atag_appender) + params = atag_appender(params); + setup_memory_tags(); setup_commandline_tag(commandline, swap); @@ -242,10 +246,10 @@ static void setup_tags(unsigned long initrd_address, setup_revision_tag(); setup_serial_tag(); -#ifdef CONFIG_ARM_BOARD_APPEND_ATAG - if (atag_appender != NULL) + if (IS_ENABLED(CONFIG_ARM_BOARD_APPEND_ATAG) && atag_appender && + !IS_ENABLED(CONFIG_ARM_BOARD_PREPEND_ATAG)) params = atag_appender(params); -#endif + setup_end_tag(); printf("commandline: %s\n" diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib32/ashldi3.S index b62e06f602..b62e06f602 100644 --- a/arch/arm/lib/ashldi3.S +++ b/arch/arm/lib32/ashldi3.S diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib32/ashrdi3.S index db849b65fc..db849b65fc 100644 --- a/arch/arm/lib/ashrdi3.S +++ b/arch/arm/lib32/ashrdi3.S diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib32/barebox.lds.S index 6dc8bd2f3c..6dc8bd2f3c 100644 --- a/arch/arm/lib/barebox.lds.S +++ b/arch/arm/lib32/barebox.lds.S diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib32/bootz.c index 5167c9d20d..5167c9d20d 100644 --- a/arch/arm/lib/bootz.c +++ b/arch/arm/lib32/bootz.c diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib32/copy_template.S index d8eb06328a..d8eb06328a 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib32/copy_template.S diff --git a/arch/arm/lib/div0.c b/arch/arm/lib32/div0.c index 852cb72331..852cb72331 100644 --- a/arch/arm/lib/div0.c +++ b/arch/arm/lib32/div0.c diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib32/findbit.S index ef4caff1ad..ef4caff1ad 100644 --- a/arch/arm/lib/findbit.S +++ b/arch/arm/lib32/findbit.S diff --git a/arch/arm/lib/io-readsb.S b/arch/arm/lib32/io-readsb.S index 963c455175..963c455175 100644 --- a/arch/arm/lib/io-readsb.S +++ b/arch/arm/lib32/io-readsb.S diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib32/io-readsl.S index 47a29744e9..47a29744e9 100644 --- a/arch/arm/lib/io-readsl.S +++ b/arch/arm/lib32/io-readsl.S diff --git a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib32/io-readsw-armv4.S index f5b34a3479..f5b34a3479 100644 --- a/arch/arm/lib/io-readsw-armv4.S +++ b/arch/arm/lib32/io-readsw-armv4.S diff --git a/arch/arm/lib/io-writesb.S b/arch/arm/lib32/io-writesb.S index 1ab8e47cb4..1ab8e47cb4 100644 --- a/arch/arm/lib/io-writesb.S +++ b/arch/arm/lib32/io-writesb.S diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib32/io-writesl.S index 8a3bcd6456..8a3bcd6456 100644 --- a/arch/arm/lib/io-writesl.S +++ b/arch/arm/lib32/io-writesl.S diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib32/io-writesw-armv4.S index 9e8308dd77..9e8308dd77 100644 --- a/arch/arm/lib/io-writesw-armv4.S +++ b/arch/arm/lib32/io-writesw-armv4.S diff --git a/arch/arm/lib/io.c b/arch/arm/lib32/io.c index abfd887aac..abfd887aac 100644 --- a/arch/arm/lib/io.c +++ b/arch/arm/lib32/io.c diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib32/lib1funcs.S index bf1d0192d6..bf1d0192d6 100644 --- a/arch/arm/lib/lib1funcs.S +++ b/arch/arm/lib32/lib1funcs.S diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib32/lshrdi3.S index e77e96c7bc..e77e96c7bc 100644 --- a/arch/arm/lib/lshrdi3.S +++ b/arch/arm/lib32/lshrdi3.S diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib32/memcpy.S index 5123691ca9..5123691ca9 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib32/memcpy.S diff --git a/arch/arm/lib/memset.S b/arch/arm/lib32/memset.S index c4d2672038..c4d2672038 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib32/memset.S diff --git a/arch/arm/lib/module.c b/arch/arm/lib32/module.c index be7965d59c..be7965d59c 100644 --- a/arch/arm/lib/module.c +++ b/arch/arm/lib32/module.c diff --git a/arch/arm/lib/runtime-offset.S b/arch/arm/lib32/runtime-offset.S index f10c4c8469..f10c4c8469 100644 --- a/arch/arm/lib/runtime-offset.S +++ b/arch/arm/lib32/runtime-offset.S diff --git a/arch/arm/lib/semihosting-trap.S b/arch/arm/lib32/semihosting-trap.S index 9e40ebfe21..9e40ebfe21 100644 --- a/arch/arm/lib/semihosting-trap.S +++ b/arch/arm/lib32/semihosting-trap.S diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib32/semihosting.c index a7351961dc..a7351961dc 100644 --- a/arch/arm/lib/semihosting.c +++ b/arch/arm/lib32/semihosting.c diff --git a/arch/arm/lib/unwind.c b/arch/arm/lib32/unwind.c index c3dca5b61d..c3dca5b61d 100644 --- a/arch/arm/lib/unwind.c +++ b/arch/arm/lib32/unwind.c diff --git a/arch/arm/lib64/Makefile b/arch/arm/lib64/Makefile new file mode 100644 index 0000000000..87e26f6afa --- /dev/null +++ b/arch/arm/lib64/Makefile @@ -0,0 +1,9 @@ +obj-$(CONFIG_ARM_LINUX) += armlinux.o +obj-y += div0.o +obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o +obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o +extra-y += barebox.lds + +pbl-y += lib1funcs.o +pbl-y += ashldi3.o +pbl-y += div0.o diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c new file mode 100644 index 0000000000..020e6d70ff --- /dev/null +++ b/arch/arm/lib64/armlinux.c @@ -0,0 +1,50 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * This program 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 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. + */ + +#include <boot.h> +#include <common.h> +#include <command.h> +#include <driver.h> +#include <environment.h> +#include <image.h> +#include <init.h> +#include <fs.h> +#include <linux/list.h> +#include <xfuncs.h> +#include <malloc.h> +#include <fcntl.h> +#include <errno.h> +#include <memory.h> +#include <of.h> +#include <magicvar.h> + +#include <asm/byteorder.h> +#include <asm/setup.h> +#include <asm/barebox-arm.h> +#include <asm/armlinux.h> +#include <asm/system.h> + +void start_linux(void *adr, int swap, unsigned long initrd_address, + unsigned long initrd_size, void *oftree) +{ + void (*kernel)(void *dtb) = adr; + + shutdown_barebox(); + + kernel(oftree); +} diff --git a/arch/arm/lib64/barebox.lds.S b/arch/arm/lib64/barebox.lds.S new file mode 100644 index 0000000000..240699f1a6 --- /dev/null +++ b/arch/arm/lib64/barebox.lds.S @@ -0,0 +1,125 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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 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. + * + * + */ + +#include <asm-generic/barebox.lds.h> + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(start) +SECTIONS +{ +#ifdef CONFIG_RELOCATABLE + . = 0x0; +#else + . = TEXT_BASE; +#endif + +#ifndef CONFIG_PBL_IMAGE + PRE_IMAGE +#endif + . = ALIGN(4); + .text : + { + _stext = .; + _text = .; + *(.text_entry*) + __bare_init_start = .; + *(.text_bare_init*) + __bare_init_end = .; + __exceptions_start = .; + KEEP(*(.text_exceptions*)) + __exceptions_stop = .; + *(.text*) + } + BAREBOX_BARE_INIT_SIZE + + . = ALIGN(4); + .rodata : { *(.rodata*) } + +#ifdef CONFIG_ARM_UNWIND + /* + * Stack unwinding tables + */ + . = ALIGN(8); + .ARM.unwind_idx : { + __start_unwind_idx = .; + *(.ARM.exidx*) + __stop_unwind_idx = .; + } + .ARM.unwind_tab : { + __start_unwind_tab = .; + *(.ARM.extab*) + __stop_unwind_tab = .; + } +#endif + _etext = .; /* End of text and rodata section */ + _sdata = .; + + . = ALIGN(4); + .data : { *(.data*) } + + .barebox_imd : { BAREBOX_IMD } + + . = .; + __barebox_cmd_start = .; + .barebox_cmd : { BAREBOX_CMDS } + __barebox_cmd_end = .; + + __barebox_magicvar_start = .; + .barebox_magicvar : { BAREBOX_MAGICVARS } + __barebox_magicvar_end = .; + + __barebox_initcalls_start = .; + .barebox_initcalls : { INITCALLS } + __barebox_initcalls_end = .; + + __barebox_exitcalls_start = .; + .barebox_exitcalls : { EXITCALLS } + __barebox_exitcalls_end = .; + + __usymtab_start = .; + __usymtab : { BAREBOX_SYMS } + __usymtab_end = .; + + .oftables : { BAREBOX_CLK_TABLE() } + + .dtb : { BAREBOX_DTB() } + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + __dynsym_end = .; + } + + _edata = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss*) } + __bss_stop = .; + _end = .; + _barebox_image_size = __bss_start - TEXT_BASE; +} diff --git a/arch/arm/lib64/copy_template.S b/arch/arm/lib64/copy_template.S new file mode 100644 index 0000000000..cc9a84260d --- /dev/null +++ b/arch/arm/lib64/copy_template.S @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2013 ARM Ltd. + * Copyright (C) 2013 Linaro. + * + * This code is based on glibc cortex strings work originally authored by Linaro + * and re-licensed under GPLv2 for the Linux kernel. The original code can + * be found @ + * + * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/ + * files/head:/src/aarch64/ + * + * 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/>. + */ + + +/* + * Copy a buffer from src to dest (alignment handled by the hardware) + * + * Parameters: + * x0 - dest + * x1 - src + * x2 - n + * Returns: + * x0 - dest + */ +dstin .req x0 +src .req x1 +count .req x2 +tmp1 .req x3 +tmp1w .req w3 +tmp2 .req x4 +tmp2w .req w4 +dst .req x6 + +A_l .req x7 +A_h .req x8 +B_l .req x9 +B_h .req x10 +C_l .req x11 +C_h .req x12 +D_l .req x13 +D_h .req x14 + + mov dst, dstin + cmp count, #16 + /*When memory length is less than 16, the accessed are not aligned.*/ + b.lo .Ltiny15 + + neg tmp2, src + ands tmp2, tmp2, #15/* Bytes to reach alignment. */ + b.eq .LSrcAligned + sub count, count, tmp2 + /* + * Copy the leading memory data from src to dst in an increasing + * address order.By this way,the risk of overwritting the source + * memory data is eliminated when the distance between src and + * dst is less than 16. The memory accesses here are alignment. + */ + tbz tmp2, #0, 1f + ldrb1 tmp1w, src, #1 + strb1 tmp1w, dst, #1 +1: + tbz tmp2, #1, 2f + ldrh1 tmp1w, src, #2 + strh1 tmp1w, dst, #2 +2: + tbz tmp2, #2, 3f + ldr1 tmp1w, src, #4 + str1 tmp1w, dst, #4 +3: + tbz tmp2, #3, .LSrcAligned + ldr1 tmp1, src, #8 + str1 tmp1, dst, #8 + +.LSrcAligned: + cmp count, #64 + b.ge .Lcpy_over64 + /* + * Deal with small copies quickly by dropping straight into the + * exit block. + */ +.Ltail63: + /* + * Copy up to 48 bytes of data. At this point we only need the + * bottom 6 bits of count to be accurate. + */ + ands tmp1, count, #0x30 + b.eq .Ltiny15 + cmp tmp1w, #0x20 + b.eq 1f + b.lt 2f + ldp1 A_l, A_h, src, #16 + stp1 A_l, A_h, dst, #16 +1: + ldp1 A_l, A_h, src, #16 + stp1 A_l, A_h, dst, #16 +2: + ldp1 A_l, A_h, src, #16 + stp1 A_l, A_h, dst, #16 +.Ltiny15: + /* + * Prefer to break one ldp/stp into several load/store to access + * memory in an increasing address order,rather than to load/store 16 + * bytes from (src-16) to (dst-16) and to backward the src to aligned + * address,which way is used in original cortex memcpy. If keeping + * the original memcpy process here, memmove need to satisfy the + * precondition that src address is at least 16 bytes bigger than dst + * address,otherwise some source data will be overwritten when memove + * call memcpy directly. To make memmove simpler and decouple the + * memcpy's dependency on memmove, withdrew the original process. + */ + tbz count, #3, 1f + ldr1 tmp1, src, #8 + str1 tmp1, dst, #8 +1: + tbz count, #2, 2f + ldr1 tmp1w, src, #4 + str1 tmp1w, dst, #4 +2: + tbz count, #1, 3f + ldrh1 tmp1w, src, #2 + strh1 tmp1w, dst, #2 +3: + tbz count, #0, .Lexitfunc + ldrb1 tmp1w, src, #1 + strb1 tmp1w, dst, #1 + + b .Lexitfunc + +.Lcpy_over64: + subs count, count, #128 + b.ge .Lcpy_body_large + /* + * Less than 128 bytes to copy, so handle 64 here and then jump + * to the tail. + */ + ldp1 A_l, A_h, src, #16 + stp1 A_l, A_h, dst, #16 + ldp1 B_l, B_h, src, #16 + ldp1 C_l, C_h, src, #16 + stp1 B_l, B_h, dst, #16 + stp1 C_l, C_h, dst, #16 + ldp1 D_l, D_h, src, #16 + stp1 D_l, D_h, dst, #16 + + tst count, #0x3f + b.ne .Ltail63 + b .Lexitfunc + + /* + * Critical loop. Start at a new cache line boundary. Assuming + * 64 bytes per line this ensures the entire loop is in one line. + */ +.Lcpy_body_large: + /* pre-get 64 bytes data. */ + ldp1 A_l, A_h, src, #16 + ldp1 B_l, B_h, src, #16 + ldp1 C_l, C_h, src, #16 + ldp1 D_l, D_h, src, #16 +1: + /* + * interlace the load of next 64 bytes data block with store of the last + * loaded 64 bytes data. + */ + stp1 A_l, A_h, dst, #16 + ldp1 A_l, A_h, src, #16 + stp1 B_l, B_h, dst, #16 + ldp1 B_l, B_h, src, #16 + stp1 C_l, C_h, dst, #16 + ldp1 C_l, C_h, src, #16 + stp1 D_l, D_h, dst, #16 + ldp1 D_l, D_h, src, #16 + subs count, count, #64 + b.ge 1b + stp1 A_l, A_h, dst, #16 + stp1 B_l, B_h, dst, #16 + stp1 C_l, C_h, dst, #16 + stp1 D_l, D_h, dst, #16 + + tst count, #0x3f + b.ne .Ltail63 +.Lexitfunc: diff --git a/arch/arm/lib64/div0.c b/arch/arm/lib64/div0.c new file mode 100644 index 0000000000..852cb72331 --- /dev/null +++ b/arch/arm/lib64/div0.c @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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 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. + * + */ +#include <common.h> + +extern void __div0(void); + +/* Replacement (=dummy) for GNU/Linux division-by zero handler */ +void __div0 (void) +{ + panic("division by zero\n"); +} diff --git a/arch/arm/lib64/memcpy.S b/arch/arm/lib64/memcpy.S new file mode 100644 index 0000000000..cfed3191c5 --- /dev/null +++ b/arch/arm/lib64/memcpy.S @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013 ARM Ltd. + * Copyright (C) 2013 Linaro. + * + * This code is based on glibc cortex strings work originally authored by Linaro + * and re-licensed under GPLv2 for the Linux kernel. The original code can + * be found @ + * + * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/ + * files/head:/src/aarch64/ + * + * 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 <linux/linkage.h> +#include <asm/assembler.h> + +/* + * Copy a buffer from src to dest (alignment handled by the hardware) + * + * Parameters: + * x0 - dest + * x1 - src + * x2 - n + * Returns: + * x0 - dest + */ + .macro ldrb1 ptr, regB, val + ldrb \ptr, [\regB], \val + .endm + + .macro strb1 ptr, regB, val + strb \ptr, [\regB], \val + .endm + + .macro ldrh1 ptr, regB, val + ldrh \ptr, [\regB], \val + .endm + + .macro strh1 ptr, regB, val + strh \ptr, [\regB], \val + .endm + + .macro ldr1 ptr, regB, val + ldr \ptr, [\regB], \val + .endm + + .macro str1 ptr, regB, val + str \ptr, [\regB], \val + .endm + + .macro ldp1 ptr, regB, regC, val + ldp \ptr, \regB, [\regC], \val + .endm + + .macro stp1 ptr, regB, regC, val + stp \ptr, \regB, [\regC], \val + .endm + + .weak memcpy +ENTRY(memcpy) +#include "copy_template.S" + ret +ENDPROC(memcpy) diff --git a/arch/arm/lib64/memset.S b/arch/arm/lib64/memset.S new file mode 100644 index 0000000000..380a54097e --- /dev/null +++ b/arch/arm/lib64/memset.S @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2013 ARM Ltd. + * Copyright (C) 2013 Linaro. + * + * This code is based on glibc cortex strings work originally authored by Linaro + * and re-licensed under GPLv2 for the Linux kernel. The original code can + * be found @ + * + * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/ + * files/head:/src/aarch64/ + * + * 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 <linux/linkage.h> +#include <asm/assembler.h> + +/* + * Fill in the buffer with character c (alignment handled by the hardware) + * + * Parameters: + * x0 - buf + * x1 - c + * x2 - n + * Returns: + * x0 - buf + */ + +dstin .req x0 +val .req w1 +count .req x2 +tmp1 .req x3 +tmp1w .req w3 +tmp2 .req x4 +tmp2w .req w4 +zva_len_x .req x5 +zva_len .req w5 +zva_bits_x .req x6 + +A_l .req x7 +A_lw .req w7 +dst .req x8 +tmp3w .req w9 +tmp3 .req x9 + + .weak memset +ENTRY(memset) + mov dst, dstin /* Preserve return value. */ + and A_lw, val, #255 + orr A_lw, A_lw, A_lw, lsl #8 + orr A_lw, A_lw, A_lw, lsl #16 + orr A_l, A_l, A_l, lsl #32 + + cmp count, #15 + b.hi .Lover16_proc + /*All store maybe are non-aligned..*/ + tbz count, #3, 1f + str A_l, [dst], #8 +1: + tbz count, #2, 2f + str A_lw, [dst], #4 +2: + tbz count, #1, 3f + strh A_lw, [dst], #2 +3: + tbz count, #0, 4f + strb A_lw, [dst] +4: + ret + +.Lover16_proc: + /*Whether the start address is aligned with 16.*/ + neg tmp2, dst + ands tmp2, tmp2, #15 + b.eq .Laligned +/* +* The count is not less than 16, we can use stp to store the start 16 bytes, +* then adjust the dst aligned with 16.This process will make the current +* memory address at alignment boundary. +*/ + stp A_l, A_l, [dst] /*non-aligned store..*/ + /*make the dst aligned..*/ + sub count, count, tmp2 + add dst, dst, tmp2 + +.Laligned: + cbz A_l, .Lzero_mem + +.Ltail_maybe_long: + cmp count, #64 + b.ge .Lnot_short +.Ltail63: + ands tmp1, count, #0x30 + b.eq 3f + cmp tmp1w, #0x20 + b.eq 1f + b.lt 2f + stp A_l, A_l, [dst], #16 +1: + stp A_l, A_l, [dst], #16 +2: + stp A_l, A_l, [dst], #16 +/* +* The last store length is less than 16,use stp to write last 16 bytes. +* It will lead some bytes written twice and the access is non-aligned. +*/ +3: + ands count, count, #15 + cbz count, 4f + add dst, dst, count + stp A_l, A_l, [dst, #-16] /* Repeat some/all of last store. */ +4: + ret + + /* + * Critical loop. Start at a new cache line boundary. Assuming + * 64 bytes per line, this ensures the entire loop is in one line. + */ +.Lnot_short: + sub dst, dst, #16/* Pre-bias. */ + sub count, count, #64 +1: + stp A_l, A_l, [dst, #16] + stp A_l, A_l, [dst, #32] + stp A_l, A_l, [dst, #48] + stp A_l, A_l, [dst, #64]! + subs count, count, #64 + b.ge 1b + tst count, #0x3f + add dst, dst, #16 + b.ne .Ltail63 +.Lexitfunc: + ret + + /* + * For zeroing memory, check to see if we can use the ZVA feature to + * zero entire 'cache' lines. + */ +.Lzero_mem: + cmp count, #63 + b.le .Ltail63 + /* + * For zeroing small amounts of memory, it's not worth setting up + * the line-clear code. + */ + cmp count, #128 + b.lt .Lnot_short /*count is at least 128 bytes*/ + + mrs tmp1, dczid_el0 + tbnz tmp1, #4, .Lnot_short + mov tmp3w, #4 + and zva_len, tmp1w, #15 /* Safety: other bits reserved. */ + lsl zva_len, tmp3w, zva_len + + ands tmp3w, zva_len, #63 + /* + * ensure the zva_len is not less than 64. + * It is not meaningful to use ZVA if the block size is less than 64. + */ + b.ne .Lnot_short +.Lzero_by_line: + /* + * Compute how far we need to go to become suitably aligned. We're + * already at quad-word alignment. + */ + cmp count, zva_len_x + b.lt .Lnot_short /* Not enough to reach alignment. */ + sub zva_bits_x, zva_len_x, #1 + neg tmp2, dst + ands tmp2, tmp2, zva_bits_x + b.eq 2f /* Already aligned. */ + /* Not aligned, check that there's enough to copy after alignment.*/ + sub tmp1, count, tmp2 + /* + * grantee the remain length to be ZVA is bigger than 64, + * avoid to make the 2f's process over mem range.*/ + cmp tmp1, #64 + ccmp tmp1, zva_len_x, #8, ge /* NZCV=0b1000 */ + b.lt .Lnot_short + /* + * We know that there's at least 64 bytes to zero and that it's safe + * to overrun by 64 bytes. + */ + mov count, tmp1 +1: + stp A_l, A_l, [dst] + stp A_l, A_l, [dst, #16] + stp A_l, A_l, [dst, #32] + subs tmp2, tmp2, #64 + stp A_l, A_l, [dst, #48] + add dst, dst, #64 + b.ge 1b + /* We've overrun a bit, so adjust dst downwards.*/ + add dst, dst, tmp2 +2: + sub count, count, zva_len_x +3: + dc zva, dst + add dst, dst, zva_len_x + subs count, count, zva_len_x + b.ge 3b + ands count, count, zva_bits_x + b.ne .Ltail_maybe_long + ret +ENDPROC(memset) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 5b648acbbc..80f8fd80ae 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -33,6 +33,7 @@ config ARCH_TEXT_BASE default 0x17800000 if MACH_SABRESD default 0x4fc00000 if MACH_REALQ7 default 0x4fc00000 if MACH_GK802 + default 0x87f00000 if MACH_KINDLE3 default 0x2fc00000 if MACH_TQMA6X default 0x4fc00000 if MACH_DFI_FS700_M60 default 0x4fc00000 if MACH_UDOO @@ -453,6 +454,14 @@ config MACH_GUF_CUPID Say Y here if you are using the Garz+Fricke Neso board equipped with a Freescale i.MX35 Processor +config MACH_KINDLE3 + bool "Amazon Kindle3" + select ARCH_IMX35 + select ARCH_HAS_L2X0 + select HAVE_DEFAULT_ENVIRONMENT_NEW + help + Say Y here if you are using the Amazon Model No. D00901 Kindle + # ---------------------------------------------------------- comment "i.MX51 Boards" diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c index 6785da0dee..f992134f7e 100644 --- a/arch/arm/mach-imx/clk-pllv1.c +++ b/arch/arm/mach-imx/clk-pllv1.c @@ -61,8 +61,9 @@ static unsigned long clk_pllv1_recalc_rate(struct clk *clk, do_div(ll, mfd + 1); if (mfn < 0) - ll = -ll; - ll = (freq * mfi) + ll; + ll = (freq * mfi) - ll; + else + ll = (freq * mfi) + ll; return ll; } diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c index a2b016f346..5ba07fa5e6 100644 --- a/arch/arm/mach-imx/clk-pllv2.c +++ b/arch/arm/mach-imx/clk-pllv2.c @@ -113,8 +113,9 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, temp = (u64) ref_clk * mfn_abs; do_div(temp, mfd + 1); if (mfn < 0) - temp = -temp; - temp = (ref_clk * mfi) + temp; + temp = (ref_clk * mfi) - temp; + else + temp = (ref_clk * mfi) + temp; return temp; } diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c index c3ba67e0b8..6addfed696 100644 --- a/arch/arm/mach-imx/iim.c +++ b/arch/arm/mach-imx/iim.c @@ -196,7 +196,7 @@ int imx_iim_read(unsigned int banknum, int offset, void *buf, int count) if (!imx_iim) return -ENODEV; - if (banknum > IIM_NUM_BANKS) + if (banknum >= IIM_NUM_BANKS) return -EINVAL; bank = iim->bank[banknum]; diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c index 3cfeebbe93..2534d75429 100644 --- a/arch/arm/mach-imx/imx25.c +++ b/arch/arm/mach-imx/imx25.c @@ -23,14 +23,6 @@ #define MX25_BOOTROM_HAB_MAGIC 0x3c95cac6 #define MX25_DRYICE_GPR 0x3c -void imx25_setup_weimcs(size_t cs, unsigned upper, unsigned lower, - unsigned additional) -{ - writel(upper, MX25_WEIM_BASE_ADDR + (cs * 0x10) + 0x0); - writel(lower, MX25_WEIM_BASE_ADDR + (cs * 0x10) + 0x4); - writel(additional, MX25_WEIM_BASE_ADDR + (cs * 0x10) + 0x8); -} - /* IIM fuse definitions */ #define IIM_BANK0_BASE (MX25_IIM_BASE_ADDR + 0x800) #define IIM_BANK1_BASE (MX25_IIM_BASE_ADDR + 0xc00) diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h index 46fe38856f..0a4200b3f4 100644 --- a/arch/arm/mach-imx/include/mach/generic.h +++ b/arch/arm/mach-imx/include/mach/generic.h @@ -4,6 +4,7 @@ #include <linux/compiler.h> #include <linux/types.h> #include <bootsource.h> +#include <mach/imx_cpu_types.h> u64 imx_uid(void); @@ -42,16 +43,6 @@ void imx6_cpu_lowlevel_init(void); /* range e.g. GPIO_1_5 is gpio 5 under linux */ #define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr)) -#define IMX_CPU_IMX1 1 -#define IMX_CPU_IMX21 21 -#define IMX_CPU_IMX25 25 -#define IMX_CPU_IMX27 27 -#define IMX_CPU_IMX31 31 -#define IMX_CPU_IMX35 35 -#define IMX_CPU_IMX51 51 -#define IMX_CPU_IMX53 53 -#define IMX_CPU_IMX6 6 - extern unsigned int __imx_cpu_type; #ifdef CONFIG_ARCH_IMX1 diff --git a/arch/arm/mach-imx/include/mach/imx-pll.h b/arch/arm/mach-imx/include/mach/imx-pll.h index df7e73efea..0ccf41bcaa 100644 --- a/arch/arm/mach-imx/include/mach/imx-pll.h +++ b/arch/arm/mach-imx/include/mach/imx-pll.h @@ -15,4 +15,12 @@ #define IMX_PLL_MFN(x) (((x) & 0x3ff) << 0) #define IMX_PLL_BRMO (1 << 31) +/* Assuming 24MHz input clock */ +#define MPCTL_PARAM_532 ((1 << 31) | \ + IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) +#define MPCTL_PARAM_399 \ + (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) +#define PPCTL_PARAM_300 \ + (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) + #endif /* __INCLUDE_ASM_ARCH_IMX_PLL_H*/ diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h index 52e209b4de..48bf64386a 100644 --- a/arch/arm/mach-imx/include/mach/imx35-regs.h +++ b/arch/arm/mach-imx/include/mach/imx35-regs.h @@ -150,11 +150,26 @@ #define MX35_CCM_CGR3 0x38 #define MX35_CCM_CGR0_CSPI1_SHIFT 10 +#define MX35_CCM_CGR0_CSPI2_SHIFT 12 +#define MX35_CCM_CGR0_EPIT1_SHIFT 20 +#define MX35_CCM_CGR0_EPIT2_SHIFT 22 +#define MX35_CCM_CGR0_ESDHC1_SHIFT 26 +#define MX35_CCM_CGR0_ESDHC2_SHIFT 28 +#define MX35_CCM_CGR0_ESDHC3_SHIFT 30 #define MX35_CCM_CGR1_FEC_SHIFT 0 +#define MX35_CCM_CGR1_GPIO1_SHIFT 2 +#define MX35_CCM_CGR1_GPIO2_SHIFT 4 +#define MX35_CCM_CGR1_GPIO3_SHIFT 6 #define MX35_CCM_CGR1_I2C1_SHIFT 10 -#define MX35_CCM_CGR1_SDHC1_SHIFT 26 +#define MX35_CCM_CGR1_I2C2_SHIFT 12 +#define MX35_CCM_CGR1_I2C3_SHIFT 14 +#define MX35_CCM_CGR1_IOMUX_SHIFT 16 +#define MX35_CCM_CGR1_KPP_SHIFT 20 +#define MX35_CCM_CGR2_UART1_SHIFT 16 #define MX35_CCM_CGR2_UART2_SHIFT 18 +#define MX35_CCM_CGR2_UART3_SHIFT 20 #define MX35_CCM_CGR2_USB_SHIFT 22 +#define MX35_CCM_CGR2_WDOG_SHIFT 24 #define MX35_CCM_RCSR_MEM_CTRL_SHIFT 25 #define MX35_CCM_RCSR_MEM_TYPE_SHIFT 23 diff --git a/arch/arm/mach-imx/include/mach/imx53-regs.h b/arch/arm/mach-imx/include/mach/imx53-regs.h index 9cd7723ce9..d45c94370d 100644 --- a/arch/arm/mach-imx/include/mach/imx53-regs.h +++ b/arch/arm/mach-imx/include/mach/imx53-regs.h @@ -1,8 +1,13 @@ #ifndef __MACH_IMX53_REGS_H #define __MACH_IMX53_REGS_H +#include <linux/sizes.h> + #define MX53_IROM_BASE_ADDR 0x0 +#define MX53_IRAM_BASE_ADDR 0xF8000000 +#define MX53_IRAM_SIZE SZ_128K + #define MX53_SATA_BASE_ADDR 0x10000000 #define MX53_IPU_BASE_ADDR 0x18000000 diff --git a/arch/arm/mach-imx/include/mach/imx_cpu_types.h b/arch/arm/mach-imx/include/mach/imx_cpu_types.h new file mode 100644 index 0000000000..781ab9fe74 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/imx_cpu_types.h @@ -0,0 +1,14 @@ +#ifndef __MACH_IMX_CPU_TYPES_H +#define __MACH_IMX_CPU_TYPES_H + +#define IMX_CPU_IMX1 1 +#define IMX_CPU_IMX21 21 +#define IMX_CPU_IMX25 25 +#define IMX_CPU_IMX27 27 +#define IMX_CPU_IMX31 31 +#define IMX_CPU_IMX35 35 +#define IMX_CPU_IMX51 51 +#define IMX_CPU_IMX53 53 +#define IMX_CPU_IMX6 6 + +#endif /* __MACH_IMX_CPU_TYPES_H */ diff --git a/arch/arm/mach-imx/include/mach/iomux-mx31.h b/arch/arm/mach-imx/include/mach/iomux-mx31.h index 258ccee034..c814c15912 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx31.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx31.h @@ -573,10 +573,7 @@ enum iomux_pins { #define MX31_PIN_CONTRAST__CONTRAST IOMUX_MODE(MX31_PIN_CONTRAST, IOMUX_CONFIG_FUNC) #define MX31_PIN_D3_SPL__D3_SPL IOMUX_MODE(MX31_PIN_D3_SPL, IOMUX_CONFIG_FUNC) #define MX31_PIN_D3_CLS__D3_CLS IOMUX_MODE(MX31_PIN_D3_CLS, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LCS0__GPI03_23 IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO) #define MX31_PIN_GPIO1_1__GPIO IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_I2C_CLK__SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_I2C_DAT__SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) #define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2) #define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2) #define MX31_PIN_CSPI2_SS2__I2C3_SDA IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_ALT1) @@ -640,37 +637,6 @@ enum iomux_pins { #define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO) #define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) #define MX31_PIN_I2C_CLK__I2C1_SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_ATA_CS0__GPIO3_26 IOMUX_MODE(MX31_PIN_ATA_CS0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_ATA_CS1__GPIO3_27 IOMUX_MODE(MX31_PIN_ATA_CS1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_PC_PWRON__SD2_DATA3 IOMUX_MODE(MX31_PIN_PC_PWRON, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_VS1__SD2_DATA2 IOMUX_MODE(MX31_PIN_PC_VS1, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_READY__SD2_DATA1 IOMUX_MODE(MX31_PIN_PC_READY, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_WAIT_B__SD2_DATA0 IOMUX_MODE(MX31_PIN_PC_WAIT_B, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_CD2_B__SD2_CLK IOMUX_MODE(MX31_PIN_PC_CD2_B, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_CD1_B__SD2_CMD IOMUX_MODE(MX31_PIN_PC_CD1_B, IOMUX_CONFIG_ALT1) -#define MX31_PIN_ATA_DIOR__GPIO3_28 IOMUX_MODE(MX31_PIN_ATA_DIOR, IOMUX_CONFIG_GPIO) -#define MX31_PIN_ATA_DIOW__GPIO3_29 IOMUX_MODE(MX31_PIN_ATA_DIOW, IOMUX_CONFIG_GPIO) -#define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D7__CSI_D7 IOMUX_MODE(MX31_PIN_CSI_D7, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D8__CSI_D8 IOMUX_MODE(MX31_PIN_CSI_D8, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D9__CSI_D9 IOMUX_MODE(MX31_PIN_CSI_D9, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D10__CSI_D10 IOMUX_MODE(MX31_PIN_CSI_D10, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D11__CSI_D11 IOMUX_MODE(MX31_PIN_CSI_D11, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D12__CSI_D12 IOMUX_MODE(MX31_PIN_CSI_D12, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D13__CSI_D13 IOMUX_MODE(MX31_PIN_CSI_D13, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D14__CSI_D14 IOMUX_MODE(MX31_PIN_CSI_D14, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D15__CSI_D15 IOMUX_MODE(MX31_PIN_CSI_D15, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_HSYNC__CSI_HSYNC IOMUX_MODE(MX31_PIN_CSI_HSYNC, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_MCLK__CSI_MCLK IOMUX_MODE(MX31_PIN_CSI_MCLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_PIXCLK__CSI_PIXCLK IOMUX_MODE(MX31_PIN_CSI_PIXCLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_VSYNC__CSI_VSYNC IOMUX_MODE(MX31_PIN_CSI_VSYNC, IOMUX_CONFIG_FUNC) -#define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO) #define MX31_PIN_GPIO1_0__GPIO1_0 IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO) #define MX31_PIN_SVEN0__GPIO2_0 IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO) #define MX31_PIN_STX0__GPIO2_1 IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO) diff --git a/arch/arm/mach-imx/include/mach/weim.h b/arch/arm/mach-imx/include/mach/weim.h index 3fbbb6ba8e..22d9c76d61 100644 --- a/arch/arm/mach-imx/include/mach/weim.h +++ b/arch/arm/mach-imx/include/mach/weim.h @@ -12,9 +12,6 @@ void imx31_setup_weimcs(size_t cs, unsigned upper, unsigned lower, void imx35_setup_weimcs(size_t cs, unsigned upper, unsigned lower, unsigned additional); -void imx25_setup_weimcs(size_t cs, unsigned upper, unsigned lower, - unsigned additional); - void imx1_setup_eimcs(size_t cs, unsigned upper, unsigned lower); void imx21_setup_eimcs(size_t cs, unsigned upper, unsigned lower); diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig new file mode 100644 index 0000000000..d30bae4c6f --- /dev/null +++ b/arch/arm/mach-qemu/Kconfig @@ -0,0 +1,18 @@ +if ARCH_QEMU + +config ARCH_TEXT_BASE + hex + default 0x40000000 + +choice + prompt "ARM Board type" + +config MACH_QEMU_VIRT64 + bool "QEMU arm64 virt machine" + select CPU_V8 + select SYS_SUPPORTS_64BIT_KERNEL + select ARM_AMBA + select HAVE_CONFIGURABLE_MEMORY_LAYOUT + +endchoice +endif diff --git a/arch/arm/mach-qemu/Makefile b/arch/arm/mach-qemu/Makefile new file mode 100644 index 0000000000..ece277ce0e --- /dev/null +++ b/arch/arm/mach-qemu/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MACH_QEMU_VIRT64) += virt_devices.o diff --git a/arch/arm/mach-qemu/include/mach/debug_ll.h b/arch/arm/mach-qemu/include/mach/debug_ll.h new file mode 100644 index 0000000000..89b06923ad --- /dev/null +++ b/arch/arm/mach-qemu/include/mach/debug_ll.h @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Jean-Christophe PLAGNIOL-VILLARD <plagniol@jcrosoft.com> + * + * GPLv2 only + */ + +#ifndef __MACH_DEBUG_LL_H__ +#define __MACH_DEBUG_LL_H__ + +#include <linux/amba/serial.h> +#include <io.h> + +#define DEBUG_LL_PHYS_BASE 0x10000000 +#define DEBUG_LL_PHYS_BASE_RS1 0x1c000000 + +#ifdef MP +#define DEBUG_LL_UART_ADDR DEBUG_LL_PHYS_BASE +#else +#define DEBUG_LL_UART_ADDR DEBUG_LL_PHYS_BASE_RS1 +#endif + +#include <asm/debug_ll_pl011.h> + +#endif diff --git a/arch/arm/mach-qemu/include/mach/devices.h b/arch/arm/mach-qemu/include/mach/devices.h new file mode 100644 index 0000000000..9872c61b49 --- /dev/null +++ b/arch/arm/mach-qemu/include/mach/devices.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2016 Raphaël Poggi <poggi.raph@gmail.com> + * + * GPLv2 only + */ + +#ifndef __ASM_ARCH_DEVICES_H__ +#define __ASM_ARCH_DEVICES_H__ + +void virt_add_ddram(u32 size); +void virt_register_uart(unsigned id); + +#endif /* __ASM_ARCH_DEVICES_H__ */ diff --git a/arch/arm/mach-qemu/virt_devices.c b/arch/arm/mach-qemu/virt_devices.c new file mode 100644 index 0000000000..999f463125 --- /dev/null +++ b/arch/arm/mach-qemu/virt_devices.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 Raphaël Poggi <poggi.raph@gmail.com> + * + * GPLv2 only + */ + +#include <common.h> +#include <linux/amba/bus.h> +#include <asm/memory.h> +#include <mach/devices.h> +#include <linux/ioport.h> + +void virt_add_ddram(u32 size) +{ + arm_add_mem_device("ram0", 0x40000000, size); +} + +void virt_register_uart(unsigned id) +{ + resource_size_t start; + + switch (id) { + case 0: + start = 0x09000000; + break; + default: + return; + } + amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0); +} diff --git a/arch/mips/boards/black-swift/include/board/board_pbl_start.h b/arch/mips/boards/black-swift/include/board/board_pbl_start.h index ee21a85ac9..4c2ab2ef0f 100644 --- a/arch/mips/boards/black-swift/include/board/board_pbl_start.h +++ b/arch/mips/boards/black-swift/include/board/board_pbl_start.h @@ -26,6 +26,8 @@ mips_barebox_10h + pbl_ar9331_wmac_enable + hornet_mips24k_cp0_setup pbl_blt 0xbf000000 skip_pll_ram_config t8 diff --git a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h index ef0d36dc38..3a7b560a05 100644 --- a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h +++ b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h @@ -26,6 +26,8 @@ mips_barebox_10h + pbl_ar9331_wmac_enable + hornet_mips24k_cp0_setup pbl_blt 0xbf000000 skip_pll_ram_config t8 diff --git a/arch/mips/lib/csrc-r4k.c b/arch/mips/lib/csrc-r4k.c index 5c3f18ff24..6f6e18c8e8 100644 --- a/arch/mips/lib/csrc-r4k.c +++ b/arch/mips/lib/csrc-r4k.c @@ -21,6 +21,8 @@ */ #include <init.h> +#include <of.h> +#include <linux/clk.h> #include <clock.h> #include <io.h> #include <asm/mipsregs.h> @@ -37,8 +39,26 @@ static struct clocksource cs = { static int clocksource_init(void) { - cs.mult = clocksource_hz2mult(100000000, cs.shift); + unsigned int mips_hpt_frequency; + struct device_node *np; + struct clk *clk; + + /* default rate: 100 MHz */ + mips_hpt_frequency = 100000000; + + if (IS_ENABLED(CONFIG_OFTREE)) { + np = of_get_cpu_node(0, NULL); + if (np) { + clk = of_clk_get(np, 0); + if (!IS_ERR(clk)) { + mips_hpt_frequency = clk_get_rate(clk) / 2; + } + } + } + + clocks_calc_mult_shift(&cs.mult, &cs.shift, + mips_hpt_frequency, NSEC_PER_SEC, 10); return init_clock(&cs); } -core_initcall(clocksource_init); +postcore_initcall(clocksource_init); diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h index 4cbe94a487..de96c565a6 100644 --- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h +++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h @@ -31,11 +31,25 @@ #define AR71XX_PLL_SIZE 0x100 #define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) #define AR71XX_RESET_SIZE 0x100 +#define AR71XX_RTC_BASE (AR71XX_APB_BASE + 0x00107000) +#define AR71XX_RTC_SIZE 0x100 #define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) #define AR933X_UART_SIZE 0x14 /* + * RTC block + */ +#define AR933X_RTC_REG_RESET 0x40 +#define AR933X_RTC_REG_STATUS 0x44 +#define AR933X_RTC_REG_DERIVED 0x48 +#define AR933X_RTC_REG_FORCE_WAKE 0x4c +#define AR933X_RTC_REG_INT_CAUSE 0x50 +#define AR933X_RTC_REG_CAUSE_CLR 0x50 +#define AR933X_RTC_REG_INT_ENABLE 0x54 +#define AR933X_RTC_REG_INT_MASKE 0x58 + +/* * DDR_CTRL block */ #define AR933X_DDR_CONFIG 0x00 diff --git a/arch/mips/mach-ath79/include/mach/pbl_macros.h b/arch/mips/mach-ath79/include/mach/pbl_macros.h index 8f4d09aec4..680fcbb867 100644 --- a/arch/mips/mach-ath79/include/mach/pbl_macros.h +++ b/arch/mips/mach-ath79/include/mach/pbl_macros.h @@ -274,4 +274,67 @@ normal_path: .set pop .endm +.macro pbl_ar9331_wmac_enable + .set push + .set noreorder + + /* These three WLAN_RESET will avoid original issue */ + li t3, 0x03 +1: + li t0, CKSEG1ADDR(AR71XX_RESET_BASE) + lw t1, AR933X_RESET_REG_RESET_MODULE(t0) + ori t1, t1, 0x0800 + sw t1, AR933X_RESET_REG_RESET_MODULE(t0) + nop + lw t1, AR933X_RESET_REG_RESET_MODULE(t0) + li t2, 0xfffff7ff + and t1, t1, t2 + sw t1, AR933X_RESET_REG_RESET_MODULE(t0) + nop + addi t3, t3, -1 + bnez t3, 1b + nop + + li t2, 0x20 +2: + beqz t2, 1b + nop + addi t2, t2, -1 + lw t5, AR933X_RESET_REG_BOOTSTRAP(t0) + andi t1, t5, 0x10 + bnez t1, 2b + nop + + li t1, 0x02110E + sw t1, AR933X_RESET_REG_BOOTSTRAP(t0) + nop + + /* RTC Force Wake */ + li t0, CKSEG1ADDR(AR71XX_RTC_BASE) + li t1, 0x03 + sw t1, AR933X_RTC_REG_FORCE_WAKE(t0) + nop + nop + + /* RTC Reset */ + li t1, 0x00 + sw t1, AR933X_RTC_REG_RESET(t0) + nop + nop + + li t1, 0x01 + sw t1, AR933X_RTC_REG_RESET(t0) + nop + nop + + /* Wait for RTC in on state */ +1: + lw t1, AR933X_RTC_REG_STATUS(t0) + andi t1, t1, 0x02 + beqz t1, 1b + nop + + .set pop +.endm + #endif /* __ASM_MACH_ATH79_PBL_MACROS_H */ |