diff options
79 files changed, 1054 insertions, 437 deletions
diff --git a/arch/arm/cpu/armv7/uniphier/Kconfig b/arch/arm/cpu/armv7/uniphier/Kconfig index 524b193e58..f013dc3cad 100644 --- a/arch/arm/cpu/armv7/uniphier/Kconfig +++ b/arch/arm/cpu/armv7/uniphier/Kconfig @@ -23,4 +23,13 @@ config MACH_PH1_SLD8 endchoice +config CMD_PINMON + bool "Enable boot mode pins monitor command" + depends on !SPL_BUILD + default y + help + The command "pinmon" shows the state of the boot mode pins. + The boot mode pins are latched when the system reset is deasserted + and determine which device the system should load a boot image from. + endmenu diff --git a/arch/arm/cpu/armv7/uniphier/Makefile b/arch/arm/cpu/armv7/uniphier/Makefile index 7cedddaadc..dd57469d9c 100644 --- a/arch/arm/cpu/armv7/uniphier/Makefile +++ b/arch/arm/cpu/armv7/uniphier/Makefile @@ -12,7 +12,7 @@ obj-y += dram_init.o obj-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o obj-$(CONFIG_UNIPHIER_SMP) += smp.o -obj-$(if $(CONFIG_SPL_BUILD),,y) += cmd_pinmon.o +obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o obj-y += board_common.o obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += support_card.o diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index ba717146f5..78aceef17b 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -29,6 +29,8 @@ #define EXYNOS4_MIU_BASE 0x10600000 #define EXYNOS4_ACE_SFR_BASE 0x10830000 #define EXYNOS4_GPIO_PART2_BASE 0x11000000 +#define EXYNOS4_GPIO_PART2_0 0x11000000 /* GPJ0 */ +#define EXYNOS4_GPIO_PART2_1 0x11000c00 /* GPX0 */ #define EXYNOS4_GPIO_PART1_BASE 0x11400000 #define EXYNOS4_FIMD_BASE 0x11C00000 #define EXYNOS4_MIPI_DSIM_BASE 0x11C80000 @@ -70,7 +72,14 @@ #define EXYNOS4X12_GPIO_PART4_BASE 0x106E0000 #define EXYNOS4X12_ACE_SFR_BASE 0x10830000 #define EXYNOS4X12_GPIO_PART2_BASE 0x11000000 +#define EXYNOS4X12_GPIO_PART2_0 0x11000000 +#define EXYNOS4X12_GPIO_PART2_1 0x11000040 /* GPK0 */ +#define EXYNOS4X12_GPIO_PART2_2 0x11000260 /* GPM0 */ +#define EXYNOS4X12_GPIO_PART2_3 0x11000c00 /* GPX0 */ #define EXYNOS4X12_GPIO_PART1_BASE 0x11400000 +#define EXYNOS4X12_GPIO_PART1_0 0x11400000 /* GPA0 */ +#define EXYNOS4X12_GPIO_PART1_1 0x11400180 /* GPF0 */ +#define EXYNOS4X12_GPIO_PART1_2 0x11400240 /* GPJ0 */ #define EXYNOS4X12_FIMD_BASE 0x11C00000 #define EXYNOS4X12_MIPI_DSIM_BASE 0x11C80000 #define EXYNOS4X12_USBOTG_BASE 0x12480000 diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h index ad2ece64f4..02287decc2 100644 --- a/arch/arm/include/asm/arch-exynos/gpio.h +++ b/arch/arm/include/asm/arch-exynos/gpio.h @@ -284,7 +284,10 @@ enum exynos4_gpio_pin { EXYNOS4_GPIO_Y65, EXYNOS4_GPIO_Y66, EXYNOS4_GPIO_Y67, - EXYNOS4_GPIO_X00, /* 256 0x100 */ + + /* GPIO_PART2_1 STARTS */ + EXYNOS4_GPIO_MAX_PORT_PART_2_0, /* 256 0x100 */ + EXYNOS4_GPIO_X00 = EXYNOS4_GPIO_MAX_PORT_PART_2_0, EXYNOS4_GPIO_X01, EXYNOS4_GPIO_X02, EXYNOS4_GPIO_X03, @@ -318,8 +321,8 @@ enum exynos4_gpio_pin { EXYNOS4_GPIO_X37, /* GPIO_PART3_STARTS */ - EXYNOS4_GPIO_MAX_PORT_PART_2, /* 288 0x120 */ - EXYNOS4_GPIO_Z0 = EXYNOS4_GPIO_MAX_PORT_PART_2, + EXYNOS4_GPIO_MAX_PORT_PART_2_1, /* 288 0x120 */ + EXYNOS4_GPIO_Z0 = EXYNOS4_GPIO_MAX_PORT_PART_2_1, EXYNOS4_GPIO_Z1, EXYNOS4_GPIO_Z2, EXYNOS4_GPIO_Z3, @@ -332,7 +335,7 @@ enum exynos4_gpio_pin { }; enum exynos4X12_gpio_pin { - /* GPIO_PART1_STARTS */ + /* EXYNOS4X12_GPIO_PART1_0 starts here */ EXYNOS4X12_GPIO_A00, /* 0 */ EXYNOS4X12_GPIO_A01, EXYNOS4X12_GPIO_A02, @@ -389,7 +392,9 @@ enum exynos4X12_gpio_pin { EXYNOS4X12_GPIO_D15, EXYNOS4X12_GPIO_D16, EXYNOS4X12_GPIO_D17, - EXYNOS4X12_GPIO_F00, /* 56 0x38 */ + EXYNOS4X12_GPIO_MAX_PORT_PART_1_0, /* 56 0x38 */ + /* EXYNOS4X12_GPIO_PART1_1 starts here */ + EXYNOS4X12_GPIO_F00 = EXYNOS4X12_GPIO_MAX_PORT_PART_1_0, EXYNOS4X12_GPIO_F01, EXYNOS4X12_GPIO_F02, EXYNOS4X12_GPIO_F03, @@ -421,7 +426,9 @@ enum exynos4X12_gpio_pin { EXYNOS4X12_GPIO_F35, EXYNOS4X12_GPIO_F36, EXYNOS4X12_GPIO_F37, - EXYNOS4X12_GPIO_J00, /* 88 0x58 */ + EXYNOS4X12_GPIO_MAX_PORT_PART_1_1, /* 88 0x58 */ + /* EXYNOS4X12_GPIO_PART1_2 starts here */ + EXYNOS4X12_GPIO_J00 = EXYNOS4X12_GPIO_MAX_PORT_PART_1_1, EXYNOS4X12_GPIO_J01, EXYNOS4X12_GPIO_J02, EXYNOS4X12_GPIO_J03, @@ -438,9 +445,12 @@ enum exynos4X12_gpio_pin { EXYNOS4X12_GPIO_J16, EXYNOS4X12_GPIO_J17, - /* GPIO_PART2_STARTS */ - EXYNOS4X12_GPIO_MAX_PORT_PART_1,/* 104 0x66 */ - EXYNOS4X12_GPIO_K00 = EXYNOS4X12_GPIO_MAX_PORT_PART_1, + /** + * EXYNOS4X12_GPIO_PART2_0 is not used + * EXYNOS4X12_GPIO_PART2_1 starts here + */ + EXYNOS4X12_GPIO_MAX_PORT_PART_1_2, /* 104 0x66 */ + EXYNOS4X12_GPIO_K00 = EXYNOS4X12_GPIO_MAX_PORT_PART_1_2, EXYNOS4X12_GPIO_K01, EXYNOS4X12_GPIO_K02, EXYNOS4X12_GPIO_K03, @@ -552,7 +562,9 @@ enum exynos4X12_gpio_pin { EXYNOS4X12_GPIO_Y65, EXYNOS4X12_GPIO_Y66, EXYNOS4X12_GPIO_Y67, - EXYNOS4X12_GPIO_M00, /* 216 0xd8 */ + EXYNOS4X12_GPIO_MAX_PORT_PART_2_1, /* 216 0xd8 */ + /* EXYNOS4X12_GPIO_PART2_2 starts here */ + EXYNOS4X12_GPIO_M00 = EXYNOS4X12_GPIO_MAX_PORT_PART_2_1, EXYNOS4X12_GPIO_M01, EXYNOS4X12_GPIO_M02, EXYNOS4X12_GPIO_M03, @@ -592,7 +604,9 @@ enum exynos4X12_gpio_pin { EXYNOS4X12_GPIO_M45, EXYNOS4X12_GPIO_M46, EXYNOS4X12_GPIO_M47, - EXYNOS4X12_GPIO_X00, /* 256 0x100 */ + EXYNOS4X12_GPIO_MAX_PORT_PART_2_2, /* 256 0x100 */ + /* EXYNOS4X12_GPIO_PART2_3 starts here */ + EXYNOS4X12_GPIO_X00 = EXYNOS4X12_GPIO_MAX_PORT_PART_2_2, EXYNOS4X12_GPIO_X01, EXYNOS4X12_GPIO_X02, EXYNOS4X12_GPIO_X03, @@ -625,9 +639,9 @@ enum exynos4X12_gpio_pin { EXYNOS4X12_GPIO_X36, EXYNOS4X12_GPIO_X37, - /* GPIO_PART3_STARTS */ - EXYNOS4X12_GPIO_MAX_PORT_PART_2,/* 288 0x120 */ - EXYNOS4X12_GPIO_Z0 = EXYNOS4X12_GPIO_MAX_PORT_PART_2, + /* EXYNOS4X12_GPIO_PART3 starts here */ + EXYNOS4X12_GPIO_MAX_PORT_PART_2_3, /* 288 0x120 */ + EXYNOS4X12_GPIO_Z0 = EXYNOS4X12_GPIO_MAX_PORT_PART_2_3, EXYNOS4X12_GPIO_Z1, EXYNOS4X12_GPIO_Z2, EXYNOS4X12_GPIO_Z3, @@ -636,7 +650,7 @@ enum exynos4X12_gpio_pin { EXYNOS4X12_GPIO_Z6, EXYNOS4X12_GPIO_Z7, - /* GPIO_PART4_STARTS */ + /* EXYNOS4X12_GPIO_PART4 starts here */ EXYNOS4X12_GPIO_MAX_PORT_PART_3,/* 296 0x128 */ EXYNOS4X12_GPIO_V00 = EXYNOS4X12_GPIO_MAX_PORT_PART_3, EXYNOS4X12_GPIO_V01, @@ -1339,17 +1353,22 @@ struct gpio_info { unsigned int max_gpio; /* Maximum GPIO in this part */ }; -#define EXYNOS4_GPIO_NUM_PARTS 3 +#define EXYNOS4_GPIO_NUM_PARTS 4 static struct gpio_info exynos4_gpio_data[EXYNOS4_GPIO_NUM_PARTS] = { { EXYNOS4_GPIO_PART1_BASE, EXYNOS4_GPIO_MAX_PORT_PART_1 }, - { EXYNOS4_GPIO_PART2_BASE, EXYNOS4_GPIO_MAX_PORT_PART_2 }, + { EXYNOS4_GPIO_PART2_0, EXYNOS4_GPIO_MAX_PORT_PART_2_0 }, + { EXYNOS4_GPIO_PART2_1, EXYNOS4_GPIO_MAX_PORT_PART_2_1 }, { EXYNOS4_GPIO_PART3_BASE, EXYNOS4_GPIO_MAX_PORT }, }; -#define EXYNOS4X12_GPIO_NUM_PARTS 4 +#define EXYNOS4X12_GPIO_NUM_PARTS 8 static struct gpio_info exynos4x12_gpio_data[EXYNOS4X12_GPIO_NUM_PARTS] = { - { EXYNOS4X12_GPIO_PART1_BASE, EXYNOS4X12_GPIO_MAX_PORT_PART_1 }, - { EXYNOS4X12_GPIO_PART2_BASE, EXYNOS4X12_GPIO_MAX_PORT_PART_2 }, + { EXYNOS4X12_GPIO_PART1_0, EXYNOS4X12_GPIO_MAX_PORT_PART_1_0 }, + { EXYNOS4X12_GPIO_PART1_1, EXYNOS4X12_GPIO_MAX_PORT_PART_1_1 }, + { EXYNOS4X12_GPIO_PART1_2, EXYNOS4X12_GPIO_MAX_PORT_PART_1_2 }, + { EXYNOS4X12_GPIO_PART2_1, EXYNOS4X12_GPIO_MAX_PORT_PART_2_1 }, + { EXYNOS4X12_GPIO_PART2_2, EXYNOS4X12_GPIO_MAX_PORT_PART_2_2 }, + { EXYNOS4X12_GPIO_PART2_3, EXYNOS4X12_GPIO_MAX_PORT_PART_2_3 }, { EXYNOS4X12_GPIO_PART3_BASE, EXYNOS4X12_GPIO_MAX_PORT_PART_3 }, { EXYNOS4X12_GPIO_PART4_BASE, EXYNOS4X12_GPIO_MAX_PORT }, }; diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9b72bab56b..4991da2226 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -4,6 +4,10 @@ menu "MIPS architecture" config SYS_ARCH default "mips" +config SYS_CPU + default "mips32" if CPU_MIPS32_R1 || CPU_MIPS32_R2 + default "mips64" if CPU_MIPS64_R1 || CPU_MIPS64_R2 + config USE_PRIVATE_LIBGCC default y @@ -12,21 +16,39 @@ choice config TARGET_QEMU_MIPS bool "Support qemu-mips" + select SUPPORTS_BIG_ENDIAN + select SUPPORTS_LITTLE_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 + select SUPPORTS_CPU_MIPS64_R1 + select SUPPORTS_CPU_MIPS64_R2 config TARGET_MALTA bool "Support malta" + select SUPPORTS_BIG_ENDIAN + select SUPPORTS_LITTLE_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 config TARGET_VCT bool "Support vct" + select SUPPORTS_BIG_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 config TARGET_DBAU1X00 bool "Support dbau1x00" + select SUPPORTS_BIG_ENDIAN + select SUPPORTS_LITTLE_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 config TARGET_PB1X00 bool "Support pb1x00" + select SUPPORTS_LITTLE_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 -config TARGET_QEMU_MIPS64 - bool "Support qemu-mips64" endchoice @@ -36,4 +58,88 @@ source "board/micronas/vct/Kconfig" source "board/pb1x00/Kconfig" source "board/qemu-mips/Kconfig" +if MIPS + +choice + prompt "Endianness selection" + help + Some MIPS boards can be configured for either little or big endian + byte order. These modes require different U-Boot images. In general there + is one preferred byteorder for a particular system but some systems are + just as commonly used in the one or the other endianness. + +config SYS_BIG_ENDIAN + bool "Big endian" + depends on SUPPORTS_BIG_ENDIAN + +config SYS_LITTLE_ENDIAN + bool "Little endian" + depends on SUPPORTS_LITTLE_ENDIAN + +endchoice + +choice + prompt "CPU selection" + default CPU_MIPS32_R2 + +config CPU_MIPS32_R1 + bool "MIPS32 Release 1" + depends on SUPPORTS_CPU_MIPS32_R1 + select 32BIT + help + Choose this option to build an U-Boot for release 1 or later of the + MIPS32 architecture. + +config CPU_MIPS32_R2 + bool "MIPS32 Release 2" + depends on SUPPORTS_CPU_MIPS32_R2 + select 32BIT + help + Choose this option to build an U-Boot for release 2 or later of the + MIPS32 architecture. + +config CPU_MIPS64_R1 + bool "MIPS64 Release 1" + depends on SUPPORTS_CPU_MIPS64_R1 + select 64BIT + help + Choose this option to build a kernel for release 1 or later of the + MIPS64 architecture. + +config CPU_MIPS64_R2 + bool "MIPS64 Release 2" + depends on SUPPORTS_CPU_MIPS64_R2 + select 64BIT + help + Choose this option to build a kernel for release 2 or later of the + MIPS64 architecture. + +endchoice + +config SUPPORTS_BIG_ENDIAN + bool + +config SUPPORTS_LITTLE_ENDIAN + bool + +config SUPPORTS_CPU_MIPS32_R1 + bool + +config SUPPORTS_CPU_MIPS32_R2 + bool + +config SUPPORTS_CPU_MIPS64_R1 + bool + +config SUPPORTS_CPU_MIPS64_R2 + bool + +config 32BIT + bool + +config 64BIT + bool + +endif + endmenu diff --git a/arch/mips/config.mk b/arch/mips/config.mk index a2d07aff1b..4dc88f4d51 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -5,25 +5,41 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := mips_4KC- +ifdef CONFIG_SYS_BIG_ENDIAN +32bit-emul := elf32btsmip +64bit-emul := elf64btsmip +32bit-bfd := elf32-tradbigmips +64bit-bfd := elf64-tradbigmips +PLATFORM_CPPFLAGS += -EB +PLATFORM_LDFLAGS += -EB endif -# Handle special prefix in ELDK 4.0 toolchain -ifneq (,$(findstring 4KCle,$(CROSS_COMPILE))) -ENDIANNESS := -EL +ifdef CONFIG_SYS_LITTLE_ENDIAN +32bit-emul := elf32ltsmip +64bit-emul := elf64ltsmip +32bit-bfd := elf32-tradlittlemips +64bit-bfd := elf64-tradlittlemips +PLATFORM_CPPFLAGS += -EL +PLATFORM_LDFLAGS += -EL endif -ifdef CONFIG_SYS_LITTLE_ENDIAN -ENDIANNESS := -EL +ifdef CONFIG_32BIT +PLATFORM_CPPFLAGS += -mabi=32 +PLATFORM_LDFLAGS += -m $(32bit-emul) +OBJCOPYFLAGS += -O $(32bit-bfd) endif -ifdef CONFIG_SYS_BIG_ENDIAN -ENDIANNESS := -EB +ifdef CONFIG_64BIT +PLATFORM_CPPFLAGS += -mabi=64 +PLATFORM_LDFLAGS += -m$(64bit-emul) +OBJCOPYFLAGS += -O $(64bit-bfd) endif -# Default to EB if no endianess is configured -ENDIANNESS ?= -EB +cpuflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,-mips32 +cpuflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,-mips32r2 +cpuflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,-mips64 +cpuflags-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,-mips64r2 +PLATFORM_CPPFLAGS += $(cpuflags-y) PLATFORM_CPPFLAGS += -D__MIPS__ @@ -49,10 +65,10 @@ __HAVE_ARCH_GENERIC_BOARD := y # On the other hand, we want PIC in the U-Boot code to relocate it from ROM # to RAM. $28 is always used as gp. # -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS) +PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic PLATFORM_CPPFLAGS += -msoft-float -PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS) +PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections -pie OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .got -OBJCOPYFLAGS += -j .u_boot_list -j .rel.dyn +OBJCOPYFLAGS += -j .u_boot_list -j .rel.dyn -j .padding diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk index 332cd62c74..4257c56d59 100644 --- a/arch/mips/cpu/mips32/config.mk +++ b/arch/mips/cpu/mips32/config.mk @@ -5,19 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -# -# Default optimization level for MIPS32 -# -# Note: Toolchains with binutils prior to v2.16 -# are no longer supported by U-Boot MIPS tree! -# -PLATFORM_CPPFLAGS += -DCONFIG_MIPS32 -march=mips32r2 -PLATFORM_CPPFLAGS += -mabi=32 -DCONFIG_32BIT -ifdef CONFIG_SYS_BIG_ENDIAN -PLATFORM_LDFLAGS += -m elf32btsmip -else -PLATFORM_LDFLAGS += -m elf32ltsmip -endif - CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 \ -T $(srctree)/examples/standalone/mips.lds diff --git a/arch/mips/cpu/mips64/config.mk b/arch/mips/cpu/mips64/config.mk index c55eb7f2ee..96eb82948d 100644 --- a/arch/mips/cpu/mips64/config.mk +++ b/arch/mips/cpu/mips64/config.mk @@ -5,19 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -# -# Default optimization level for MIPS64 -# -# Note: Toolchains with binutils prior to v2.16 -# are no longer supported by U-Boot MIPS tree! -# -PLATFORM_CPPFLAGS += -DCONFIG_MIPS64 -march=mips64 -PLATFORM_CPPFLAGS += -mabi=64 -DCONFIG_64BIT -ifdef CONFIG_SYS_BIG_ENDIAN -PLATFORM_LDFLAGS += -m elf64btsmip -else -PLATFORM_LDFLAGS += -m elf64ltsmip -endif - CONFIG_STANDALONE_LOAD_ADDR ?= 0xffffffff80200000 \ -T $(srctree)/examples/standalone/mips64.lds diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds index e504ea7544..7d71c11ae4 100644 --- a/arch/mips/cpu/u-boot.lds +++ b/arch/mips/cpu/u-boot.lds @@ -61,6 +61,24 @@ SECTIONS __rel_dyn_end = .; } + .padding : { + /* + * Workaround for a binutils feature (or bug?). + * + * The GNU ld from binutils puts the dynamic relocation + * entries into the .rel.dyn section. Sometimes it + * allocates more dynamic relocation entries than it needs + * and the unused slots are set to R_MIPS_NONE entries. + * + * However the size of the .rel.dyn section in the ELF + * section header does not cover the unused entries, so + * objcopy removes those during stripping. + * + * Create a small section here to avoid that. + */ + LONG(0xFFFFFFFF) + } + _end = .; .bss __rel_dyn_start (OVERLAY) : { diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index e7bb3e33d5..9d38ef73a7 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -10,4 +10,4 @@ extra-y = start.o obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o -obj-y += interrupts.o cpu.o +obj-y += interrupts.o cpu.o call64.o diff --git a/arch/x86/cpu/call64.S b/arch/x86/cpu/call64.S new file mode 100644 index 0000000000..74dd5a89dc --- /dev/null +++ b/arch/x86/cpu/call64.S @@ -0,0 +1,93 @@ +/* + * (C) Copyright 2014 Google, Inc + * Copyright (C) 1991, 1992, 1993 Linus Torvalds + * + * Parts of this copied from Linux arch/x86/boot/compressed/head_64.S + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/global_data.h> +#include <asm/msr-index.h> +#include <asm/processor-flags.h> + +.code32 +.globl cpu_call64 +cpu_call64: + /* + * cpu_call64(ulong pgtable, ulong setup_base, ulong target) + * + * eax - pgtable + * edx - setup_base + * ecx - target + */ + cli + push %ecx /* arg2 = target */ + push %edx /* arg1 = setup_base */ + mov %eax, %ebx + + /* Load new GDT with the 64bit segments using 32bit descriptor */ + leal gdt, %eax + movl %eax, gdt+2 + lgdt gdt + + /* Enable PAE mode */ + movl $(X86_CR4_PAE), %eax + movl %eax, %cr4 + + /* Enable the boot page tables */ + leal (%ebx), %eax + movl %eax, %cr3 + + /* Enable Long mode in EFER (Extended Feature Enable Register) */ + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_LME, %eax + wrmsr + + /* After gdt is loaded */ + xorl %eax, %eax + lldt %ax + movl $0x20, %eax + ltr %ax + + /* + * Setup for the jump to 64bit mode + * + * When the jump is performed we will be in long mode but + * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1 + * (and in turn EFER.LMA = 1). To jump into 64bit mode we use + * the new gdt/idt that has __KERNEL_CS with CS.L = 1. + * We place all of the values on our mini stack so lret can + * used to perform that far jump. See the gdt below. + */ + pop %esi /* setup_base */ + + pushl $0x10 + leal lret_target, %eax + pushl %eax + + /* Enter paged protected Mode, activating Long Mode */ + movl $(X86_CR0_PG | X86_CR0_PE), %eax + movl %eax, %cr0 + + /* Jump from 32bit compatibility mode into 64bit mode. */ + lret + +code64: +lret_target: + pop %eax /* target */ + mov %eax, %eax /* Clear bits 63:32 */ + jmp *%eax /* Jump to the 64-bit target */ + + .data +gdt: + .word gdt_end - gdt + .long gdt + .word 0 + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x0080890000000000 /* TS descriptor */ + .quad 0x0000000000000000 /* TS continued */ +gdt_end: diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 623e3af61f..2e252532d6 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -18,7 +18,10 @@ #include <common.h> #include <command.h> +#include <errno.h> +#include <malloc.h> #include <asm/control_regs.h> +#include <asm/cpu.h> #include <asm/processor.h> #include <asm/processor-flags.h> #include <asm/interrupt.h> @@ -240,3 +243,144 @@ int icache_status(void) { return 1; } + +void cpu_enable_paging_pae(ulong cr3) +{ + __asm__ __volatile__( + /* Load the page table address */ + "movl %0, %%cr3\n" + /* Enable pae */ + "movl %%cr4, %%eax\n" + "orl $0x00000020, %%eax\n" + "movl %%eax, %%cr4\n" + /* Enable paging */ + "movl %%cr0, %%eax\n" + "orl $0x80000000, %%eax\n" + "movl %%eax, %%cr0\n" + : + : "r" (cr3) + : "eax"); +} + +void cpu_disable_paging_pae(void) +{ + /* Turn off paging */ + __asm__ __volatile__ ( + /* Disable paging */ + "movl %%cr0, %%eax\n" + "andl $0x7fffffff, %%eax\n" + "movl %%eax, %%cr0\n" + /* Disable pae */ + "movl %%cr4, %%eax\n" + "andl $0xffffffdf, %%eax\n" + "movl %%eax, %%cr4\n" + : + : + : "eax"); +} + +static bool has_cpuid(void) +{ + unsigned long flag; + + asm volatile("pushf\n" \ + "pop %%eax\n" + "mov %%eax, %%ecx\n" /* ecx = flags */ + "xor %1, %%eax\n" + "push %%eax\n" + "popf\n" /* flags ^= $2 */ + "pushf\n" + "pop %%eax\n" /* eax = flags */ + "push %%ecx\n" + "popf\n" /* flags = ecx */ + "xor %%ecx, %%eax\n" + "mov %%eax, %0" + : "=r" (flag) + : "i" (1 << 21) + : "eax", "ecx", "memory"); + + return flag != 0; +} + +static bool can_detect_long_mode(void) +{ + unsigned long flag; + + asm volatile("mov $0x80000000, %%eax\n" + "cpuid\n" + "mov %%eax, %0" + : "=r" (flag) + : + : "eax", "ebx", "ecx", "edx", "memory"); + + return flag > 0x80000000UL; +} + +static bool has_long_mode(void) +{ + unsigned long flag; + + asm volatile("mov $0x80000001, %%eax\n" + "cpuid\n" + "mov %%edx, %0" + : "=r" (flag) + : + : "eax", "ebx", "ecx", "edx", "memory"); + + return flag & (1 << 29) ? true : false; +} + +int cpu_has_64bit(void) +{ + return has_cpuid() && can_detect_long_mode() && + has_long_mode(); +} + +int print_cpuinfo(void) +{ + printf("CPU: %s\n", cpu_has_64bit() ? "x86_64" : "x86"); + + return 0; +} + +#define PAGETABLE_SIZE (6 * 4096) + +/** + * build_pagetable() - build a flat 4GiB page table structure for 64-bti mode + * + * @pgtable: Pointer to a 24iKB block of memory + */ +static void build_pagetable(uint32_t *pgtable) +{ + uint i; + + memset(pgtable, '\0', PAGETABLE_SIZE); + + /* Level 4 needs a single entry */ + pgtable[0] = (uint32_t)&pgtable[1024] + 7; + + /* Level 3 has one 64-bit entry for each GiB of memory */ + for (i = 0; i < 4; i++) { + pgtable[1024 + i * 2] = (uint32_t)&pgtable[2048] + + 0x1000 * i + 7; + } + + /* Level 2 has 2048 64-bit entries, each repesenting 2MiB */ + for (i = 0; i < 2048; i++) + pgtable[2048 + i * 2] = 0x183 + (i << 21UL); +} + +int cpu_jump_to_64bit(ulong setup_base, ulong target) +{ + uint32_t *pgtable; + + pgtable = memalign(4096, PAGETABLE_SIZE); + if (!pgtable) + return -ENOMEM; + + build_pagetable(pgtable); + cpu_call64((ulong)pgtable, setup_base, target); + free(pgtable); + + return -EFAULT; +} diff --git a/arch/x86/include/asm/bootm.h b/arch/x86/include/asm/bootm.h index 033ab79516..f6a64ce2c9 100644 --- a/arch/x86/include/asm/bootm.h +++ b/arch/x86/include/asm/bootm.h @@ -9,4 +9,20 @@ void bootm_announce_and_cleanup(void); +/** + * boot_linux_kernel() - boot a linux kernel + * + * This boots a kernel image, either 32-bit or 64-bit. It will also work with + * a self-extracting kernel, if you set @image_64bit to false. + * + * @setup_base: Pointer to the setup.bin information for the kernel + * @load_address: Pointer to the start of the kernel image + * @image_64bit: true if the image is a raw 64-bit kernel, false if it + * is raw 32-bit or any type of self-extracting kernel + * such as a bzImage. + * @return -ve error code. This function does not return if the kernel was + * booted successfully. + */ +int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit); + #endif diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h new file mode 100644 index 0000000000..6c6774af76 --- /dev/null +++ b/arch/x86/include/asm/cpu.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __X86_CPU_H +#define __X86_CPU_H + + /** + * cpu_enable_paging_pae() - Enable PAE-paging + * + * @pdpt: Value to set in cr3 (PDPT or PML4T) + */ +void cpu_enable_paging_pae(ulong cr3); + +/** + * cpu_disable_paging_pae() - Disable paging and PAE + */ +void cpu_disable_paging_pae(void); + +/** + * cpu_has_64bit() - Check if the CPU has 64-bit support + * + * @return 1 if this CPU supports long mode (64-bit), 0 if not + */ +int cpu_has_64bit(void); + +/** + * cpu_call64() - Jump to a 64-bit Linux kernel (internal function) + * + * The kernel is uncompressed and the 64-bit entry point is expected to be + * at @target. + * + * This function is used internally - see cpu_jump_to_64bit() for a more + * useful function. + * + * @pgtable: Address of 24KB area containing the page table + * @setup_base: Pointer to the setup.bin information for the kernel + * @target: Pointer to the start of the kernel image + */ +void cpu_call64(ulong pgtable, ulong setup_base, ulong target); + +/** + * cpu_jump_to_64bit() - Jump to a 64-bit Linux kernel + * + * The kernel is uncompressed and the 64-bit entry point is expected to be + * at @target. + * + * @setup_base: Pointer to the setup.bin information for the kernel + * @target: Pointer to the start of the kernel image + */ +int cpu_jump_to_64bit(ulong setup_base, ulong target); + +#endif diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 0a36e178f5..6027d593ff 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -44,12 +44,16 @@ #define MSR_IA32_PERFCTR0 0x000000c1 #define MSR_IA32_PERFCTR1 0x000000c2 #define MSR_FSB_FREQ 0x000000cd +#define MSR_NHM_PLATFORM_INFO 0x000000ce #define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 #define NHM_C3_AUTO_DEMOTE (1UL << 25) #define NHM_C1_AUTO_DEMOTE (1UL << 26) #define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25) +#define SNB_C1_AUTO_UNDEMOTE (1UL << 27) +#define SNB_C3_AUTO_UNDEMOTE (1UL << 28) +#define MSR_PLATFORM_INFO 0x000000ce #define MSR_MTRRcap 0x000000fe #define MSR_IA32_BBL_CR_CTL 0x00000119 #define MSR_IA32_BBL_CR_CTL3 0x0000011e @@ -64,10 +68,20 @@ #define MSR_OFFCORE_RSP_0 0x000001a6 #define MSR_OFFCORE_RSP_1 0x000001a7 +#define MSR_NHM_TURBO_RATIO_LIMIT 0x000001ad +#define MSR_IVT_TURBO_RATIO_LIMIT 0x000001ae + +#define MSR_LBR_SELECT 0x000001c8 +#define MSR_LBR_TOS 0x000001c9 +#define MSR_LBR_NHM_FROM 0x00000680 +#define MSR_LBR_NHM_TO 0x000006c0 +#define MSR_LBR_CORE_FROM 0x00000040 +#define MSR_LBR_CORE_TO 0x00000060 #define MSR_IA32_PEBS_ENABLE 0x000003f1 #define MSR_IA32_DS_AREA 0x00000600 #define MSR_IA32_PERF_CAPABILITIES 0x00000345 +#define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6 #define MSR_MTRRfix64K_00000 0x00000250 #define MSR_MTRRfix16K_80000 0x00000258 @@ -91,7 +105,8 @@ #define MSR_IA32_LASTINTTOIP 0x000001de /* DEBUGCTLMSR bits (others vary by model): */ -#define DEBUGCTLMSR_LBR (1UL << 0) +#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ +/* single-step on branches */ #define DEBUGCTLMSR_BTF (1UL << 1) #define DEBUGCTLMSR_TR (1UL << 6) #define DEBUGCTLMSR_BTS (1UL << 7) @@ -100,11 +115,50 @@ #define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10) #define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11) +#define MSR_IA32_POWER_CTL 0x000001fc + #define MSR_IA32_MC0_CTL 0x00000400 #define MSR_IA32_MC0_STATUS 0x00000401 #define MSR_IA32_MC0_ADDR 0x00000402 #define MSR_IA32_MC0_MISC 0x00000403 +/* C-state Residency Counters */ +#define MSR_PKG_C3_RESIDENCY 0x000003f8 +#define MSR_PKG_C6_RESIDENCY 0x000003f9 +#define MSR_PKG_C7_RESIDENCY 0x000003fa +#define MSR_CORE_C3_RESIDENCY 0x000003fc +#define MSR_CORE_C6_RESIDENCY 0x000003fd +#define MSR_CORE_C7_RESIDENCY 0x000003fe +#define MSR_PKG_C2_RESIDENCY 0x0000060d +#define MSR_PKG_C8_RESIDENCY 0x00000630 +#define MSR_PKG_C9_RESIDENCY 0x00000631 +#define MSR_PKG_C10_RESIDENCY 0x00000632 + +/* Run Time Average Power Limiting (RAPL) Interface */ + +#define MSR_RAPL_POWER_UNIT 0x00000606 + +#define MSR_PKG_POWER_LIMIT 0x00000610 +#define MSR_PKG_ENERGY_STATUS 0x00000611 +#define MSR_PKG_PERF_STATUS 0x00000613 +#define MSR_PKG_POWER_INFO 0x00000614 + +#define MSR_DRAM_POWER_LIMIT 0x00000618 +#define MSR_DRAM_ENERGY_STATUS 0x00000619 +#define MSR_DRAM_PERF_STATUS 0x0000061b +#define MSR_DRAM_POWER_INFO 0x0000061c + +#define MSR_PP0_POWER_LIMIT 0x00000638 +#define MSR_PP0_ENERGY_STATUS 0x00000639 +#define MSR_PP0_POLICY 0x0000063a +#define MSR_PP0_PERF_STATUS 0x0000063b + +#define MSR_PP1_POWER_LIMIT 0x00000640 +#define MSR_PP1_ENERGY_STATUS 0x00000641 +#define MSR_PP1_POLICY 0x00000642 + +#define MSR_CORE_C1_RES 0x00000660 + #define MSR_AMD64_MC0_MASK 0xc0010044 #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) @@ -123,18 +177,31 @@ #define MSR_P6_EVNTSEL0 0x00000186 #define MSR_P6_EVNTSEL1 0x00000187 +#define MSR_KNC_PERFCTR0 0x00000020 +#define MSR_KNC_PERFCTR1 0x00000021 +#define MSR_KNC_EVNTSEL0 0x00000028 +#define MSR_KNC_EVNTSEL1 0x00000029 + +/* Alternative perfctr range with full access. */ +#define MSR_IA32_PMC0 0x000004c1 + /* AMD64 MSRs. Not complete. See the architecture manual for a more complete list. */ #define MSR_AMD64_PATCH_LEVEL 0x0000008b +#define MSR_AMD64_TSC_RATIO 0xc0000104 #define MSR_AMD64_NB_CFG 0xc001001f #define MSR_AMD64_PATCH_LOADER 0xc0010020 #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 #define MSR_AMD64_OSVW_STATUS 0xc0010141 +#define MSR_AMD64_LS_CFG 0xc0011020 #define MSR_AMD64_DC_CFG 0xc0011022 +#define MSR_AMD64_BU_CFG2 0xc001102a #define MSR_AMD64_IBSFETCHCTL 0xc0011030 #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 #define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 +#define MSR_AMD64_IBSFETCH_REG_COUNT 3 +#define MSR_AMD64_IBSFETCH_REG_MASK ((1UL<<MSR_AMD64_IBSFETCH_REG_COUNT)-1) #define MSR_AMD64_IBSOPCTL 0xc0011033 #define MSR_AMD64_IBSOPRIP 0xc0011034 #define MSR_AMD64_IBSOPDATA 0xc0011035 @@ -142,12 +209,21 @@ #define MSR_AMD64_IBSOPDATA3 0xc0011037 #define MSR_AMD64_IBSDCLINAD 0xc0011038 #define MSR_AMD64_IBSDCPHYSAD 0xc0011039 +#define MSR_AMD64_IBSOP_REG_COUNT 7 +#define MSR_AMD64_IBSOP_REG_MASK ((1UL<<MSR_AMD64_IBSOP_REG_COUNT)-1) #define MSR_AMD64_IBSCTL 0xc001103a #define MSR_AMD64_IBSBRTARGET 0xc001103b +#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */ + +/* Fam 16h MSRs */ +#define MSR_F16H_L2I_PERF_CTL 0xc0010230 +#define MSR_F16H_L2I_PERF_CTR 0xc0010231 /* Fam 15h MSRs */ #define MSR_F15H_PERF_CTL 0xc0010200 #define MSR_F15H_PERF_CTR 0xc0010201 +#define MSR_F15H_NB_PERF_CTL 0xc0010240 +#define MSR_F15H_NB_PERF_CTR 0xc0010241 /* Fam 10h MSRs */ #define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 @@ -226,7 +302,9 @@ #define MSR_IA32_PLATFORM_ID 0x00000017 #define MSR_IA32_EBL_CR_POWERON 0x0000002a #define MSR_EBC_FREQUENCY_ID 0x0000002c +#define MSR_SMI_COUNT 0x00000034 #define MSR_IA32_FEATURE_CONTROL 0x0000003a +#define MSR_IA32_TSC_ADJUST 0x0000003b #define FEATURE_CONTROL_LOCKED (1<<0) #define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) @@ -237,11 +315,16 @@ #define MSR_IA32_APICBASE_ENABLE (1<<11) #define MSR_IA32_APICBASE_BASE (0xfffff<<12) +#define MSR_IA32_TSCDEADLINE 0x000006e0 + #define MSR_IA32_UCODE_WRITE 0x00000079 #define MSR_IA32_UCODE_REV 0x0000008b #define MSR_IA32_PERF_STATUS 0x00000198 #define MSR_IA32_PERF_CTL 0x00000199 +#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 +#define MSR_AMD_PERF_STATUS 0xc0010063 +#define MSR_AMD_PERF_CTL 0xc0010062 #define MSR_IA32_MPERF 0x000000e7 #define MSR_IA32_APERF 0x000000e8 @@ -267,6 +350,9 @@ #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 +#define ENERGY_PERF_BIAS_PERFORMANCE 0 +#define ENERGY_PERF_BIAS_NORMAL 6 +#define ENERGY_PERF_BIAS_POWERSAVE 15 #define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1 @@ -320,6 +406,8 @@ #define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) +#define MSR_IA32_TSC_DEADLINE 0x000006E0 + /* P4/Xeon+ specific */ #define MSR_IA32_MCG_EAX 0x00000180 #define MSR_IA32_MCG_EBX 0x00000181 @@ -446,7 +534,23 @@ #define MSR_IA32_VMX_VMCS_ENUM 0x0000048a #define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b #define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c - +#define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x0000048d +#define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x0000048e +#define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x0000048f +#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 +#define MSR_IA32_VMX_VMFUNC 0x00000491 + +/* VMX_BASIC bits and bitmasks */ +#define VMX_BASIC_VMCS_SIZE_SHIFT 32 +#define VMX_BASIC_64 0x0001000000000000LLU +#define VMX_BASIC_MEM_TYPE_SHIFT 50 +#define VMX_BASIC_MEM_TYPE_MASK 0x003c000000000000LLU +#define VMX_BASIC_MEM_TYPE_WB 6LLU +#define VMX_BASIC_INOUT 0x0040000000000000LLU + +/* MSR_IA32_VMX_MISC bits */ +#define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29) +#define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE 0x1F /* AMD-V MSRs */ #define MSR_VM_CR 0xc0010114 diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h index 0f36662688..8e7dd424ca 100644 --- a/arch/x86/include/asm/zimage.h +++ b/arch/x86/include/asm/zimage.h @@ -35,10 +35,8 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *); struct boot_params *load_zimage(char *image, unsigned long kernel_size, - void **load_address); + ulong *load_addressp); int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, unsigned long initrd_addr, unsigned long initrd_size); -void boot_zimage(void *setup_base, void *load_address); - #endif diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 4c5c7f5aa7..86030cf52a 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -10,10 +10,12 @@ #include <common.h> #include <command.h> +#include <errno.h> #include <fdt_support.h> #include <image.h> #include <u-boot/zlib.h> #include <asm/bootparam.h> +#include <asm/cpu.h> #include <asm/byteorder.h> #include <asm/zimage.h> #ifdef CONFIG_SYS_COREBOOT @@ -109,17 +111,17 @@ static int boot_prep_linux(bootm_headers_t *images) } if (is_zimage) { - void *load_address; + ulong load_address; char *base_ptr; base_ptr = (char *)load_zimage(data, len, &load_address); - images->os.load = (ulong)load_address; + images->os.load = load_address; cmd_line_dest = base_ptr + COMMAND_LINE_OFFSET; images->ep = (ulong)base_ptr; } else if (images->ep) { cmd_line_dest = (void *)images->ep + COMMAND_LINE_OFFSET; } else { - printf("## Kernel loading failed (no setup) ...\n"); + printf("## Kernel loading failed (missing x86 kernel setup) ...\n"); goto error; } @@ -139,16 +141,50 @@ error: return 1; } +int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit) +{ + bootm_announce_and_cleanup(); + +#ifdef CONFIG_SYS_COREBOOT + timestamp_add_now(TS_U_BOOT_START_KERNEL); +#endif + if (image_64bit) { + if (!cpu_has_64bit()) { + puts("Cannot boot 64-bit kernel on 32-bit machine\n"); + return -EFAULT; + } + return cpu_jump_to_64bit(setup_base, load_address); + } else { + /* + * Set %ebx, %ebp, and %edi to 0, %esi to point to the + * boot_params structure, and then jump to the kernel. We + * assume that %cs is 0x10, 4GB flat, and read/execute, and + * the data segments are 0x18, 4GB flat, and read/write. + * U-boot is setting them up that way for itself in + * arch/i386/cpu/cpu.c. + */ + __asm__ __volatile__ ( + "movl $0, %%ebp\n" + "cli\n" + "jmp *%[kernel_entry]\n" + :: [kernel_entry]"a"(load_address), + [boot_params] "S"(setup_base), + "b"(0), "D"(0) + ); + } + + /* We can't get to here */ + return -EFAULT; +} + /* Subcommand: GO */ static int boot_jump_linux(bootm_headers_t *images) { debug("## Transferring control to Linux (at address %08lx, kernel %08lx) ...\n", images->ep, images->os.load); - boot_zimage((struct boot_params *)images->ep, (void *)images->os.load); - /* does not return */ - - return 1; + return boot_linux_kernel(images->ep, images->os.load, + images->os.arch == IH_ARCH_X86_64); } int do_bootm_linux(int flag, int argc, char * const argv[], @@ -161,10 +197,8 @@ int do_bootm_linux(int flag, int argc, char * const argv[], if (flag & BOOTM_STATE_OS_PREP) return boot_prep_linux(images); - if (flag & BOOTM_STATE_OS_GO) { - boot_jump_linux(images); - return 0; - } + if (flag & BOOTM_STATE_OS_GO) + return boot_jump_linux(images); return boot_jump_linux(images); } diff --git a/arch/x86/lib/physmem.c b/arch/x86/lib/physmem.c index b57b2c30fe..c3c709ec07 100644 --- a/arch/x86/lib/physmem.c +++ b/arch/x86/lib/physmem.c @@ -10,6 +10,7 @@ #include <common.h> #include <physmem.h> +#include <asm/cpu.h> #include <linux/compiler.h> DECLARE_GLOBAL_DATA_PTR; @@ -112,41 +113,13 @@ static void x86_phys_enter_paging(void) x86_phys_map_page(page_addr, page_addr, 0); } - /* Turn on paging */ - __asm__ __volatile__( - /* Load the page table address */ - "movl %0, %%cr3\n\t" - /* Enable pae */ - "movl %%cr4, %%eax\n\t" - "orl $0x00000020, %%eax\n\t" - "movl %%eax, %%cr4\n\t" - /* Enable paging */ - "movl %%cr0, %%eax\n\t" - "orl $0x80000000, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - : - : "r" (pdpt) - : "eax" - ); + cpu_enable_paging_pae((ulong)pdpt); } /* Disable paging and PAE mode. */ static void x86_phys_exit_paging(void) { - /* Turn off paging */ - __asm__ __volatile__ ( - /* Disable paging */ - "movl %%cr0, %%eax\n\t" - "andl $0x7fffffff, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - /* Disable pae */ - "movl %%cr4, %%eax\n\t" - "andl $0xffffffdf, %%eax\n\t" - "movl %%eax, %%cr4\n\t" - : - : - : "eax" - ); + cpu_disable_paging_pae(); } /* diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index b1902834e8..566b048c88 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -103,7 +103,7 @@ static int get_boot_protocol(struct setup_header *hdr) } struct boot_params *load_zimage(char *image, unsigned long kernel_size, - void **load_address) + ulong *load_addressp) { struct boot_params *setup_base; int setup_size; @@ -155,9 +155,9 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, /* Determine load address */ if (big_image) - *load_address = (void *)BZIMAGE_LOAD_ADDR; + *load_addressp = BZIMAGE_LOAD_ADDR; else - *load_address = (void *)ZIMAGE_LOAD_ADDR; + *load_addressp = ZIMAGE_LOAD_ADDR; printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base); memset(setup_base, 0, sizeof(*setup_base)); @@ -204,10 +204,10 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, return 0; } - printf("Loading %s at address %p (%ld bytes)\n", - big_image ? "bzImage" : "zImage", *load_address, kernel_size); + printf("Loading %s at address %lx (%ld bytes)\n", + big_image ? "bzImage" : "zImage", *load_addressp, kernel_size); - memmove(*load_address, image + setup_size, kernel_size); + memmove((void *)*load_addressp, image + setup_size, kernel_size); return setup_base; } @@ -261,30 +261,6 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, return 0; } -void boot_zimage(void *setup_base, void *load_address) -{ - bootm_announce_and_cleanup(); - -#ifdef CONFIG_SYS_COREBOOT - timestamp_add_now(TS_U_BOOT_START_KERNEL); -#endif - /* - * Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params - * structure, and then jump to the kernel. We assume that %cs is - * 0x10, 4GB flat, and read/execute, and the data segments are 0x18, - * 4GB flat, and read/write. U-boot is setting them up that way for - * itself in arch/i386/cpu/cpu.c. - */ - __asm__ __volatile__ ( - "movl $0, %%ebp\n" - "cli\n" - "jmp *%[kernel_entry]\n" - :: [kernel_entry]"a"(load_address), - [boot_params] "S"(setup_base), - "b"(0), "D"(0) - ); -} - void setup_pcat_compatibility(void) __attribute__((weak, alias("__setup_pcat_compatibility"))); @@ -296,7 +272,7 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { struct boot_params *base_ptr; void *bzImage_addr = NULL; - void *load_address; + ulong load_address; char *s; ulong bzImage_size = 0; ulong initrd_addr = 0; @@ -331,20 +307,17 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) base_ptr = load_zimage(bzImage_addr, bzImage_size, &load_address); if (!base_ptr) { - printf("## Kernel loading failed ...\n"); + puts("## Kernel loading failed ...\n"); return -1; } if (setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET, 0, initrd_addr, initrd_size)) { - printf("Setting up boot parameters failed ...\n"); + puts("Setting up boot parameters failed ...\n"); return -1; } /* we assume that the kernel is in place */ - boot_zimage(base_ptr, load_address); - /* does not return */ - - return -1; + return boot_linux_kernel((ulong)base_ptr, load_address, false); } U_BOOT_CMD( diff --git a/board/dbau1x00/Kconfig b/board/dbau1x00/Kconfig index 1a8946d06c..1286e4509f 100644 --- a/board/dbau1x00/Kconfig +++ b/board/dbau1x00/Kconfig @@ -1,8 +1,5 @@ if TARGET_DBAU1X00 -config SYS_CPU - default "mips32" - config SYS_BOARD default "dbau1x00" @@ -12,4 +9,22 @@ config SYS_SOC config SYS_CONFIG_NAME default "dbau1x00" +menu "dbau1x00 board options" + +choice + prompt "Select au1x00 SoC type" + +config DBAU1100 + bool "Select AU1100" + +config DBAU1500 + bool "Select AU1500" + +config DBAU1550 + bool "Select AU1550" + +endchoice + +endmenu + endif diff --git a/board/imgtec/malta/Kconfig b/board/imgtec/malta/Kconfig index 401962c4bd..4c06d0c0d8 100644 --- a/board/imgtec/malta/Kconfig +++ b/board/imgtec/malta/Kconfig @@ -1,8 +1,5 @@ if TARGET_MALTA -config SYS_CPU - default "mips32" - config SYS_BOARD default "malta" diff --git a/board/micronas/vct/Kconfig b/board/micronas/vct/Kconfig index 75046fe7ab..288a1aeb70 100644 --- a/board/micronas/vct/Kconfig +++ b/board/micronas/vct/Kconfig @@ -1,8 +1,5 @@ if TARGET_VCT -config SYS_CPU - default "mips32" - config SYS_BOARD default "vct" @@ -12,4 +9,28 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "vct" +menu "vct board options" + +choice + prompt "Board variant" + +config VCT_PLATINUM + bool "Enable VCT_PLATINUM" + +config VCT_PLATINUMAVC + bool "Enable VCT_PLATINUMAVC" + +config VCT_PREMIUM + bool "Enable VCT_PLATINUMAVC" + +endchoice + +config VCT_ONENAND + bool "Enable VCT_ONENAND" + +config VCT_SMALL_IMAGE + bool "Enable VCT_SMALL_IMAGE" + +endmenu + endif diff --git a/board/pb1x00/Kconfig b/board/pb1x00/Kconfig index ef2844a497..251db6ab63 100644 --- a/board/pb1x00/Kconfig +++ b/board/pb1x00/Kconfig @@ -1,8 +1,5 @@ if TARGET_PB1X00 -config SYS_CPU - default "mips32" - config SYS_BOARD default "pb1x00" diff --git a/board/qemu-mips/Kconfig b/board/qemu-mips/Kconfig index e4d9663c2d..18d78b5100 100644 --- a/board/qemu-mips/Kconfig +++ b/board/qemu-mips/Kconfig @@ -1,25 +1,10 @@ if TARGET_QEMU_MIPS -config SYS_CPU - default "mips32" - -config SYS_BOARD - default "qemu-mips" - -config SYS_CONFIG_NAME - default "qemu-mips" - -endif - -if TARGET_QEMU_MIPS64 - -config SYS_CPU - default "mips64" - config SYS_BOARD default "qemu-mips" config SYS_CONFIG_NAME - default "qemu-mips64" + default "qemu-mips" if 32BIT + default "qemu-mips64" if 64BIT endif diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c index 5edb250f06..33003ee9b5 100644 --- a/board/samsung/odroid/odroid.c +++ b/board/samsung/odroid/odroid.c @@ -356,21 +356,29 @@ static void board_clock_init(void) static void board_gpio_init(void) { /* eMMC Reset Pin */ + gpio_request(EXYNOS4X12_GPIO_K12, "eMMC Reset"); + gpio_cfg_pin(EXYNOS4X12_GPIO_K12, S5P_GPIO_FUNC(0x1)); gpio_set_pull(EXYNOS4X12_GPIO_K12, S5P_GPIO_PULL_NONE); gpio_set_drv(EXYNOS4X12_GPIO_K12, S5P_GPIO_DRV_4X); /* Enable FAN (Odroid U3) */ + gpio_request(EXYNOS4X12_GPIO_D00, "FAN Control"); + gpio_set_pull(EXYNOS4X12_GPIO_D00, S5P_GPIO_PULL_UP); gpio_set_drv(EXYNOS4X12_GPIO_D00, S5P_GPIO_DRV_4X); gpio_direction_output(EXYNOS4X12_GPIO_D00, 1); /* OTG Vbus output (Odroid U3+) */ + gpio_request(EXYNOS4X12_GPIO_L20, "OTG Vbus"); + gpio_set_pull(EXYNOS4X12_GPIO_L20, S5P_GPIO_PULL_NONE); gpio_set_drv(EXYNOS4X12_GPIO_L20, S5P_GPIO_DRV_4X); gpio_direction_output(EXYNOS4X12_GPIO_L20, 0); /* OTG INT (Odroid U3+) */ + gpio_request(EXYNOS4X12_GPIO_X31, "OTG INT"); + gpio_set_pull(EXYNOS4X12_GPIO_X31, S5P_GPIO_PULL_UP); gpio_set_drv(EXYNOS4X12_GPIO_X31, S5P_GPIO_DRV_4X); gpio_direction_input(EXYNOS4X12_GPIO_X31); @@ -403,7 +411,6 @@ static void board_init_i2c(void) int exynos_early_init_f(void) { board_clock_init(); - board_gpio_init(); return 0; } @@ -414,6 +421,8 @@ int exynos_init(void) gd->ram_size -= SZ_1M; gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS - 1].size -= SZ_1M; + board_gpio_init(); + return 0; } diff --git a/common/bootm.c b/common/bootm.c index 81e32617c3..6b3ea8c61b 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -167,7 +167,8 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, } /* If we have a valid setup.bin, we will use that for entry (x86) */ - if (images.os.arch == IH_ARCH_I386) { + if (images.os.arch == IH_ARCH_I386 || + images.os.arch == IH_ARCH_X86_64) { ulong len; ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len); diff --git a/common/image-fit.c b/common/image-fit.c index a272ea2e83..4ffc5aaa51 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1114,7 +1114,8 @@ int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) if (fit_image_get_arch(fit, noffset, &image_arch)) return 0; - return (arch == image_arch); + return (arch == image_arch) || + (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64); } /** diff --git a/common/image.c b/common/image.c index eb92e6323c..b75a5ce29a 100644 --- a/common/image.c +++ b/common/image.c @@ -85,6 +85,7 @@ static const table_entry_t uimage_arch[] = { { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, { IH_ARCH_ARM64, "arm64", "AArch64", }, { IH_ARCH_ARC, "arc", "ARC", }, + { IH_ARCH_X86_64, "x86_64", "AMD x86_64", }, { -1, "", "", }, }; diff --git a/common/stdio.c b/common/stdio.c index 68c595d2d7..adbfc890dd 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -197,6 +197,7 @@ int stdio_deregister_dev(struct stdio_dev *dev, int force) } list_del(&(dev->list)); + free(dev); /* reassign Device list */ list_for_each(pos, &(devs.list)) { diff --git a/common/usb.c b/common/usb.c index bd0f8d5d18..7d33a0f086 100644 --- a/common/usb.c +++ b/common/usb.c @@ -927,7 +927,6 @@ int usb_new_device(struct usb_device *dev) * thread_id=5729457&forum_id=5398 */ __maybe_unused struct usb_device_descriptor *desc; - int port = -1; struct usb_device *parent = dev->parent; unsigned short portstatus; @@ -965,24 +964,10 @@ int usb_new_device(struct usb_device *dev) #endif if (parent) { - int j; - - /* find the port number we're at */ - for (j = 0; j < parent->maxchild; j++) { - if (parent->children[j] == dev) { - port = j; - break; - } - } - if (port < 0) { - printf("usb_new_device:cannot locate device's port.\n"); - return 1; - } - /* reset the port for the second time */ - err = hub_port_reset(dev->parent, port, &portstatus); + err = hub_port_reset(dev->parent, dev->portnr - 1, &portstatus); if (err < 0) { - printf("\n Couldn't reset port %i\n", port); + printf("\n Couldn't reset port %i\n", dev->portnr); return 1; } } diff --git a/common/usb_hub.c b/common/usb_hub.c index c416e5e0b3..0f1eab4486 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -86,50 +86,11 @@ static void usb_hub_power_on(struct usb_hub_device *hub) int i; struct usb_device *dev; unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2; - ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); - unsigned short portstatus; - int ret; dev = hub->pusb_dev; - /* - * Enable power to the ports: - * Here we Power-cycle the ports: aka, - * turning them off and turning on again. - */ debug("enabling power on all ports\n"); for (i = 0; i < dev->maxchild; i++) { - usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); - debug("port %d returns %lX\n", i + 1, dev->status); - } - - /* Wait at least 2*bPwrOn2PwrGood for PP to change */ - mdelay(pgood_delay); - - for (i = 0; i < dev->maxchild; i++) { - ret = usb_get_port_status(dev, i + 1, portsts); - if (ret < 0) { - debug("port %d: get_port_status failed\n", i + 1); - continue; - } - - /* - * Check to confirm the state of Port Power: - * xHCI says "After modifying PP, s/w shall read - * PP and confirm that it has reached the desired state - * before modifying it again, undefined behavior may occur - * if this procedure is not followed". - * EHCI doesn't say anything like this, but no harm in keeping - * this. - */ - portstatus = le16_to_cpu(portsts->wPortStatus); - if (portstatus & (USB_PORT_STAT_POWER << 1)) { - debug("port %d: Port power change failed\n", i + 1); - continue; - } - } - - for (i = 0; i < dev->maxchild; i++) { usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); debug("port %d returns %lX\n", i + 1, dev->status); } diff --git a/common/usb_kbd.c b/common/usb_kbd.c index fdc083c70c..bc7145ea79 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -99,6 +99,11 @@ static const unsigned char usb_kbd_arrow[] = { #define USB_KBD_BOOT_REPORT_SIZE 8 struct usb_kbd_pdata { + unsigned long intpipe; + int intpktsize; + int intinterval; + struct int_queue *intq; + uint32_t repeat_delay; uint32_t usb_in_pointer; @@ -116,32 +121,6 @@ extern int __maybe_unused net_busy_flag; /* The period of time between two calls of usb_kbd_testc(). */ static unsigned long __maybe_unused kbd_testc_tms; -/* Generic keyboard event polling. */ -void usb_kbd_generic_poll(void) -{ - struct stdio_dev *dev; - struct usb_device *usb_kbd_dev; - struct usb_kbd_pdata *data; - struct usb_interface *iface; - struct usb_endpoint_descriptor *ep; - int pipe; - int maxp; - - /* Get the pointer to USB Keyboard device pointer */ - dev = stdio_get_by_name(DEVNAME); - usb_kbd_dev = (struct usb_device *)dev->priv; - data = usb_kbd_dev->privptr; - iface = &usb_kbd_dev->config.if_desc[0]; - ep = &iface->ep_desc[0]; - pipe = usb_rcvintpipe(usb_kbd_dev, ep->bEndpointAddress); - - /* Submit a interrupt transfer request */ - maxp = usb_maxpacket(usb_kbd_dev, pipe); - usb_submit_int_msg(usb_kbd_dev, pipe, data->new, - min(maxp, USB_KBD_BOOT_REPORT_SIZE), - ep->bInterval); -} - /* Puts character in the queue and sets up the in and out pointer. */ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, char c) { @@ -331,23 +310,11 @@ static int usb_kbd_irq(struct usb_device *dev) static inline void usb_kbd_poll_for_event(struct usb_device *dev) { #if defined(CONFIG_SYS_USB_EVENT_POLL) - struct usb_interface *iface; - struct usb_endpoint_descriptor *ep; - struct usb_kbd_pdata *data; - int pipe; - int maxp; - - /* Get the pointer to USB Keyboard device pointer */ - data = dev->privptr; - iface = &dev->config.if_desc[0]; - ep = &iface->ep_desc[0]; - pipe = usb_rcvintpipe(dev, ep->bEndpointAddress); + struct usb_kbd_pdata *data = dev->privptr; /* Submit a interrupt transfer request */ - maxp = usb_maxpacket(dev, pipe); - usb_submit_int_msg(dev, pipe, &data->new[0], - min(maxp, USB_KBD_BOOT_REPORT_SIZE), - ep->bInterval); + usb_submit_int_msg(dev, data->intpipe, &data->new[0], data->intpktsize, + data->intinterval); usb_kbd_irq_worker(dev); #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) @@ -358,6 +325,15 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) 1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE); if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE)) usb_kbd_irq_worker(dev); +#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE) + struct usb_kbd_pdata *data = dev->privptr; + if (poll_int_queue(dev, data->intq)) { + usb_kbd_irq_worker(dev); + /* We've consumed all queued int packets, create new */ + destroy_int_queue(dev, data->intq); + data->intq = create_int_queue(dev, data->intpipe, 1, + USB_KBD_BOOT_REPORT_SIZE, data->new); + } #endif } @@ -415,7 +391,6 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) struct usb_interface *iface; struct usb_endpoint_descriptor *ep; struct usb_kbd_pdata *data; - int pipe, maxp; if (dev->descriptor.bNumConfigurations != 1) return 0; @@ -464,8 +439,10 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) /* Set IRQ handler */ dev->irq_handle = usb_kbd_irq; - pipe = usb_rcvintpipe(dev, ep->bEndpointAddress); - maxp = usb_maxpacket(dev, pipe); + data->intpipe = usb_rcvintpipe(dev, ep->bEndpointAddress); + data->intpktsize = min(usb_maxpacket(dev, data->intpipe), + USB_KBD_BOOT_REPORT_SIZE); + data->intinterval = ep->bInterval; /* We found a USB Keyboard, install it. */ usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0); @@ -474,9 +451,14 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0); debug("USB KBD: enable interrupt pipe...\n"); - if (usb_submit_int_msg(dev, pipe, data->new, - min(maxp, USB_KBD_BOOT_REPORT_SIZE), - ep->bInterval) < 0) { +#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE + data->intq = create_int_queue(dev, data->intpipe, 1, + USB_KBD_BOOT_REPORT_SIZE, data->new); + if (!data->intq) { +#else + if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize, + data->intinterval) < 0) { +#endif printf("Failed to get keyboard state from device %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); /* Abort, we don't want to use that non-functional keyboard. */ @@ -550,9 +532,22 @@ int drv_usb_kbd_init(void) int usb_kbd_deregister(int force) { #ifdef CONFIG_SYS_STDIO_DEREGISTER - int ret = stdio_deregister(DEVNAME, force); - if (ret && ret != -ENODEV) - return ret; + struct stdio_dev *dev; + struct usb_device *usb_kbd_dev; + struct usb_kbd_pdata *data; + + dev = stdio_get_by_name(DEVNAME); + if (dev) { + usb_kbd_dev = (struct usb_device *)dev->priv; + data = usb_kbd_dev->privptr; + if (stdio_deregister_dev(dev, force) != 0) + return 1; +#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE + destroy_int_queue(usb_kbd_dev, data->intq); +#endif + free(data->new); + free(data); + } return 0; #else diff --git a/configs/dbau1000_defconfig b/configs/dbau1000_defconfig index 7c95629cfb..aa4d338d43 100644 --- a/configs/dbau1000_defconfig +++ b/configs/dbau1000_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="DBAU1000" CONFIG_MIPS=y CONFIG_TARGET_DBAU1X00=y +CONFIG_SYS_BIG_ENDIAN=y diff --git a/configs/dbau1100_defconfig b/configs/dbau1100_defconfig index 506f5da8ca..aac9f032b0 100644 --- a/configs/dbau1100_defconfig +++ b/configs/dbau1100_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="DBAU1100" CONFIG_MIPS=y CONFIG_TARGET_DBAU1X00=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_DBAU1100=y diff --git a/configs/dbau1500_defconfig b/configs/dbau1500_defconfig index 5a02a78610..d96de13ff9 100644 --- a/configs/dbau1500_defconfig +++ b/configs/dbau1500_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="DBAU1500" CONFIG_MIPS=y CONFIG_TARGET_DBAU1X00=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_DBAU1500=y diff --git a/configs/dbau1550_defconfig b/configs/dbau1550_defconfig index 9015023524..a2dfe18c78 100644 --- a/configs/dbau1550_defconfig +++ b/configs/dbau1550_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="DBAU1550" CONFIG_MIPS=y CONFIG_TARGET_DBAU1X00=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_DBAU1550=y diff --git a/configs/dbau1550_el_defconfig b/configs/dbau1550_el_defconfig index 53b35ce60f..767326f6d4 100644 --- a/configs/dbau1550_el_defconfig +++ b/configs/dbau1550_el_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="DBAU1550,SYS_LITTLE_ENDIAN" CONFIG_MIPS=y CONFIG_TARGET_DBAU1X00=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_DBAU1550=y diff --git a/configs/malta_defconfig b/configs/malta_defconfig index f3788b6db1..5a178a76b3 100644 --- a/configs/malta_defconfig +++ b/configs/malta_defconfig @@ -1,3 +1,3 @@ -CONFIG_SYS_EXTRA_OPTIONS="SYS_BIG_ENDIAN" CONFIG_MIPS=y CONFIG_TARGET_MALTA=y +CONFIG_SYS_BIG_ENDIAN=y diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig index 97d0e899da..011525fc2b 100644 --- a/configs/maltael_defconfig +++ b/configs/maltael_defconfig @@ -1,3 +1,3 @@ -CONFIG_SYS_EXTRA_OPTIONS="SYS_LITTLE_ENDIAN" CONFIG_MIPS=y CONFIG_TARGET_MALTA=y +CONFIG_SYS_LITTLE_ENDIAN=y diff --git a/configs/pb1000_defconfig b/configs/pb1000_defconfig index e226358fe2..72c22a0876 100644 --- a/configs/pb1000_defconfig +++ b/configs/pb1000_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="PB1000" CONFIG_MIPS=y CONFIG_TARGET_PB1X00=y +CONFIG_SYS_LITTLE_ENDIAN=y diff --git a/configs/qemu_mips64_defconfig b/configs/qemu_mips64_defconfig index 2948355769..3608bbe552 100644 --- a/configs/qemu_mips64_defconfig +++ b/configs/qemu_mips64_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="SYS_BIG_ENDIAN" CONFIG_MIPS=y -CONFIG_TARGET_QEMU_MIPS64=y +CONFIG_TARGET_QEMU_MIPS=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_CPU_MIPS64_R1=y diff --git a/configs/qemu_mips64el_defconfig b/configs/qemu_mips64el_defconfig index 13a039f0b8..a9ebd7b5ff 100644 --- a/configs/qemu_mips64el_defconfig +++ b/configs/qemu_mips64el_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="SYS_LITTLE_ENDIAN" CONFIG_MIPS=y -CONFIG_TARGET_QEMU_MIPS64=y +CONFIG_TARGET_QEMU_MIPS=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS64_R1=y diff --git a/configs/qemu_mips_defconfig b/configs/qemu_mips_defconfig index 6b2c0290e9..f58dd2200a 100644 --- a/configs/qemu_mips_defconfig +++ b/configs/qemu_mips_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="SYS_BIG_ENDIAN" CONFIG_MIPS=y CONFIG_TARGET_QEMU_MIPS=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_CPU_MIPS32_R2=y diff --git a/configs/qemu_mipsel_defconfig b/configs/qemu_mipsel_defconfig index 57c87016c4..84a45116fa 100644 --- a/configs/qemu_mipsel_defconfig +++ b/configs/qemu_mipsel_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="SYS_LITTLE_ENDIAN" CONFIG_MIPS=y CONFIG_TARGET_QEMU_MIPS=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS32_R2=y diff --git a/configs/vct_platinum_defconfig b/configs/vct_platinum_defconfig index 9ff8b68421..32e9e8cc6d 100644 --- a/configs/vct_platinum_defconfig +++ b/configs/vct_platinum_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUM" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUM=y diff --git a/configs/vct_platinum_onenand_defconfig b/configs/vct_platinum_onenand_defconfig index f33c97dc8f..4346518a18 100644 --- a/configs/vct_platinum_onenand_defconfig +++ b/configs/vct_platinum_onenand_defconfig @@ -1,3 +1,5 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUM,VCT_ONENAND" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUM=y +CONFIG_VCT_ONENAND=y diff --git a/configs/vct_platinum_onenand_small_defconfig b/configs/vct_platinum_onenand_small_defconfig index 58c79955ab..fd52282966 100644 --- a/configs/vct_platinum_onenand_small_defconfig +++ b/configs/vct_platinum_onenand_small_defconfig @@ -1,4 +1,7 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUM,VCT_ONENAND,VCT_SMALL_IMAGE" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUM=y +CONFIG_VCT_ONENAND=y +CONFIG_VCT_SMALL_IMAGE=y # CONFIG_CMD_CRC32 is not set diff --git a/configs/vct_platinum_small_defconfig b/configs/vct_platinum_small_defconfig index f4f56c4f4c..58f956d7db 100644 --- a/configs/vct_platinum_small_defconfig +++ b/configs/vct_platinum_small_defconfig @@ -1,4 +1,6 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUM,VCT_SMALL_IMAGE" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUM=y +CONFIG_VCT_SMALL_IMAGE=y # CONFIG_CMD_CRC32 is not set diff --git a/configs/vct_platinumavc_defconfig b/configs/vct_platinumavc_defconfig index 8aaac56e3d..732565cb96 100644 --- a/configs/vct_platinumavc_defconfig +++ b/configs/vct_platinumavc_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUMAVC" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUMAVC=y diff --git a/configs/vct_platinumavc_onenand_defconfig b/configs/vct_platinumavc_onenand_defconfig index 926c6e4050..670e7f92da 100644 --- a/configs/vct_platinumavc_onenand_defconfig +++ b/configs/vct_platinumavc_onenand_defconfig @@ -1,3 +1,5 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUMAVC,VCT_ONENAND" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUMAVC=y +CONFIG_VCT_ONENAND=y diff --git a/configs/vct_platinumavc_onenand_small_defconfig b/configs/vct_platinumavc_onenand_small_defconfig index 31b4c9a8d6..31a4948e70 100644 --- a/configs/vct_platinumavc_onenand_small_defconfig +++ b/configs/vct_platinumavc_onenand_small_defconfig @@ -1,4 +1,7 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUMAVC,VCT_ONENAND,VCT_SMALL_IMAGE" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUMAVC=y +CONFIG_VCT_ONENAND=y +CONFIG_VCT_SMALL_IMAGE=y # CONFIG_CMD_CRC32 is not set diff --git a/configs/vct_platinumavc_small_defconfig b/configs/vct_platinumavc_small_defconfig index 23f6561b34..ce00a6c0f1 100644 --- a/configs/vct_platinumavc_small_defconfig +++ b/configs/vct_platinumavc_small_defconfig @@ -1,4 +1,6 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PLATINUMAVC,VCT_SMALL_IMAGE" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PLATINUMAVC=y +CONFIG_VCT_SMALL_IMAGE=y # CONFIG_CMD_CRC32 is not set diff --git a/configs/vct_premium_defconfig b/configs/vct_premium_defconfig index 0e16ff9cac..a19e65d7e6 100644 --- a/configs/vct_premium_defconfig +++ b/configs/vct_premium_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PREMIUM" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PREMIUM=y diff --git a/configs/vct_premium_onenand_defconfig b/configs/vct_premium_onenand_defconfig index 29734b8274..092d0f79d3 100644 --- a/configs/vct_premium_onenand_defconfig +++ b/configs/vct_premium_onenand_defconfig @@ -1,3 +1,5 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PREMIUM,VCT_ONENAND" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PREMIUM=y +CONFIG_VCT_ONENAND=y diff --git a/configs/vct_premium_onenand_small_defconfig b/configs/vct_premium_onenand_small_defconfig index 354793edc8..eabfb88e0c 100644 --- a/configs/vct_premium_onenand_small_defconfig +++ b/configs/vct_premium_onenand_small_defconfig @@ -1,4 +1,7 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PREMIUM=y +CONFIG_VCT_ONENAND=y +CONFIG_VCT_SMALL_IMAGE=y # CONFIG_CMD_CRC32 is not set diff --git a/configs/vct_premium_small_defconfig b/configs/vct_premium_small_defconfig index a23ddb7e21..1ce0efd273 100644 --- a/configs/vct_premium_small_defconfig +++ b/configs/vct_premium_small_defconfig @@ -1,4 +1,6 @@ -CONFIG_SYS_EXTRA_OPTIONS="VCT_PREMIUM,VCT_SMALL_IMAGE" CONFIG_MIPS=y CONFIG_TARGET_VCT=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_VCT_PREMIUM=y +CONFIG_VCT_SMALL_IMAGE=y # CONFIG_CMD_CRC32 is not set diff --git a/doc/SPI/README.altera_spi b/doc/SPI/README.altera_spi new file mode 100644 index 0000000000..b07449f80d --- /dev/null +++ b/doc/SPI/README.altera_spi @@ -0,0 +1,6 @@ +SoCFPGA EPCS/EPCQx1 mini howto: +- Instantiate EPCS/EPCQx1 Serial flash controller in QSys and rebuild +- The controller base address is the "Base" in QSys + 0x400 +- Set MSEL[4:0]=10010 (AS Standard) +- Load the bitstream into FPGA, enable bridges +- Only then will the driver work diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c index 9114b3ed60..3f3d415213 100644 --- a/drivers/serial/serial_uniphier.c +++ b/drivers/serial/serial_uniphier.c @@ -55,7 +55,7 @@ struct uniphier_serial_private_data { #define uniphier_serial_port(dev) \ ((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase -int uniphier_serial_setbrg(struct udevice *dev, int baudrate) +static int uniphier_serial_setbrg(struct udevice *dev, int baudrate) { struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); struct uniphier_serial __iomem *port = uniphier_serial_port(dev); @@ -93,7 +93,17 @@ static int uniphier_serial_putc(struct udevice *dev, const char c) return 0; } -int uniphier_serial_probe(struct udevice *dev) +static int uniphier_serial_pending(struct udevice *dev, bool input) +{ + struct uniphier_serial __iomem *port = uniphier_serial_port(dev); + + if (input) + return readb(&port->lsr) & UART_LSR_DR; + else + return !(readb(&port->lsr) & UART_LSR_THRE); +} + +static int uniphier_serial_probe(struct udevice *dev) { struct uniphier_serial_private_data *priv = dev_get_priv(dev); struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); @@ -106,7 +116,7 @@ int uniphier_serial_probe(struct udevice *dev) return 0; } -int uniphier_serial_remove(struct udevice *dev) +static int uniphier_serial_remove(struct udevice *dev) { unmap_sysmem(uniphier_serial_port(dev)); @@ -134,6 +144,7 @@ static const struct dm_serial_ops uniphier_serial_ops = { .setbrg = uniphier_serial_setbrg, .getc = uniphier_serial_getc, .putc = uniphier_serial_putc, + .pending = uniphier_serial_pending, }; U_BOOT_DRIVER(uniphier_serial) = { diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c index 5accbb5c22..a4d03d97cf 100644 --- a/drivers/spi/altera_spi.c +++ b/drivers/spi/altera_spi.c @@ -12,58 +12,62 @@ #include <malloc.h> #include <spi.h> -#define ALTERA_SPI_RXDATA 0 -#define ALTERA_SPI_TXDATA 4 -#define ALTERA_SPI_STATUS 8 -#define ALTERA_SPI_CONTROL 12 -#define ALTERA_SPI_SLAVE_SEL 20 - -#define ALTERA_SPI_STATUS_ROE_MSK (0x8) -#define ALTERA_SPI_STATUS_TOE_MSK (0x10) -#define ALTERA_SPI_STATUS_TMT_MSK (0x20) -#define ALTERA_SPI_STATUS_TRDY_MSK (0x40) -#define ALTERA_SPI_STATUS_RRDY_MSK (0x80) -#define ALTERA_SPI_STATUS_E_MSK (0x100) - -#define ALTERA_SPI_CONTROL_IROE_MSK (0x8) -#define ALTERA_SPI_CONTROL_ITOE_MSK (0x10) -#define ALTERA_SPI_CONTROL_ITRDY_MSK (0x40) -#define ALTERA_SPI_CONTROL_IRRDY_MSK (0x80) -#define ALTERA_SPI_CONTROL_IE_MSK (0x100) -#define ALTERA_SPI_CONTROL_SSO_MSK (0x400) +#ifndef CONFIG_ALTERA_SPI_IDLE_VAL +#define CONFIG_ALTERA_SPI_IDLE_VAL 0xff +#endif #ifndef CONFIG_SYS_ALTERA_SPI_LIST #define CONFIG_SYS_ALTERA_SPI_LIST { CONFIG_SYS_SPI_BASE } #endif +struct altera_spi_regs { + u32 rxdata; + u32 txdata; + u32 status; + u32 control; + u32 _reserved; + u32 slave_sel; +}; + +#define ALTERA_SPI_STATUS_ROE_MSK (1 << 3) +#define ALTERA_SPI_STATUS_TOE_MSK (1 << 4) +#define ALTERA_SPI_STATUS_TMT_MSK (1 << 5) +#define ALTERA_SPI_STATUS_TRDY_MSK (1 << 6) +#define ALTERA_SPI_STATUS_RRDY_MSK (1 << 7) +#define ALTERA_SPI_STATUS_E_MSK (1 << 8) + +#define ALTERA_SPI_CONTROL_IROE_MSK (1 << 3) +#define ALTERA_SPI_CONTROL_ITOE_MSK (1 << 4) +#define ALTERA_SPI_CONTROL_ITRDY_MSK (1 << 6) +#define ALTERA_SPI_CONTROL_IRRDY_MSK (1 << 7) +#define ALTERA_SPI_CONTROL_IE_MSK (1 << 8) +#define ALTERA_SPI_CONTROL_SSO_MSK (1 << 10) + static ulong altera_spi_base_list[] = CONFIG_SYS_ALTERA_SPI_LIST; struct altera_spi_slave { - struct spi_slave slave; - ulong base; + struct spi_slave slave; + struct altera_spi_regs *regs; }; #define to_altera_spi_slave(s) container_of(s, struct altera_spi_slave, slave) -__attribute__((weak)) -int spi_cs_is_valid(unsigned int bus, unsigned int cs) +__weak int spi_cs_is_valid(unsigned int bus, unsigned int cs) { return bus < ARRAY_SIZE(altera_spi_base_list) && cs < 32; } -__attribute__((weak)) -void spi_cs_activate(struct spi_slave *slave) +__weak void spi_cs_activate(struct spi_slave *slave) { struct altera_spi_slave *altspi = to_altera_spi_slave(slave); - writel(1 << slave->cs, altspi->base + ALTERA_SPI_SLAVE_SEL); - writel(ALTERA_SPI_CONTROL_SSO_MSK, altspi->base + ALTERA_SPI_CONTROL); + writel(1 << slave->cs, &altspi->regs->slave_sel); + writel(ALTERA_SPI_CONTROL_SSO_MSK, &altspi->regs->control); } -__attribute__((weak)) -void spi_cs_deactivate(struct spi_slave *slave) +__weak void spi_cs_deactivate(struct spi_slave *slave) { struct altera_spi_slave *altspi = to_altera_spi_slave(slave); - writel(0, altspi->base + ALTERA_SPI_CONTROL); - writel(0, altspi->base + ALTERA_SPI_SLAVE_SEL); + writel(0, &altspi->regs->control); + writel(0, &altspi->regs->slave_sel); } void spi_init(void) @@ -87,9 +91,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, if (!altspi) return NULL; - altspi->base = altera_spi_base_list[bus]; - debug("%s: bus:%i cs:%i base:%lx\n", __func__, - bus, cs, altspi->base); + altspi->regs = (struct altera_spi_regs *)altera_spi_base_list[bus]; + debug("%s: bus:%i cs:%i base:%p\n", __func__, bus, cs, altspi->regs); return &altspi->slave; } @@ -105,8 +108,8 @@ int spi_claim_bus(struct spi_slave *slave) struct altera_spi_slave *altspi = to_altera_spi_slave(slave); debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); - writel(0, altspi->base + ALTERA_SPI_CONTROL); - writel(0, altspi->base + ALTERA_SPI_SLAVE_SEL); + writel(0, &altspi->regs->control); + writel(0, &altspi->regs->slave_sel); return 0; } @@ -115,24 +118,22 @@ void spi_release_bus(struct spi_slave *slave) struct altera_spi_slave *altspi = to_altera_spi_slave(slave); debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); - writel(0, altspi->base + ALTERA_SPI_SLAVE_SEL); + writel(0, &altspi->regs->slave_sel); } -#ifndef CONFIG_ALTERA_SPI_IDLE_VAL -# define CONFIG_ALTERA_SPI_IDLE_VAL 0xff -#endif - int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct altera_spi_slave *altspi = to_altera_spi_slave(slave); /* assume spi core configured to do 8 bit transfers */ - uint bytes = bitlen / 8; - const uchar *txp = dout; - uchar *rxp = din; + unsigned int bytes = bitlen / 8; + const unsigned char *txp = dout; + unsigned char *rxp = din; + uint32_t reg, data, start; debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__, - slave->bus, slave->cs, bitlen, bytes, flags); + slave->bus, slave->cs, bitlen, bytes, flags); + if (bitlen == 0) goto done; @@ -142,25 +143,40 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, } /* empty read buffer */ - if (readl(altspi->base + ALTERA_SPI_STATUS) & - ALTERA_SPI_STATUS_RRDY_MSK) - readl(altspi->base + ALTERA_SPI_RXDATA); + if (readl(&altspi->regs->status) & ALTERA_SPI_STATUS_RRDY_MSK) + readl(&altspi->regs->rxdata); + if (flags & SPI_XFER_BEGIN) spi_cs_activate(slave); while (bytes--) { - uchar d = txp ? *txp++ : CONFIG_ALTERA_SPI_IDLE_VAL; - debug("%s: tx:%x ", __func__, d); - writel(d, altspi->base + ALTERA_SPI_TXDATA); - while (!(readl(altspi->base + ALTERA_SPI_STATUS) & - ALTERA_SPI_STATUS_RRDY_MSK)) - ; - d = readl(altspi->base + ALTERA_SPI_RXDATA); + if (txp) + data = *txp++; + else + data = CONFIG_ALTERA_SPI_IDLE_VAL; + + debug("%s: tx:%x ", __func__, data); + writel(data, &altspi->regs->txdata); + + start = get_timer(0); + while (1) { + reg = readl(&altspi->regs->status); + if (reg & ALTERA_SPI_STATUS_RRDY_MSK) + break; + if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { + printf("%s: Transmission timed out!\n", __func__); + goto done; + } + } + + data = readl(&altspi->regs->rxdata); if (rxp) - *rxp++ = d; - debug("rx:%x\n", d); + *rxp++ = data & 0xff; + + debug("rx:%x\n", data); } - done: + +done: if (flags & SPI_XFER_END) spi_cs_deactivate(slave); diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index be102692d4..23f2ba6223 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -49,6 +49,8 @@ struct mxc_spi_slave { #endif int gpio; int ss_pol; + unsigned int max_hz; + unsigned int mode; }; static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave) @@ -83,12 +85,13 @@ u32 get_cspi_div(u32 div) } #ifdef MXC_CSPI -static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs, - unsigned int max_hz, unsigned int mode) +static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs) { unsigned int ctrl_reg; u32 clk_src; u32 div; + unsigned int max_hz = mxcs->max_hz; + unsigned int mode = mxcs->mode; clk_src = mxc_get_clock(MXC_CSPI_CLK); @@ -120,19 +123,15 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs, #endif #ifdef MXC_ECSPI -static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs, - unsigned int max_hz, unsigned int mode) +static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs) { u32 clk_src = mxc_get_clock(MXC_CSPI_CLK); s32 reg_ctrl, reg_config; u32 ss_pol = 0, sclkpol = 0, sclkpha = 0, sclkctl = 0; u32 pre_div = 0, post_div = 0; struct cspi_regs *regs = (struct cspi_regs *)mxcs->base; - - if (max_hz == 0) { - printf("Error: desired clock is 0\n"); - return -1; - } + unsigned int max_hz = mxcs->max_hz; + unsigned int mode = mxcs->mode; /* * Reset SPI and set all CSs to master mode, if toggling @@ -169,9 +168,6 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs, reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_POSTDIV(0x0F)) | MXC_CSPICTRL_POSTDIV(post_div); - /* We need to disable SPI before changing registers */ - reg_ctrl &= ~MXC_CSPICTRL_EN; - if (mode & SPI_CS_HIGH) ss_pol = 1; @@ -412,6 +408,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, if (bus >= ARRAY_SIZE(spi_bases)) return NULL; + if (max_hz == 0) { + printf("Error: desired clock is 0\n"); + return NULL; + } + mxcs = spi_alloc_slave(struct mxc_spi_slave, bus, cs); if (!mxcs) { puts("mxc_spi: SPI Slave not allocated !\n"); @@ -427,13 +428,9 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, } mxcs->base = spi_bases[bus]; + mxcs->max_hz = max_hz; + mxcs->mode = mode; - ret = spi_cfg_mxc(mxcs, cs, max_hz, mode); - if (ret) { - printf("mxc_spi: cannot setup SPI controller\n"); - free(mxcs); - return NULL; - } return &mxcs->slave; } @@ -446,12 +443,17 @@ void spi_free_slave(struct spi_slave *slave) int spi_claim_bus(struct spi_slave *slave) { + int ret; struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave); struct cspi_regs *regs = (struct cspi_regs *)mxcs->base; reg_write(®s->rxdata, 1); udelay(1); - reg_write(®s->ctrl, mxcs->ctrl_reg); + ret = spi_cfg_mxc(mxcs, slave->cs); + if (ret) { + printf("mxc_spi: cannot setup SPI controller\n"); + return ret; + } reg_write(®s->period, MXC_CSPIPERIOD_32KHZ); reg_write(®s->intr, 0); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 936d006ba4..c671c72cb1 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1097,6 +1097,7 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, } struct int_queue { + int elementsize; struct QH *first; struct QH *current; struct QH *last; @@ -1154,6 +1155,23 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, struct int_queue *result = NULL; int i; + /* + * Interrupt transfers requiring several transactions are not supported + * because bInterval is ignored. + * + * Also, ehci_submit_async() relies on wMaxPacketSize being a power of 2 + * <= PKT_ALIGN if several qTDs are required, while the USB + * specification does not constrain this for interrupt transfers. That + * means that ehci_submit_async() would support interrupt transfers + * requiring several transactions only as long as the transfer size does + * not require more than a single qTD. + */ + if (elementsize > usb_maxpacket(dev, pipe)) { + printf("%s: xfers requiring several transactions are not supported.\n", + __func__); + return NULL; + } + debug("Enter create_int_queue\n"); if (usb_pipetype(pipe) != PIPE_INTERRUPT) { debug("non-interrupt pipe (type=%lu)", usb_pipetype(pipe)); @@ -1174,6 +1192,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, debug("ehci intr queue: out of memory\n"); goto fail1; } + result->elementsize = elementsize; result->first = memalign(USB_DMA_MINALIGN, sizeof(struct QH) * queuesize); if (!result->first) { @@ -1249,9 +1268,11 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, ALIGN_END_ADDR(struct qTD, result->tds, queuesize)); - if (disable_periodic(ctrl) < 0) { - debug("FATAL: periodic should never fail, but did"); - goto fail3; + if (ctrl->periodic_schedules > 0) { + if (disable_periodic(ctrl) < 0) { + debug("FATAL: periodic should never fail, but did"); + goto fail3; + } } /* hook up to periodic list */ @@ -1308,13 +1329,18 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) queue->current++; else queue->current = NULL; + + invalidate_dcache_range((uint32_t)cur->buffer, + ALIGN_END_ADDR(char, cur->buffer, + queue->elementsize)); + debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n", hc32_to_cpu(cur_td->qt_token), cur, queue->first); return cur->buffer; } /* Do not free buffers associated with QHs, they're owned by someone else */ -static int +int destroy_int_queue(struct usb_device *dev, struct int_queue *queue) { struct ehci_ctrl *ctrl = dev->controller; @@ -1373,24 +1399,9 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval); - /* - * Interrupt transfers requiring several transactions are not supported - * because bInterval is ignored. - * - * Also, ehci_submit_async() relies on wMaxPacketSize being a power of 2 - * <= PKT_ALIGN if several qTDs are required, while the USB - * specification does not constrain this for interrupt transfers. That - * means that ehci_submit_async() would support interrupt transfers - * requiring several transactions only as long as the transfer size does - * not require more than a single qTD. - */ - if (length > usb_maxpacket(dev, pipe)) { - printf("%s: Interrupt transfers requiring several " - "transactions are not supported.\n", __func__); - return -1; - } - queue = create_int_queue(dev, pipe, 1, length, buffer); + if (!queue) + return -1; timeout = get_timer(0) + USB_TIMEOUT_MS(pipe); while ((backbuffer = poll_int_queue(dev, queue)) == NULL) @@ -1406,9 +1417,6 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, return -EINVAL; } - invalidate_dcache_range((uint32_t)buffer, - ALIGN_END_ADDR(char, buffer, length)); - ret = destroy_int_queue(dev, queue); if (ret < 0) return ret; diff --git a/drivers/usb/host/ehci-rmobile.c b/drivers/usb/host/ehci-rmobile.c index 0d1a726d35..b4330876f8 100644 --- a/drivers/usb/host/ehci-rmobile.c +++ b/drivers/usb/host/ehci-rmobile.c @@ -22,12 +22,8 @@ static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = { 0xEE0A0000, /* USB1 */ 0xEE0C0000, /* USB2 */ }; -#elif defined(CONFIG_R8A7791) -static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = { - 0xEE080000, /* USB0 (EHCI) */ - 0xEE0C0000, /* USB1 */ -}; -#elif defined(CONFIG_R8A7794) +#elif defined(CONFIG_R8A7791) || defined(CONFIG_R8A7793) || \ + defined(CONFIG_R8A7794) static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = { 0xEE080000, /* USB0 (EHCI) */ 0xEE0C0000, /* USB1 */ diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index 69c0336cae..cdccbef1f6 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2003-2005 + * (C) Copyright 2003-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2004-2006 @@ -19,6 +19,8 @@ #define CONFIG_MPC5200 1 /* This is an MPC5200 CPU */ #define CONFIG_TQM5200 1 /* ... on TQM5200 module */ #undef CONFIG_TQM5200_REV100 /* define for revision 100 modules */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO /* * Valid values for CONFIG_SYS_TEXT_BASE are: diff --git a/include/configs/TQM823L.h b/include/configs/TQM823L.h index cc2204586e..0d5a2b96f1 100644 --- a/include/configs/TQM823L.h +++ b/include/configs/TQM823L.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC823 1 /* This is a MPC823 CPU */ #define CONFIG_TQM823L 1 /* ...on a TQM8xxL module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM823M.h b/include/configs/TQM823M.h index 4fd070f27d..e765a03cfb 100644 --- a/include/configs/TQM823M.h +++ b/include/configs/TQM823M.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC823 1 /* This is a MPC823 CPU */ #define CONFIG_TQM823M 1 /* ...on a TQM8xxM module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM850L.h b/include/configs/TQM850L.h index ca3750d407..bbdc3f81fc 100644 --- a/include/configs/TQM850L.h +++ b/include/configs/TQM850L.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC850 1 /* This is a MPC850 CPU */ #define CONFIG_TQM850L 1 /* ...on a TQM8xxL module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM850M.h b/include/configs/TQM850M.h index 659c9ad1c3..5fc87f2138 100644 --- a/include/configs/TQM850M.h +++ b/include/configs/TQM850M.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC850 1 /* This is a MPC850 CPU */ #define CONFIG_TQM850M 1 /* ...on a TQM8xxM module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM855L.h b/include/configs/TQM855L.h index 906d79b0c8..589d168eba 100644 --- a/include/configs/TQM855L.h +++ b/include/configs/TQM855L.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC855 1 /* This is a MPC855 CPU */ #define CONFIG_TQM855L 1 /* ...on a TQM8xxL module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM855M.h b/include/configs/TQM855M.h index 44d456e165..60acb564e8 100644 --- a/include/configs/TQM855M.h +++ b/include/configs/TQM855M.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC855 1 /* This is a MPC855 CPU */ #define CONFIG_TQM855M 1 /* ...on a TQM8xxM module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM860L.h b/include/configs/TQM860L.h index 855b0cddc4..ebc5571632 100644 --- a/include/configs/TQM860L.h +++ b/include/configs/TQM860L.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC860 1 /* This is a MPC860 CPU */ #define CONFIG_TQM860L 1 /* ...on a TQM8xxL module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM860M.h b/include/configs/TQM860M.h index 8109379ae9..f4ce07f20e 100644 --- a/include/configs/TQM860M.h +++ b/include/configs/TQM860M.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC860 1 /* This is a MPC860 CPU */ #define CONFIG_TQM860M 1 /* ...on a TQM8xxM module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM862L.h b/include/configs/TQM862L.h index da4af93d25..97db519d53 100644 --- a/include/configs/TQM862L.h +++ b/include/configs/TQM862L.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -20,6 +20,8 @@ #define CONFIG_MPC860 1 #define CONFIG_MPC860T 1 #define CONFIG_MPC862 1 +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_TQM862L 1 /* ...on a TQM8xxL module */ diff --git a/include/configs/TQM862M.h b/include/configs/TQM862M.h index ec3a57b961..25d60a74ef 100644 --- a/include/configs/TQM862M.h +++ b/include/configs/TQM862M.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -20,6 +20,8 @@ #define CONFIG_MPC860 1 #define CONFIG_MPC860T 1 #define CONFIG_MPC862 1 +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_TQM862M 1 /* ...on a TQM8xxM module */ diff --git a/include/configs/TQM866M.h b/include/configs/TQM866M.h index cb8b84d3a1..928b879609 100644 --- a/include/configs/TQM866M.h +++ b/include/configs/TQM866M.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2008 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +19,8 @@ #define CONFIG_MPC866 1 /* This is a MPC866 CPU */ #define CONFIG_TQM866M 1 /* ...on a TQM8xxM module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM885D.h b/include/configs/TQM885D.h index d1e6c5b2bb..598020c867 100644 --- a/include/configs/TQM885D.h +++ b/include/configs/TQM885D.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2005 + * (C) Copyright 2000-2014 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2006 @@ -22,6 +22,8 @@ #define CONFIG_MPC885 1 /* This is a MPC885 CPU */ #define CONFIG_TQM885D 1 /* ...on a TQM88D module */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index 4b90dc205d..fef267f70b 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -26,6 +26,7 @@ #define CONFIG_PHYSMEM #define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_DISPLAY_BOARDINFO_LATE +#define CONFIG_DISPLAY_CPUINFO #define CONFIG_DM #define CONFIG_CMD_DM @@ -48,6 +49,7 @@ #define CONFIG_FIT #undef CONFIG_ZLIB #undef CONFIG_GZIP +#define CONFIG_SYS_BOOTM_LEN (16 << 20) /*----------------------------------------------------------------------- * Watchdog Configuration @@ -221,7 +223,7 @@ #define CONFIG_SYS_MEMTEST_START 0x00100000 #define CONFIG_SYS_MEMTEST_END 0x01000000 -#define CONFIG_SYS_LOAD_ADDR 0x02000000 +#define CONFIG_SYS_LOAD_ADDR 0x20000000 /*----------------------------------------------------------------------- * SDRAM Configuration diff --git a/include/configs/pb1x00.h b/include/configs/pb1x00.h index f92496571b..1c04a58e9f 100644 --- a/include/configs/pb1x00.h +++ b/include/configs/pb1x00.h @@ -29,8 +29,6 @@ #endif #endif -#define CONFIG_SYS_LITTLE_ENDIAN - #define CONFIG_ETHADDR DE:AD:BE:EF:01:01 /* Ethernet address */ #define CONFIG_BOOTDELAY 2 /* autoboot after 2 seconds */ diff --git a/include/image.h b/include/image.h index a13a30289f..07e9aed16d 100644 --- a/include/image.h +++ b/include/image.h @@ -173,6 +173,7 @@ struct lmb; #define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */ #define IH_ARCH_ARM64 22 /* ARM64 */ #define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */ +#define IH_ARCH_X86_64 24 /* AMD x86_64, Intel and Via */ /* * Image Types diff --git a/include/usb.h b/include/usb.h index c4a288d5e9..9d0d04dd8e 100644 --- a/include/usb.h +++ b/include/usb.h @@ -129,6 +129,8 @@ struct usb_device { unsigned int slot_id; }; +struct int_queue; + /* * You can initialize platform's USB host or device * ports by passing this enum as an argument to @@ -163,6 +165,13 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval); +#ifdef CONFIG_USB_EHCI /* Only the ehci code has pollable int support */ +struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe, + int queuesize, int elementsize, void *buffer); +int destroy_int_queue(struct usb_device *dev, struct int_queue *queue); +void *poll_int_queue(struct usb_device *dev, struct int_queue *queue); +#endif + /* Defines */ #define USB_UHCI_VEND_ID 0x8086 #define USB_UHCI_DEV_ID 0x7112 |