[U-Boot] [PATCH v3 00/10] x86: Add support for samus

This series adds support for samus, the Chromebook Pixel 2015. Since it is only the second board added that does not use an FSP, there is quite a bit of refactoring involved to avoid code duplication.
Samus uses roughly the same binary blobs as link, except now there is one more called the reference code binary. The only available binary for this is a coreboot 'rmodule' extracted from flash. This is a simplified ELF format so it fairly easy to load and use.
It is also possible to boot U-Boot from coreboot on samus. This works well but for a delay for non-existent IDE on start-up. The standard build does not work with binaries taken from flash, so it isn't easy to replicate this - you'll just have to take my word for it. I am working on getting that figured out - coreboot recently gained upstream support for loading U-Boot as a payload, so it should be possible to get this working nicely before long.
In any case much of the code comes from coreboot - individual files are credited with their source.
Perhaps the main value of this series is the improved non-FSP support and additions for broadwell, which samus uses. It should make it easier to add support for future non-FSP platforms.
Changes in v3: - Add more detail to the commit message and code comments - Add new patch top include missing pci.h header in me_common.c - Add new patch top include missing pci.h header in power_state.c - Add source coreboot version information to the commit message - Rename pch_common.c to pch.c
Changes in v2: - Rename sdram to mrc - Rename sdram_common.c to mrc.c
Simon Glass (10): arm: Add a 64-bit division routine to the private library dhry: Correct dhrystone calculation for fast machines x86: Move common PCH code into a common place x86: Add common SDRAM-init code x86: ivybridge: Convert to use the common SDRAM code x86: dts: Drop memory SPD compatible string x86: Support a chained-boot development flow x86: broadwell: Add missing pci.h header in power_state.c x86: Add missing pci.h header in me_common.h x86: Add support for the samus chromebook
arch/arm/lib/Makefile | 3 +- arch/arm/lib/_uldivmod.S | 245 ++++++++++++ arch/x86/cpu/broadwell/power_state.c | 1 + arch/x86/cpu/intel_common/Makefile | 2 + arch/x86/cpu/intel_common/mrc.c | 271 +++++++++++++ arch/x86/cpu/intel_common/pch.c | 25 ++ arch/x86/cpu/ivybridge/cpu.c | 1 + arch/x86/cpu/ivybridge/sata.c | 47 +-- arch/x86/cpu/ivybridge/sdram.c | 394 ++++--------------- arch/x86/cpu/start.S | 80 ++++ arch/x86/dts/Makefile | 1 + arch/x86/dts/chromebook_link.dts | 1 - arch/x86/dts/chromebook_samus.dts | 628 ++++++++++++++++++++++++++++++ arch/x86/include/asm/arch-ivybridge/pch.h | 53 --- arch/x86/include/asm/me_common.h | 1 + arch/x86/include/asm/mrc_common.h | 55 +++ arch/x86/include/asm/pch_common.h | 56 +++ board/google/Kconfig | 13 + board/google/chromebook_samus/Kconfig | 40 ++ board/google/chromebook_samus/MAINTAINERS | 6 + board/google/chromebook_samus/Makefile | 7 + board/google/chromebook_samus/samus.c | 18 + configs/chromebook_samus_defconfig | 51 +++ doc/README.x86 | 81 ++++ include/configs/chromebook_samus.h | 29 ++ include/configs/x86-chromebook.h | 3 +- include/fdtdec.h | 1 - lib/dhry/cmd_dhry.c | 8 +- lib/fdtdec.c | 1 - 29 files changed, 1719 insertions(+), 403 deletions(-) create mode 100644 arch/arm/lib/_uldivmod.S create mode 100644 arch/x86/cpu/intel_common/mrc.c create mode 100644 arch/x86/cpu/intel_common/pch.c create mode 100644 arch/x86/dts/chromebook_samus.dts create mode 100644 arch/x86/include/asm/mrc_common.h create mode 100644 arch/x86/include/asm/pch_common.h create mode 100644 board/google/chromebook_samus/Kconfig create mode 100644 board/google/chromebook_samus/MAINTAINERS create mode 100644 board/google/chromebook_samus/Makefile create mode 100644 board/google/chromebook_samus/samus.c create mode 100644 configs/chromebook_samus_defconfig create mode 100644 include/configs/chromebook_samus.h

This is missing, with causes lldiv() to fail on boards with use the private libgcc. Add the missing routine.
Code is available for using the CLZ instruction but it is not enabled at present.
This comes from coreboot version 4.0.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add source coreboot version information to the commit message
Changes in v2: None
arch/arm/lib/Makefile | 3 +- arch/arm/lib/_uldivmod.S | 245 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 arch/arm/lib/_uldivmod.S
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index f3db7b5..7a0fb58 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -6,7 +6,8 @@ #
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \ - _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o + _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o \ + _uldivmod.o
ifdef CONFIG_CPU_V7M obj-y += vectors_m.o crt0.o diff --git a/arch/arm/lib/_uldivmod.S b/arch/arm/lib/_uldivmod.S new file mode 100644 index 0000000..426c2f2 --- /dev/null +++ b/arch/arm/lib/_uldivmod.S @@ -0,0 +1,245 @@ +/* + * Copyright 2010, Google Inc. + * + * Brought in from coreboot uldivmod.S + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <linux/linkage.h> +#include <asm/assembler.h> + +/* We don't use Thumb instructions for now */ +#define ARM(x...) x +#define THUMB(x...) + +/* + * A, Q = r0 + (r1 << 32) + * B, R = r2 + (r3 << 32) + * A / B = Q ... R + */ + +A_0 .req r0 +A_1 .req r1 +B_0 .req r2 +B_1 .req r3 +C_0 .req r4 +C_1 .req r5 +D_0 .req r6 +D_1 .req r7 + +Q_0 .req r0 +Q_1 .req r1 +R_0 .req r2 +R_1 .req r3 + +THUMB( +TMP .req r8 +) + +ENTRY(__aeabi_uldivmod) + stmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) lr} + @ Test if B == 0 + orrs ip, B_0, B_1 @ Z set -> B == 0 + beq L_div_by_0 + @ Test if B is power of 2: (B & (B - 1)) == 0 + subs C_0, B_0, #1 + sbc C_1, B_1, #0 + tst C_0, B_0 + tsteq B_1, C_1 + beq L_pow2 + @ Test if A_1 == B_1 == 0 + orrs ip, A_1, B_1 + beq L_div_32_32 + +L_div_64_64: +/* CLZ only exists in ARM architecture version 5 and above. */ +#ifdef HAVE_CLZ + mov C_0, #1 + mov C_1, #0 + @ D_0 = clz A + teq A_1, #0 + clz D_0, A_1 + clzeq ip, A_0 + addeq D_0, D_0, ip + @ D_1 = clz B + teq B_1, #0 + clz D_1, B_1 + clzeq ip, B_0 + addeq D_1, D_1, ip + @ if clz B - clz A > 0 + subs D_0, D_1, D_0 + bls L_done_shift + @ B <<= (clz B - clz A) + subs D_1, D_0, #32 + rsb ip, D_0, #32 + movmi B_1, B_1, lsl D_0 +ARM( orrmi B_1, B_1, B_0, lsr ip ) +THUMB( lsrmi TMP, B_0, ip ) +THUMB( orrmi B_1, B_1, TMP ) + movpl B_1, B_0, lsl D_1 + mov B_0, B_0, lsl D_0 + @ C = 1 << (clz B - clz A) + movmi C_1, C_1, lsl D_0 +ARM( orrmi C_1, C_1, C_0, lsr ip ) +THUMB( lsrmi TMP, C_0, ip ) +THUMB( orrmi C_1, C_1, TMP ) + movpl C_1, C_0, lsl D_1 + mov C_0, C_0, lsl D_0 +L_done_shift: + mov D_0, #0 + mov D_1, #0 + @ C: current bit; D: result +#else + @ C: current bit; D: result + mov C_0, #1 + mov C_1, #0 + mov D_0, #0 + mov D_1, #0 +L_lsl_4: + cmp B_1, #0x10000000 + cmpcc B_1, A_1 + cmpeq B_0, A_0 + bcs L_lsl_1 + @ B <<= 4 + mov B_1, B_1, lsl #4 + orr B_1, B_1, B_0, lsr #28 + mov B_0, B_0, lsl #4 + @ C <<= 4 + mov C_1, C_1, lsl #4 + orr C_1, C_1, C_0, lsr #28 + mov C_0, C_0, lsl #4 + b L_lsl_4 +L_lsl_1: + cmp B_1, #0x80000000 + cmpcc B_1, A_1 + cmpeq B_0, A_0 + bcs L_subtract + @ B <<= 1 + mov B_1, B_1, lsl #1 + orr B_1, B_1, B_0, lsr #31 + mov B_0, B_0, lsl #1 + @ C <<= 1 + mov C_1, C_1, lsl #1 + orr C_1, C_1, C_0, lsr #31 + mov C_0, C_0, lsl #1 + b L_lsl_1 +#endif +L_subtract: + @ if A >= B + cmp A_1, B_1 + cmpeq A_0, B_0 + bcc L_update + @ A -= B + subs A_0, A_0, B_0 + sbc A_1, A_1, B_1 + @ D |= C + orr D_0, D_0, C_0 + orr D_1, D_1, C_1 +L_update: + @ if A == 0: break + orrs ip, A_1, A_0 + beq L_exit + @ C >>= 1 + movs C_1, C_1, lsr #1 + movs C_0, C_0, rrx + @ if C == 0: break + orrs ip, C_1, C_0 + beq L_exit + @ B >>= 1 + movs B_1, B_1, lsr #1 + mov B_0, B_0, rrx + b L_subtract +L_exit: + @ Note: A, B & Q, R are aliases + mov R_0, A_0 + mov R_1, A_1 + mov Q_0, D_0 + mov Q_1, D_1 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} + +L_div_32_32: + @ Note: A_0 & r0 are aliases + @ Q_1 r1 + mov r1, B_0 + bl __aeabi_uidivmod + mov R_0, r1 + mov R_1, #0 + mov Q_1, #0 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} + +L_pow2: +#ifdef HAVE_CLZ + @ Note: A, B and Q, R are aliases + @ R = A & (B - 1) + and C_0, A_0, C_0 + and C_1, A_1, C_1 + @ Q = A >> log2(B) + @ Note: B must not be 0 here! + clz D_0, B_0 + add D_1, D_0, #1 + rsbs D_0, D_0, #31 + bpl L_1 + clz D_0, B_1 + rsb D_0, D_0, #31 + mov A_0, A_1, lsr D_0 + add D_0, D_0, #32 +L_1: + movpl A_0, A_0, lsr D_0 +ARM( orrpl A_0, A_0, A_1, lsl D_1 ) +THUMB( lslpl TMP, A_1, D_1 ) +THUMB( orrpl A_0, A_0, TMP ) + mov A_1, A_1, lsr D_0 + @ Mov back C to R + mov R_0, C_0 + mov R_1, C_1 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} +#else + @ Note: A, B and Q, R are aliases + @ R = A & (B - 1) + and C_0, A_0, C_0 + and C_1, A_1, C_1 + @ Q = A >> log2(B) + @ Note: B must not be 0 here! + @ Count the leading zeroes in B. + mov D_0, #0 + orrs B_0, B_0, B_0 + @ If B is greater than 1 << 31, divide A and B by 1 << 32. + moveq A_0, A_1 + moveq A_1, #0 + moveq B_0, B_1 + @ Count the remaining leading zeroes in B. + movs B_1, B_0, lsl #16 + addeq D_0, #16 + moveq B_0, B_0, lsr #16 + tst B_0, #0xff + addeq D_0, #8 + moveq B_0, B_0, lsr #8 + tst B_0, #0xf + addeq D_0, #4 + moveq B_0, B_0, lsr #4 + tst B_0, #0x3 + addeq D_0, #2 + moveq B_0, B_0, lsr #2 + tst B_0, #0x1 + addeq D_0, #1 + @ Shift A to the right by the appropriate amount. + rsb D_1, D_0, #32 + mov Q_0, A_0, lsr D_0 + orr Q_0, A_1, lsl D_1 + mov Q_1, A_1, lsr D_0 + @ Move C to R + mov R_0, C_0 + mov R_1, C_1 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} +#endif + +L_div_by_0: + bl __div0 + @ As wrong as it could be + mov Q_0, #0 + mov Q_1, #0 + mov R_0, #0 + mov R_1, #0 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} +ENDPROC(__aeabi_uldivmod)

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
This is missing, with causes lldiv() to fail on boards with use the private libgcc. Add the missing routine.
Code is available for using the CLZ instruction but it is not enabled at present.
This comes from coreboot version 4.0.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add source coreboot version information to the commit message
Changes in v2: None
arch/arm/lib/Makefile | 3 +- arch/arm/lib/_uldivmod.S | 245 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 arch/arm/lib/_uldivmod.S
applied to u-boot-x86, thanks!

At present samus reports about 5600 DMIPS. With the default iteration count this is OK, but if 10 million runs are performed it overflows. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
lib/dhry/cmd_dhry.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/dhry/cmd_dhry.c b/lib/dhry/cmd_dhry.c index 5dc191e..d7e1e6a 100644 --- a/lib/dhry/cmd_dhry.c +++ b/lib/dhry/cmd_dhry.c @@ -6,11 +6,13 @@
#include <common.h> #include <command.h> +#include <div64.h> #include "dhry.h"
static int do_dhry(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong start, duration, dhry_per_sec, vax_mips; + ulong start, duration, vax_mips; + u64 dhry_per_sec; int iterations = 1000000;
if (argc > 1) @@ -19,10 +21,10 @@ static int do_dhry(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) start = get_timer(0); dhry(iterations); duration = get_timer(start); - dhry_per_sec = iterations * 1000 / duration; + dhry_per_sec = lldiv(iterations * 1000ULL, duration); vax_mips = dhry_per_sec / 1757; printf("%d iterations in %lu ms: %lu/s, %lu DMIPS\n", iterations, - duration, dhry_per_sec, vax_mips); + duration, (ulong)dhry_per_sec, vax_mips);
return 0; }

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
At present samus reports about 5600 DMIPS. With the default iteration count this is OK, but if 10 million runs are performed it overflows. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
lib/dhry/cmd_dhry.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
applied to u-boot-x86, thanks!

The SATA indexed register write functions are common to several Intel PCHs. Move this into a common location.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Rename pch_common.c to pch.c
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/pch.c | 25 ++++++++++++++ arch/x86/cpu/ivybridge/cpu.c | 1 + arch/x86/cpu/ivybridge/sata.c | 47 +++++++++----------------- arch/x86/include/asm/arch-ivybridge/pch.h | 53 ----------------------------- arch/x86/include/asm/pch_common.h | 56 +++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 84 deletions(-) create mode 100644 arch/x86/cpu/intel_common/pch.c create mode 100644 arch/x86/include/asm/pch_common.h
diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index 1918ca3..74b097a 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_HAVE_MRC) += me_status.o ifndef CONFIG_TARGET_EFI obj-y += microcode.o endif +obj-y += pch.o obj-$(CONFIG_HAVE_MRC) += report_platform.o diff --git a/arch/x86/cpu/intel_common/pch.c b/arch/x86/cpu/intel_common/pch.c new file mode 100644 index 0000000..1f05b44 --- /dev/null +++ b/arch/x86/cpu/intel_common/pch.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <asm/pch_common.h> + +u32 pch_common_sir_read(struct udevice *dev, int idx) +{ + u32 data; + + dm_pci_write_config32(dev, SATA_SIRI, idx); + dm_pci_read_config32(dev, SATA_SIRD, &data); + + return data; +} + +void pch_common_sir_write(struct udevice *dev, int idx, u32 value) +{ + dm_pci_write_config32(dev, SATA_SIRI, idx); + dm_pci_write_config32(dev, SATA_SIRD, value); +} diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c index bb720ba..0f93905 100644 --- a/arch/x86/cpu/ivybridge/cpu.c +++ b/arch/x86/cpu/ivybridge/cpu.c @@ -21,6 +21,7 @@ #include <asm/intel_regs.h> #include <asm/io.h> #include <asm/lapic.h> +#include <asm/lpc_common.h> #include <asm/microcode.h> #include <asm/msr.h> #include <asm/mtrr.h> diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c index da6455b..c3d1057 100644 --- a/arch/x86/cpu/ivybridge/sata.c +++ b/arch/x86/cpu/ivybridge/sata.c @@ -9,28 +9,13 @@ #include <dm.h> #include <fdtdec.h> #include <asm/io.h> +#include <asm/pch_common.h> #include <asm/pci.h> #include <asm/arch/pch.h> #include <asm/arch/bd82x6x.h>
DECLARE_GLOBAL_DATA_PTR;
-static inline u32 sir_read(struct udevice *dev, int idx) -{ - u32 data; - - dm_pci_write_config32(dev, SATA_SIRI, idx); - dm_pci_read_config32(dev, SATA_SIRD, &data); - - return data; -} - -static inline void sir_write(struct udevice *dev, int idx, u32 value) -{ - dm_pci_write_config32(dev, SATA_SIRI, idx); - dm_pci_write_config32(dev, SATA_SIRD, value); -} - static void common_sata_init(struct udevice *dev, unsigned int port_map) { u32 reg32; @@ -177,27 +162,27 @@ static void bd82x6x_sata_init(struct udevice *dev, struct udevice *pch) pch_iobp_update(pch, SATA_IOBP_SP1G3IR, 0, port_tx);
/* Additional Programming Requirements */ - sir_write(dev, 0x04, 0x00001600); - sir_write(dev, 0x28, 0xa0000033); - reg32 = sir_read(dev, 0x54); + pch_common_sir_write(dev, 0x04, 0x00001600); + pch_common_sir_write(dev, 0x28, 0xa0000033); + reg32 = pch_common_sir_read(dev, 0x54); reg32 &= 0xff000000; reg32 |= 0x5555aa; - sir_write(dev, 0x54, reg32); - sir_write(dev, 0x64, 0xcccc8484); - reg32 = sir_read(dev, 0x68); + pch_common_sir_write(dev, 0x54, reg32); + pch_common_sir_write(dev, 0x64, 0xcccc8484); + reg32 = pch_common_sir_read(dev, 0x68); reg32 &= 0xffff0000; reg32 |= 0xcccc; - sir_write(dev, 0x68, reg32); - reg32 = sir_read(dev, 0x78); + pch_common_sir_write(dev, 0x68, reg32); + reg32 = pch_common_sir_read(dev, 0x78); reg32 &= 0x0000ffff; reg32 |= 0x88880000; - sir_write(dev, 0x78, reg32); - sir_write(dev, 0x84, 0x001c7000); - sir_write(dev, 0x88, 0x88338822); - sir_write(dev, 0xa0, 0x001c7000); - sir_write(dev, 0xc4, 0x0c0c0c0c); - sir_write(dev, 0xc8, 0x0c0c0c0c); - sir_write(dev, 0xd4, 0x10000000); + pch_common_sir_write(dev, 0x78, reg32); + pch_common_sir_write(dev, 0x84, 0x001c7000); + pch_common_sir_write(dev, 0x88, 0x88338822); + pch_common_sir_write(dev, 0xa0, 0x001c7000); + pch_common_sir_write(dev, 0xc4, 0x0c0c0c0c); + pch_common_sir_write(dev, 0xc8, 0x0c0c0c0c); + pch_common_sir_write(dev, 0xd4, 0x10000000);
pch_iobp_update(pch, 0xea004001, 0x3fffffff, 0xc0000000); pch_iobp_update(pch, 0xea00408a, 0xfffffcff, 0x00000100); diff --git a/arch/x86/include/asm/arch-ivybridge/pch.h b/arch/x86/include/asm/arch-ivybridge/pch.h index e72ff2a..4725250 100644 --- a/arch/x86/include/asm/arch-ivybridge/pch.h +++ b/arch/x86/include/asm/arch-ivybridge/pch.h @@ -69,8 +69,6 @@ #define RTC_POWER_FAILED (1 << 1) #define SLEEP_AFTER_POWER_FAIL (1 << 0)
-#define PMBASE 0x40 -#define ACPI_CNTL 0x44 #define BIOS_CNTL 0xDC #define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ #define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ @@ -99,60 +97,11 @@ #define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ #define GPIO_ROUT 0xb8
-#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ -#define COMB_DEC_RANGE (1 << 4) /* 0x2f8-0x2ff (COM2) */ -#define COMA_DEC_RANGE (0 << 0) /* 0x3f8-0x3ff (COM1) */ -#define LPC_EN 0x82 /* LPC IF Enables Register */ -#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ -#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ -#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */ -#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ -#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ -#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ -#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */ -#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */ -#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */ -#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[3:2] */ -#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ -#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ -#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ -#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ -#define LPC_GENX_DEC(x) (0x84 + 4 * (x)) -#define GEN_DEC_RANGE_256B 0xfc0000 /* 256 Bytes */ -#define GEN_DEC_RANGE_128B 0x7c0000 /* 128 Bytes */ -#define GEN_DEC_RANGE_64B 0x3c0000 /* 64 Bytes */ -#define GEN_DEC_RANGE_32B 0x1c0000 /* 32 Bytes */ -#define GEN_DEC_RANGE_16B 0x0c0000 /* 16 Bytes */ -#define GEN_DEC_RANGE_8B 0x040000 /* 8 Bytes */ -#define GEN_DEC_RANGE_4B 0x000000 /* 4 Bytes */ -#define GEN_DEC_RANGE_EN (1 << 0) /* Range Enable */ - /* PCI Configuration Space (D31:F1): IDE */ #define PCH_IDE_DEV PCI_BDF(0, 0x1f, 1) #define PCH_SATA_DEV PCI_BDF(0, 0x1f, 2) #define PCH_SATA2_DEV PCI_BDF(0, 0x1f, 5)
-#define INTR_LN 0x3c -#define IDE_TIM_PRI 0x40 /* IDE timings, primary */ -#define IDE_DECODE_ENABLE (1 << 15) -#define IDE_SITRE (1 << 14) -#define IDE_ISP_5_CLOCKS (0 << 12) -#define IDE_ISP_4_CLOCKS (1 << 12) -#define IDE_ISP_3_CLOCKS (2 << 12) -#define IDE_RCT_4_CLOCKS (0 << 8) -#define IDE_RCT_3_CLOCKS (1 << 8) -#define IDE_RCT_2_CLOCKS (2 << 8) -#define IDE_RCT_1_CLOCKS (3 << 8) -#define IDE_DTE1 (1 << 7) -#define IDE_PPE1 (1 << 6) -#define IDE_IE1 (1 << 5) -#define IDE_TIME1 (1 << 4) -#define IDE_DTE0 (1 << 3) -#define IDE_PPE0 (1 << 2) -#define IDE_IE0 (1 << 1) -#define IDE_TIME0 (1 << 0) -#define IDE_TIM_SEC 0x42 /* IDE timings, secondary */ - #define IDE_SDMA_CNT 0x48 /* Synchronous DMA control */ #define IDE_SSDE1 (1 << 3) #define IDE_SSDE0 (1 << 2) @@ -337,9 +286,7 @@ (((d) << DIR_IDR) | ((c) << DIR_ICR) | \ ((b) << DIR_IBR) | ((a) << DIR_IAR))
-#define RC 0x3400 /* 32bit */ #define HPTC 0x3404 /* 32bit */ -#define GCS 0x3410 /* 32bit */ #define BUC 0x3414 /* 32bit */ #define PCH_DISABLE_GBE (1 << 5) #define FD 0x3418 /* 32bit */ diff --git a/arch/x86/include/asm/pch_common.h b/arch/x86/include/asm/pch_common.h new file mode 100644 index 0000000..924ccc4 --- /dev/null +++ b/arch/x86/include/asm/pch_common.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __asm_pch_common_h +#define __asm_pch_common_h + +/* Common Intel SATA registers */ +#define SATA_SIRI 0xa0 /* SATA Indexed Register Index */ +#define SATA_SIRD 0xa4 /* SATA Indexed Register Data */ +#define SATA_SP 0xd0 /* Scratchpad */ + +#define INTR_LN 0x3c +#define IDE_TIM_PRI 0x40 /* IDE timings, primary */ +#define IDE_DECODE_ENABLE (1 << 15) +#define IDE_SITRE (1 << 14) +#define IDE_ISP_5_CLOCKS (0 << 12) +#define IDE_ISP_4_CLOCKS (1 << 12) +#define IDE_ISP_3_CLOCKS (2 << 12) +#define IDE_RCT_4_CLOCKS (0 << 8) +#define IDE_RCT_3_CLOCKS (1 << 8) +#define IDE_RCT_2_CLOCKS (2 << 8) +#define IDE_RCT_1_CLOCKS (3 << 8) +#define IDE_DTE1 (1 << 7) +#define IDE_PPE1 (1 << 6) +#define IDE_IE1 (1 << 5) +#define IDE_TIME1 (1 << 4) +#define IDE_DTE0 (1 << 3) +#define IDE_PPE0 (1 << 2) +#define IDE_IE0 (1 << 1) +#define IDE_TIME0 (1 << 0) +#define IDE_TIM_SEC 0x42 /* IDE timings, secondary */ + +#define SERIRQ_CNTL 0x64 + +/** + * pch_common_sir_read() - Read from a SATA indexed register + * + * @dev: SATA device + * @idx: Register index to read + * @return value read from register + */ +u32 pch_common_sir_read(struct udevice *dev, int idx); + +/** + * pch_common_sir_write() - Write to a SATA indexed register + * + * @dev: SATA device + * @idx: Register index to write + * @value: Value to write + */ +void pch_common_sir_write(struct udevice *dev, int idx, u32 value); + +#endif

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
The SATA indexed register write functions are common to several Intel PCHs. Move this into a common location.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Rename pch_common.c to pch.c
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/pch.c | 25 ++++++++++++++ arch/x86/cpu/ivybridge/cpu.c | 1 + arch/x86/cpu/ivybridge/sata.c | 47 +++++++++----------------- arch/x86/include/asm/arch-ivybridge/pch.h | 53 ----------------------------- arch/x86/include/asm/pch_common.h | 56 +++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 84 deletions(-) create mode 100644 arch/x86/cpu/intel_common/pch.c create mode 100644 arch/x86/include/asm/pch_common.h
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Thu, Mar 17, 2016 at 9:38 AM, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
The SATA indexed register write functions are common to several Intel PCHs. Move this into a common location.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Rename pch_common.c to pch.c
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/pch.c | 25 ++++++++++++++ arch/x86/cpu/ivybridge/cpu.c | 1 + arch/x86/cpu/ivybridge/sata.c | 47 +++++++++----------------- arch/x86/include/asm/arch-ivybridge/pch.h | 53 ----------------------------- arch/x86/include/asm/pch_common.h | 56 +++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 84 deletions(-) create mode 100644 arch/x86/cpu/intel_common/pch.c create mode 100644 arch/x86/include/asm/pch_common.h
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

The code to call the memory reference code is common to several Intel CPUs. Add common code for performing this init. Intel calls this 'Pre-EFI-Init' (PEI), where EFI stands for Extensible Firmware Interface.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: - Rename sdram_common.c to mrc.c
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/mrc.c | 271 +++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/mrc_common.h | 55 ++++++++ 3 files changed, 327 insertions(+) create mode 100644 arch/x86/cpu/intel_common/mrc.c create mode 100644 arch/x86/include/asm/mrc_common.h
diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index 74b097a..804c539 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -13,3 +13,4 @@ obj-y += microcode.o endif obj-y += pch.o obj-$(CONFIG_HAVE_MRC) += report_platform.o +obj-$(CONFIG_HAVE_MRC) += mrc.o diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c new file mode 100644 index 0000000..01b6e86 --- /dev/null +++ b/arch/x86/cpu/intel_common/mrc.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <syscon.h> +#include <asm/cpu.h> +#include <asm/gpio.h> +#include <asm/intel_regs.h> +#include <asm/mrc_common.h> +#include <asm/pch_common.h> +#include <asm/post.h> +#include <asm/arch/me.h> +#include <asm/report_platform.h> + +static const char *const ecc_decoder[] = { + "inactive", + "active on IO", + "disabled on IO", + "active" +}; + +ulong mrc_common_board_get_usable_ram_top(ulong total_size) +{ + struct memory_info *info = &gd->arch.meminfo; + uintptr_t dest_addr = 0; + struct memory_area *largest = NULL; + int i; + + /* Find largest area of memory below 4GB */ + + for (i = 0; i < info->num_areas; i++) { + struct memory_area *area = &info->area[i]; + + if (area->start >= 1ULL << 32) + continue; + if (!largest || area->size > largest->size) + largest = area; + } + + /* If no suitable area was found, return an error. */ + assert(largest); + if (!largest || largest->size < (2 << 20)) + panic("No available memory found for relocation"); + + dest_addr = largest->start + largest->size; + + return (ulong)dest_addr; +} + +void mrc_common_dram_init_banksize(void) +{ + struct memory_info *info = &gd->arch.meminfo; + int num_banks; + int i; + + for (i = 0, num_banks = 0; i < info->num_areas; i++) { + struct memory_area *area = &info->area[i]; + + if (area->start >= 1ULL << 32) + continue; + gd->bd->bi_dram[num_banks].start = area->start; + gd->bd->bi_dram[num_banks].size = area->size; + num_banks++; + } +} + +int mrc_add_memory_area(struct memory_info *info, uint64_t start, + uint64_t end) +{ + struct memory_area *ptr; + + if (info->num_areas == CONFIG_NR_DRAM_BANKS) + return -ENOSPC; + + ptr = &info->area[info->num_areas]; + ptr->start = start; + ptr->size = end - start; + info->total_memory += ptr->size; + if (ptr->start < (1ULL << 32)) + info->total_32bit_memory += ptr->size; + debug("%d: memory %llx size %llx, total now %llx / %llx\n", + info->num_areas, ptr->start, ptr->size, + info->total_32bit_memory, info->total_memory); + info->num_areas++; + + return 0; +} + +/* + * Dump in the log memory controller configuration as read from the memory + * controller registers. + */ +void report_memory_config(void) +{ + u32 addr_decoder_common, addr_decode_ch[2]; + int i; + + addr_decoder_common = readl(MCHBAR_REG(0x5000)); + addr_decode_ch[0] = readl(MCHBAR_REG(0x5004)); + addr_decode_ch[1] = readl(MCHBAR_REG(0x5008)); + + debug("memcfg DDR3 clock %d MHz\n", + (readl(MCHBAR_REG(0x5e04)) * 13333 * 2 + 50) / 100); + debug("memcfg channel assignment: A: %d, B % d, C % d\n", + addr_decoder_common & 3, + (addr_decoder_common >> 2) & 3, + (addr_decoder_common >> 4) & 3); + + for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { + u32 ch_conf = addr_decode_ch[i]; + debug("memcfg channel[%d] config (%8.8x):\n", i, ch_conf); + debug(" ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); + debug(" enhanced interleave mode %s\n", + ((ch_conf >> 22) & 1) ? "on" : "off"); + debug(" rank interleave %s\n", + ((ch_conf >> 21) & 1) ? "on" : "off"); + debug(" DIMMA %d MB width x%d %s rank%s\n", + ((ch_conf >> 0) & 0xff) * 256, + ((ch_conf >> 19) & 1) ? 16 : 8, + ((ch_conf >> 17) & 1) ? "dual" : "single", + ((ch_conf >> 16) & 1) ? "" : ", selected"); + debug(" DIMMB %d MB width x%d %s rank%s\n", + ((ch_conf >> 8) & 0xff) * 256, + ((ch_conf >> 20) & 1) ? 16 : 8, + ((ch_conf >> 18) & 1) ? "dual" : "single", + ((ch_conf >> 16) & 1) ? ", selected" : ""); + } +} + +int mrc_locate_spd(struct udevice *dev, int size, const void **spd_datap) +{ + const void *blob = gd->fdt_blob; + int spd_index; + struct gpio_desc desc[4]; + int spd_node; + int node; + int ret; + + ret = gpio_request_list_by_name(dev, "board-id-gpios", desc, + ARRAY_SIZE(desc), GPIOD_IS_IN); + if (ret < 0) { + debug("%s: gpio ret=%d\n", __func__, ret); + return ret; + } + spd_index = dm_gpio_get_values_as_int(desc, ret); + debug("spd index %d\n", spd_index); + + node = fdt_first_subnode(blob, dev->of_offset); + if (node < 0) + return -EINVAL; + for (spd_node = fdt_first_subnode(blob, node); + spd_node > 0; + spd_node = fdt_next_subnode(blob, spd_node)) { + int len; + + if (fdtdec_get_int(blob, spd_node, "reg", -1) != spd_index) + continue; + *spd_datap = fdt_getprop(blob, spd_node, "data", &len); + if (len < size) { + printf("Missing SPD data\n"); + return -EINVAL; + } + + debug("Using SDRAM SPD data for '%s'\n", + fdt_get_name(blob, spd_node, NULL)); + return 0; + } + + printf("No SPD data found for index %d\n", spd_index); + return -ENOENT; +} + +asmlinkage void sdram_console_tx_byte(unsigned char byte) +{ +#ifdef DEBUG + putc(byte); +#endif +} + +/** + * Find the PEI executable in the ROM and execute it. + * + * @me_dev: Management Engine device + * @pei_data: configuration data for UEFI PEI reference code + */ +static int sdram_initialise(struct udevice *dev, struct udevice *me_dev, + void *pei_data, bool use_asm_linkage) +{ + unsigned version; + const char *data; + + report_platform_info(dev); + debug("Starting UEFI PEI System Agent\n"); + + debug("PEI data at %p:\n", pei_data); + + data = (char *)CONFIG_X86_MRC_ADDR; + if (data) { + int rv; + ulong start; + + debug("Calling MRC at %p\n", data); + post_code(POST_PRE_MRC); + start = get_timer(0); + if (use_asm_linkage) { + asmlinkage int (*func)(void *); + + func = (asmlinkage int (*)(void *))data; + rv = func(pei_data); + } else { + int (*func)(void *); + + func = (int (*)(void *))data; + rv = func(pei_data); + } + post_code(POST_MRC); + if (rv) { + switch (rv) { + case -1: + printf("PEI version mismatch.\n"); + break; + case -2: + printf("Invalid memory frequency.\n"); + break; + default: + printf("MRC returned %x.\n", rv); + } + printf("Nonzero MRC return value.\n"); + return -EFAULT; + } + debug("MRC execution time %lu ms\n", get_timer(start)); + } else { + printf("UEFI PEI System Agent not found.\n"); + return -ENOSYS; + } + + version = readl(MCHBAR_REG(MCHBAR_PEI_VERSION)); + debug("System Agent Version %d.%d.%d Build %d\n", + version >> 24 , (version >> 16) & 0xff, + (version >> 8) & 0xff, version & 0xff); + +#if CONFIG_USBDEBUG + /* mrc.bin reconfigures USB, so reinit it to have debug */ + early_usbdebug_init(); +#endif + + return 0; +} + +int mrc_common_init(struct udevice *dev, void *pei_data, bool use_asm_linkage) +{ + struct udevice *me_dev; + int ret; + + ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev); + if (ret) + return ret; + + ret = sdram_initialise(dev, me_dev, pei_data, use_asm_linkage); + if (ret) + return ret; + quick_ram_check(); + post_code(POST_DRAM); + report_memory_config(); + + return 0; +} diff --git a/arch/x86/include/asm/mrc_common.h b/arch/x86/include/asm/mrc_common.h new file mode 100644 index 0000000..cad24f2 --- /dev/null +++ b/arch/x86/include/asm/mrc_common.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_MRC_COMMON_H +#define __ASM_MRC_COMMON_H + +#include <linux/linkage.h> + +/** + * mrc_common_init() - Set up SDRAM + * + * This calls the memory reference code (MRC) to set up SDRAM + * + * @dev: Northbridge device + * @pei_data: Platform-specific data required by the MRC + * @use_asm_linkage: true if the call to MRC requires asmlinkage, false if it + * uses normal U-Boot calling + * @return 0 if OK, -ve on error + */ +int mrc_common_init(struct udevice *dev, void *pei_data, bool use_asm_linkage); + +asmlinkage void sdram_console_tx_byte(unsigned char byte); + +int mrc_locate_spd(struct udevice *dev, int size, const void **spd_datap); + +void report_memory_config(void); + +/** + * mrc_add_memory_area() - Add a new usable memory area to our list + * + * Note: @start and @end must not span the first 4GB boundary + * + * @info: Place to store memory info + * @start: Start of this memory area + * @end: End of this memory area + 1 + */ +int mrc_add_memory_area(struct memory_info *info, uint64_t start, + uint64_t end); + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. + * It overrides the default implementation found elsewhere which simply + * picks the end of ram, wherever that may be. The location of the stack, + * the relocation address, and how far U-Boot is moved by relocation are + * set in the global data structure. + */ +ulong mrc_common_board_get_usable_ram_top(ulong total_size); + +void mrc_common_dram_init_banksize(void); + +#endif

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
The code to call the memory reference code is common to several Intel CPUs. Add common code for performing this init. Intel calls this 'Pre-EFI-Init' (PEI), where EFI stands for Extensible Firmware Interface.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2:
- Rename sdram_common.c to mrc.c
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/mrc.c | 271 +++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/mrc_common.h | 55 ++++++++ 3 files changed, 327 insertions(+) create mode 100644 arch/x86/cpu/intel_common/mrc.c create mode 100644 arch/x86/include/asm/mrc_common.h
applied to u-boot-x86, thanks!

Adjust the existing implementation to use the new common SDRAM init code.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: - Rename sdram to mrc
arch/x86/cpu/ivybridge/sdram.c | 394 +++++++++-------------------------------- 1 file changed, 83 insertions(+), 311 deletions(-)
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index e0296a2..e35e543 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -25,6 +25,7 @@ #include <asm/global_data.h> #include <asm/intel_regs.h> #include <asm/mrccache.h> +#include <asm/mrc_common.h> #include <asm/mtrr.h> #include <asm/pci.h> #include <asm/report_platform.h> @@ -40,57 +41,14 @@ DECLARE_GLOBAL_DATA_PTR; #define CMOS_OFFSET_MRC_SEED_S3 156 #define CMOS_OFFSET_MRC_SEED_CHK 160
-/* - * This function looks for the highest region of memory lower than 4GB which - * has enough space for U-Boot where U-Boot is aligned on a page boundary. - * It overrides the default implementation found elsewhere which simply - * picks the end of ram, wherever that may be. The location of the stack, - * the relocation address, and how far U-Boot is moved by relocation are - * set in the global data structure. - */ ulong board_get_usable_ram_top(ulong total_size) { - struct memory_info *info = &gd->arch.meminfo; - uintptr_t dest_addr = 0; - struct memory_area *largest = NULL; - int i; - - /* Find largest area of memory below 4GB */ - - for (i = 0; i < info->num_areas; i++) { - struct memory_area *area = &info->area[i]; - - if (area->start >= 1ULL << 32) - continue; - if (!largest || area->size > largest->size) - largest = area; - } - - /* If no suitable area was found, return an error. */ - assert(largest); - if (!largest || largest->size < (2 << 20)) - panic("No available memory found for relocation"); - - dest_addr = largest->start + largest->size; - - return (ulong)dest_addr; + return mrc_common_board_get_usable_ram_top(total_size); }
void dram_init_banksize(void) { - struct memory_info *info = &gd->arch.meminfo; - int num_banks; - int i; - - for (i = 0, num_banks = 0; i < info->num_areas; i++) { - struct memory_area *area = &info->area[i]; - - if (area->start >= 1ULL << 32) - continue; - gd->bd->bi_dram[num_banks].start = area->start; - gd->bd->bi_dram[num_banks].size = area->size; - num_banks++; - } + mrc_common_dram_init_banksize(); }
static int read_seed_from_cmos(struct pei_data *pei_data) @@ -217,164 +175,10 @@ int misc_init_r(void) return 0; }
-static const char *const ecc_decoder[] = { - "inactive", - "active on IO", - "disabled on IO", - "active" -}; - -/* - * Dump in the log memory controller configuration as read from the memory - * controller registers. - */ -static void report_memory_config(void) +static void post_system_agent_init(struct udevice *dev, struct udevice *me_dev, + struct pei_data *pei_data) { - u32 addr_decoder_common, addr_decode_ch[2]; - int i; - - addr_decoder_common = readl(MCHBAR_REG(0x5000)); - addr_decode_ch[0] = readl(MCHBAR_REG(0x5004)); - addr_decode_ch[1] = readl(MCHBAR_REG(0x5008)); - - debug("memcfg DDR3 clock %d MHz\n", - (readl(MCHBAR_REG(0x5e04)) * 13333 * 2 + 50) / 100); - debug("memcfg channel assignment: A: %d, B % d, C % d\n", - addr_decoder_common & 3, - (addr_decoder_common >> 2) & 3, - (addr_decoder_common >> 4) & 3); - - for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { - u32 ch_conf = addr_decode_ch[i]; - debug("memcfg channel[%d] config (%8.8x):\n", i, ch_conf); - debug(" ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); - debug(" enhanced interleave mode %s\n", - ((ch_conf >> 22) & 1) ? "on" : "off"); - debug(" rank interleave %s\n", - ((ch_conf >> 21) & 1) ? "on" : "off"); - debug(" DIMMA %d MB width x%d %s rank%s\n", - ((ch_conf >> 0) & 0xff) * 256, - ((ch_conf >> 19) & 1) ? 16 : 8, - ((ch_conf >> 17) & 1) ? "dual" : "single", - ((ch_conf >> 16) & 1) ? "" : ", selected"); - debug(" DIMMB %d MB width x%d %s rank%s\n", - ((ch_conf >> 8) & 0xff) * 256, - ((ch_conf >> 20) & 1) ? 16 : 8, - ((ch_conf >> 18) & 1) ? "dual" : "single", - ((ch_conf >> 16) & 1) ? ", selected" : ""); - } -} - -static void post_system_agent_init(struct pei_data *pei_data) -{ - /* If PCIe init is skipped, set the PEG clock gating */ - if (!pei_data->pcie_init) - setbits_le32(MCHBAR_REG(0x7010), 1); -} - -static asmlinkage void console_tx_byte(unsigned char byte) -{ -#ifdef DEBUG - putc(byte); -#endif -} - -static int recovery_mode_enabled(void) -{ - return false; -} - -/** - * Find the PEI executable in the ROM and execute it. - * - * @dev: Northbridge device - * @pei_data: configuration data for UEFI PEI reference code - */ -int sdram_initialise(struct udevice *dev, struct udevice *me_dev, - struct pei_data *pei_data) -{ - unsigned version; - const char *data; uint16_t done; - int ret; - - report_platform_info(dev); - - /* Wait for ME to be ready */ - ret = intel_early_me_init(me_dev); - if (ret) - return ret; - ret = intel_early_me_uma_size(me_dev); - if (ret < 0) - return ret; - - debug("Starting UEFI PEI System Agent\n"); - - /* - * Do not pass MRC data in for recovery mode boot, - * Always pass it in for S3 resume. - */ - if (!recovery_mode_enabled() || - pei_data->boot_mode == PEI_BOOT_RESUME) { - ret = prepare_mrc_cache(pei_data); - if (ret) - debug("prepare_mrc_cache failed: %d\n", ret); - } - - /* If MRC data is not found we cannot continue S3 resume. */ - if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) { - debug("Giving up in sdram_initialize: No MRC data\n"); - reset_cpu(0); - } - - /* Pass console handler in pei_data */ - pei_data->tx_byte = console_tx_byte; - - debug("PEI data at %p, size %x:\n", pei_data, sizeof(*pei_data)); - - data = (char *)CONFIG_X86_MRC_ADDR; - if (data) { - int rv; - int (*func)(struct pei_data *); - ulong start; - - debug("Calling MRC at %p\n", data); - post_code(POST_PRE_MRC); - start = get_timer(0); - func = (int (*)(struct pei_data *))data; - rv = func(pei_data); - post_code(POST_MRC); - if (rv) { - switch (rv) { - case -1: - printf("PEI version mismatch.\n"); - break; - case -2: - printf("Invalid memory frequency.\n"); - break; - default: - printf("MRC returned %x.\n", rv); - } - printf("Nonzero MRC return value.\n"); - return -EFAULT; - } - debug("MRC execution time %lu ms\n", get_timer(start)); - } else { - printf("UEFI PEI System Agent not found.\n"); - return -ENOSYS; - } - -#if CONFIG_USBDEBUG - /* mrc.bin reconfigures USB, so reinit it to have debug */ - early_usbdebug_init(); -#endif - - version = readl(MCHBAR_REG(0x5034)); - debug("System Agent Version %d.%d.%d Build %d\n", - version >> 24 , (version >> 16) & 0xff, - (version >> 8) & 0xff, version & 0xff); - debug("MRC output data length %#x at %p\n", pei_data->mrc_output_len, - pei_data->mrc_output);
/* * Send ME init done for SandyBridge here. This is done inside the @@ -387,23 +191,14 @@ int sdram_initialise(struct udevice *dev, struct udevice *me_dev, else intel_me_status(me_dev);
- post_system_agent_init(pei_data); - report_memory_config(); - - /* S3 resume: don't save scrambler seed or MRC data */ - if (pei_data->boot_mode != PEI_BOOT_RESUME) { - /* - * This will be copied to SDRAM in reserve_arch(), then written - * to SPI flash in mrccache_save() - */ - gd->arch.mrc_output = (char *)pei_data->mrc_output; - gd->arch.mrc_output_len = pei_data->mrc_output_len; - ret = write_seeds_to_cmos(pei_data); - if (ret) - debug("Failed to write seeds to CMOS: %d\n", ret); - } + /* If PCIe init is skipped, set the PEG clock gating */ + if (!pei_data->pcie_init) + setbits_le32(MCHBAR_REG(0x7010), 1); +}
- return 0; +static int recovery_mode_enabled(void) +{ + return false; }
int reserve_arch(void) @@ -411,87 +206,16 @@ int reserve_arch(void) return mrccache_reserve(); }
-static int copy_spd(struct pei_data *peid) +static int copy_spd(struct udevice *dev, struct pei_data *peid) { - const int gpio_vector[] = {41, 42, 43, 10, -1}; - int spd_index; - const void *blob = gd->fdt_blob; - int node, spd_node; - int ret, i; - - for (i = 0; ; i++) { - if (gpio_vector[i] == -1) - break; - ret = gpio_requestf(gpio_vector[i], "spd_id%d", i); - if (ret) { - debug("%s: Could not request gpio %d\n", __func__, - gpio_vector[i]); - return ret; - } - } - spd_index = gpio_get_values_as_int(gpio_vector); - debug("spd index %d\n", spd_index); - node = fdtdec_next_compatible(blob, 0, COMPAT_MEMORY_SPD); - if (node < 0) { - printf("SPD data not found.\n"); - return -ENOENT; - } - - for (spd_node = fdt_first_subnode(blob, node); - spd_node > 0; - spd_node = fdt_next_subnode(blob, spd_node)) { - const char *data; - int len; - - if (fdtdec_get_int(blob, spd_node, "reg", -1) != spd_index) - continue; - data = fdt_getprop(blob, spd_node, "data", &len); - if (len < sizeof(peid->spd_data[0])) { - printf("Missing SPD data\n"); - return -EINVAL; - } - - debug("Using SDRAM SPD data for '%s'\n", - fdt_get_name(blob, spd_node, NULL)); - memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0])); - break; - } - - if (spd_node < 0) { - printf("No SPD data found for index %d\n", spd_index); - return -ENOENT; - } + const void *data; + int ret;
- return 0; -} + ret = mrc_locate_spd(dev, sizeof(peid->spd_data[0]), &data); + if (ret) + return ret;
-/** - * add_memory_area() - Add a new usable memory area to our list - * - * Note: @start and @end must not span the first 4GB boundary - * - * @info: Place to store memory info - * @start: Start of this memory area - * @end: End of this memory area + 1 - */ -static int add_memory_area(struct memory_info *info, - uint64_t start, uint64_t end) -{ - struct memory_area *ptr; - - if (info->num_areas == CONFIG_NR_DRAM_BANKS) - return -ENOSPC; - - ptr = &info->area[info->num_areas]; - ptr->start = start; - ptr->size = end - start; - info->total_memory += ptr->size; - if (ptr->start < (1ULL << 32)) - info->total_32bit_memory += ptr->size; - debug("%d: memory %llx size %llx, total now %llx / %llx\n", - info->num_areas, ptr->start, ptr->size, - info->total_32bit_memory, info->total_memory); - info->num_areas++; + memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0]));
return 0; } @@ -610,10 +334,10 @@ static int sdram_find(struct udevice *dev) debug("Available memory below 4GB: %lluM\n", tomk >> 10);
/* Report the memory regions */ - add_memory_area(info, 1 << 20, 2 << 28); - add_memory_area(info, (2 << 28) + (2 << 20), 4 << 28); - add_memory_area(info, (4 << 28) + (2 << 20), tseg_base); - add_memory_area(info, 1ULL << 32, touud); + mrc_add_memory_area(info, 1 << 20, 2 << 28); + mrc_add_memory_area(info, (2 << 28) + (2 << 20), 4 << 28); + mrc_add_memory_area(info, (4 << 28) + (2 << 20), tseg_base); + mrc_add_memory_area(info, 1ULL << 32, touud);
/* Add MTRRs for memory */ mtrr_add_request(MTRR_TYPE_WRBACK, 0, 2ULL << 30); @@ -682,7 +406,7 @@ static void rcba_config(void)
int dram_init(void) { - struct pei_data pei_data __aligned(8) = { + struct pei_data _pei_data __aligned(8) = { .pei_version = PEI_VERSION, .mchbar = MCH_BASE_ADDRESS, .dmibar = DEFAULT_DMIBAR, @@ -735,6 +459,7 @@ int dram_init(void) { 0, 4, 0x0000 }, /* P13= Empty */ }, }; + struct pei_data *pei_data = &_pei_data; struct udevice *dev, *me_dev; int ret;
@@ -744,27 +469,74 @@ int dram_init(void) ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev); if (ret) return ret; - debug("Boot mode %d\n", gd->arch.pei_boot_mode); - debug("mrc_input %p\n", pei_data.mrc_input); - pei_data.boot_mode = gd->arch.pei_boot_mode; - ret = copy_spd(&pei_data); - if (!ret) - ret = sdram_initialise(dev, me_dev, &pei_data); + ret = copy_spd(dev, pei_data); if (ret) return ret; + pei_data->boot_mode = gd->arch.pei_boot_mode; + debug("Boot mode %d\n", gd->arch.pei_boot_mode); + debug("mrc_input %p\n", pei_data->mrc_input);
- rcba_config(); - quick_ram_check(); + /* + * Do not pass MRC data in for recovery mode boot, + * Always pass it in for S3 resume. + */ + if (!recovery_mode_enabled() || + pei_data->boot_mode == PEI_BOOT_RESUME) { + ret = prepare_mrc_cache(pei_data); + if (ret) + debug("prepare_mrc_cache failed: %d\n", ret); + }
- writew(0xCAFE, MCHBAR_REG(SSKPD)); + /* If MRC data is not found we cannot continue S3 resume. */ + if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) { + debug("Giving up in sdram_initialize: No MRC data\n"); + reset_cpu(0); + }
- post_code(POST_DRAM); + /* Pass console handler in pei_data */ + pei_data->tx_byte = sdram_console_tx_byte;
- ret = sdram_find(dev); + /* Wait for ME to be ready */ + ret = intel_early_me_init(me_dev); if (ret) return ret; + ret = intel_early_me_uma_size(me_dev); + if (ret < 0) + return ret;
+ ret = mrc_common_init(dev, pei_data, false); + if (ret) + return ret; + + ret = sdram_find(dev); + if (ret) + return ret; gd->ram_size = gd->arch.meminfo.total_32bit_memory;
+ debug("MRC output data length %#x at %p\n", pei_data->mrc_output_len, + pei_data->mrc_output); + + post_system_agent_init(dev, me_dev, pei_data); + report_memory_config(); + + /* S3 resume: don't save scrambler seed or MRC data */ + if (pei_data->boot_mode != PEI_BOOT_RESUME) { + /* + * This will be copied to SDRAM in reserve_arch(), then written + * to SPI flash in mrccache_save() + */ + gd->arch.mrc_output = (char *)pei_data->mrc_output; + gd->arch.mrc_output_len = pei_data->mrc_output_len; + ret = write_seeds_to_cmos(pei_data); + if (ret) + debug("Failed to write seeds to CMOS: %d\n", ret); + } + + writew(0xCAFE, MCHBAR_REG(SSKPD)); + if (ret) + return ret; + + rcba_config(); + return 0; }

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
Adjust the existing implementation to use the new common SDRAM init code.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2:
- Rename sdram to mrc
arch/x86/cpu/ivybridge/sdram.c | 394 +++++++++-------------------------------- 1 file changed, 83 insertions(+), 311 deletions(-)
applied to u-boot-x86, thanks!

This is not needed now that the memory controller driver has the SPD data in its own node.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: None
arch/x86/dts/chromebook_link.dts | 1 - include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 3 files changed, 3 deletions(-)
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index a424f6b..fb1b31d 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -233,7 +233,6 @@ <&gpio_b 11 0>, <&gpio_a 10 0>; u-boot,dm-pre-reloc; spd { - compatible = "memory-spd"; #address-cells = <1>; #size-cells = <0>; elpida_4Gb_1600_x16 { diff --git a/include/fdtdec.h b/include/fdtdec.h index f87b5da..fb88273 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -152,7 +152,6 @@ enum fdt_compat_id { COMPAT_SAMSUNG_EXYNOS5_I2C, /* Exynos5 High Speed I2C Controller */ COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */ COMPAT_INTEL_MICROCODE, /* Intel microcode update */ - COMPAT_MEMORY_SPD, /* Memory SPD information */ COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */ COMPAT_INTEL_MODEL_206AX, /* Intel Model 206AX CPU */ COMPAT_INTEL_GMA, /* Intel Graphics Media Accelerator */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index ddbd1ae..70acc29 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -57,7 +57,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"), COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), COMPAT(INTEL_MICROCODE, "intel,microcode"), - COMPAT(MEMORY_SPD, "memory-spd"), COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"), COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"), COMPAT(INTEL_GMA, "intel,gma"),

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
This is not needed now that the memory controller driver has the SPD data in its own node.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2: None
arch/x86/dts/chromebook_link.dts | 1 - include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 3 files changed, 3 deletions(-)
applied to u-boot-x86, thanks!

Sometimes it is useful to jump into U-Boot directly from coreboot or UEFI without any 16-bit init. This can help during development by allowing U-Boot to avoid doing all the init required by the platform.
U-Boot expects its GDT to be set up correctly by its 16-bit code. If coreboot doesn't do this (because it hasn't run the payload setup code yet) then this won't happen.
In this case we cannot rely on the GDT settings. U-Boot will hang or crash if these are wrong. Provide a development-only option to set up the GDT correctly. This is just a hack so you can jump to U-Boot from any stage of coreboot, not just at the end.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add more detail to the commit message and code comments
Changes in v2: None
arch/x86/cpu/start.S | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+)
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 485868f..a5cba1c 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -18,6 +18,14 @@ #include <generated/generic-asm-offsets.h> #include <generated/asm-offsets.h>
+/* + * Define this to boot U-Boot from a 32-bit program which sets the GDT + * differently. This can be used to boot directly from any stage of coreboot, + * for example, bypassing the normal payload-loading feature. + * This is only useful for development. + */ +#undef LOAD_FROM_32_BIT + .section .text .code32 .globl _start @@ -68,6 +76,10 @@ _start: /* Save table pointer */ movl %ecx, %esi
+#ifdef LOAD_FROM_32_BIT + lgdt gdt_ptr2 +#endif + /* Load the segement registers to match the GDT loaded in start16.S */ movl $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax movw %ax, %fs @@ -220,3 +232,71 @@ multiboot_header: .long 0 /* entry addr */ .long CONFIG_SYS_TEXT_BASE + +#ifdef LOAD_FROM_32_BIT + /* + * The following Global Descriptor Table is just enough to get us into + * 'Flat Protected Mode' - It will be discarded as soon as the final + * GDT is setup in a safe location in RAM + */ +gdt_ptr2: + .word 0x1f /* limit (31 bytes = 4 GDT entries - 1) */ + .long gdt_rom2 /* base */ + + /* Some CPUs are picky about GDT alignment... */ + .align 16 +.globl gdt_rom2 +gdt_rom2: + /* + * The GDT table ... + * + * Selector Type + * 0x00 NULL + * 0x08 Unused + * 0x10 32bit code + * 0x18 32bit data/stack + */ + /* The NULL Desciptor - Mandatory */ + .word 0x0000 /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x00 /* access */ + .byte 0x00 /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* Unused Desciptor - (matches Linux) */ + .word 0x0000 /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x00 /* access */ + .byte 0x00 /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* + * The Code Segment Descriptor: + * - Base = 0x00000000 + * - Size = 4GB + * - Access = Present, Ring 0, Exec (Code), Readable + * - Flags = 4kB Granularity, 32-bit + */ + .word 0xffff /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x9b /* access */ + .byte 0xcf /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* + * The Data Segment Descriptor: + * - Base = 0x00000000 + * - Size = 4GB + * - Access = Present, Ring 0, Non-Exec (Data), Writable + * - Flags = 4kB Granularity, 32-bit + */ + .word 0xffff /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x93 /* access */ + .byte 0xcf /* flags + limit_high */ + .byte 0x00 /* base_high */ +#endif

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
Sometimes it is useful to jump into U-Boot directly from coreboot or UEFI without any 16-bit init. This can help during development by allowing U-Boot to avoid doing all the init required by the platform.
U-Boot expects its GDT to be set up correctly by its 16-bit code. If coreboot doesn't do this (because it hasn't run the payload setup code yet) then this won't happen.
In this case we cannot rely on the GDT settings. U-Boot will hang or crash if these are wrong. Provide a development-only option to set up the GDT correctly. This is just a hack so you can jump to U-Boot from any stage of coreboot, not just at the end.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add more detail to the commit message and code comments
Changes in v2: None
arch/x86/cpu/start.S | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Thu, Mar 17, 2016 at 9:39 AM, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
Sometimes it is useful to jump into U-Boot directly from coreboot or UEFI without any 16-bit init. This can help during development by allowing U-Boot to avoid doing all the init required by the platform.
U-Boot expects its GDT to be set up correctly by its 16-bit code. If coreboot doesn't do this (because it hasn't run the payload setup code yet) then this won't happen.
In this case we cannot rely on the GDT settings. U-Boot will hang or crash if these are wrong. Provide a development-only option to set up the GDT correctly. This is just a hack so you can jump to U-Boot from any stage of coreboot, not just at the end.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add more detail to the commit message and code comments
Changes in v2: None
arch/x86/cpu/start.S | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

This uses PCI so should include the header.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add new patch top include missing pci.h header in power_state.c
Changes in v2: None
arch/x86/cpu/broadwell/power_state.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/cpu/broadwell/power_state.c b/arch/x86/cpu/broadwell/power_state.c index 3380323..2b9a6bf 100644 --- a/arch/x86/cpu/broadwell/power_state.c +++ b/arch/x86/cpu/broadwell/power_state.c @@ -7,6 +7,7 @@ */
#include <common.h> +#include <pci.h> #include <asm/io.h> #include <asm/intel_regs.h> #include <asm/arch/iomap.h>

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
This uses PCI so should include the header.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch top include missing pci.h header in power_state.c
Changes in v2: None
arch/x86/cpu/broadwell/power_state.c | 1 + 1 file changed, 1 insertion(+)
Squashed into http://patchwork.ozlabs.org/patch/596623/, and applied to u-boot-x86, thanks!

This uses PCI so should include the header.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add new patch top include missing pci.h header in me_common.c
Changes in v2: None
arch/x86/include/asm/me_common.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/include/asm/me_common.h b/arch/x86/include/asm/me_common.h index 7089117..2e2251c 100644 --- a/arch/x86/include/asm/me_common.h +++ b/arch/x86/include/asm/me_common.h @@ -15,6 +15,7 @@
#include <linux/compiler.h> #include <linux/types.h> +#include <pci.h>
#define MCHBAR_PEI_VERSION 0x5034

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
This uses PCI so should include the header.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch top include missing pci.h header in me_common.c
Changes in v2: None
arch/x86/include/asm/me_common.h | 1 + 1 file changed, 1 insertion(+)
Squashed into http://patchwork.ozlabs.org/patch/596594/, and applied to u-boot-x86, thanks!

This adds basic support for chromebook_samus. This is the 2015 Pixel and is based on an Intel broadwell platform.
Supported so far are: - Serial - SPI flash - SDRAM init (with MRC cache) - SATA - Video (on the internal LCD panel) - Keyboard
Various less-visible drivers are provided to make the above work (e.g. PCH, power control and LPC).
The platform requires various binary blobs which are documented in the README. The major missing feature is USB3 since the existing U-Boot support does not work correctly with Intel XHCI controllers.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: None
arch/x86/dts/Makefile | 1 + arch/x86/dts/chromebook_samus.dts | 628 ++++++++++++++++++++++++++++++ board/google/Kconfig | 13 + board/google/chromebook_samus/Kconfig | 40 ++ board/google/chromebook_samus/MAINTAINERS | 6 + board/google/chromebook_samus/Makefile | 7 + board/google/chromebook_samus/samus.c | 18 + configs/chromebook_samus_defconfig | 51 +++ doc/README.x86 | 81 ++++ include/configs/chromebook_samus.h | 29 ++ include/configs/x86-chromebook.h | 3 +- 11 files changed, 876 insertions(+), 1 deletion(-) create mode 100644 arch/x86/dts/chromebook_samus.dts create mode 100644 board/google/chromebook_samus/Kconfig create mode 100644 board/google/chromebook_samus/MAINTAINERS create mode 100644 board/google/chromebook_samus/Makefile create mode 100644 board/google/chromebook_samus/samus.c create mode 100644 configs/chromebook_samus_defconfig create mode 100644 include/configs/chromebook_samus.h
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 84feb19..fcfce95 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -5,6 +5,7 @@ dtb-y += bayleybay.dtb \ chromebook_link.dtb \ chromebox_panther.dtb \ + chromebook_samus.dtb \ cougarcanyon2.dtb \ crownbay.dtb \ efi.dtb \ diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts new file mode 100644 index 0000000..5dd3e57 --- /dev/null +++ b/arch/x86/dts/chromebook_samus.dts @@ -0,0 +1,628 @@ +/dts-v1/; + +#include <dt-bindings/gpio/x86-gpio.h> + +/include/ "skeleton.dtsi" +/include/ "keyboard.dtsi" +/include/ "serial.dtsi" +/include/ "rtc.dtsi" +/include/ "tsc_timer.dtsi" + +/ { + model = "Google Samus"; + compatible = "google,samus", "intel,broadwell"; + + aliases { + spi0 = &spi; + usb0 = &usb_0; + usb1 = &usb_1; + }; + + config { + silent_console = <0>; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <0>; + intel,apic-id = <0>; + intel,slow-ramp = <3>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <1>; + intel,apic-id = <1>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <2>; + intel,apic-id = <2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <3>; + intel,apic-id = <3>; + }; + + }; + + chosen { + stdout-path = "/serial"; + }; + + keyboard { + intel,duplicate-por; + }; + + pch_pinctrl { + compatible = "intel,x86-broadwell-pinctrl"; + u-boot,dm-pre-reloc; + reg = <0 0>; + + /* Put this first: it is the default */ + gpio_unused: gpio-unused { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + sense-disable; + }; + + gpio_acpi_sci: acpi-sci { + mode-gpio; + direction = <PIN_INPUT>; + invert; + route = <ROUTE_SCI>; + }; + + gpio_acpi_smi: acpi-smi { + mode-gpio; + direction = <PIN_INPUT>; + invert; + route = <ROUTE_SMI>; + }; + + gpio_input: gpio-input { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + }; + + gpio_input_invert: gpio-input-invert { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + invert; + }; + + gpio_native: gpio-native { + }; + + gpio_out_high: gpio-out-high { + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <1>; + owner = <OWNER_GPIO>; + sense-disable; + }; + + gpio_out_low: gpio-out-low { + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <0>; + owner = <OWNER_GPIO>; + sense-disable; + }; + + gpio_pirq: gpio-pirq { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + pirq-apic = <PIRQ_APIC_ROUTE>; + }; + + soc_gpio@0 { + config = + <0 &gpio_unused 0>, /* unused */ + <1 &gpio_unused 0>, /* unused */ + <2 &gpio_unused 0>, /* unused */ + <3 &gpio_unused 0>, /* unused */ + <4 &gpio_native 0>, /* native: i2c0_sda_gpio4 */ + <5 &gpio_native 0>, /* native: i2c0_scl_gpio5 */ + <6 &gpio_native 0>, /* native: i2c1_sda_gpio6 */ + <7 &gpio_native 0>, /* native: i2c1_scl_gpio7 */ + <8 &gpio_acpi_sci 0>, /* pch_lte_wake_l */ + <9 &gpio_input_invert 0>, /* trackpad_int_l (wake) */ + <10 &gpio_acpi_sci 0>, /* pch_wlan_wake_l */ + <11 &gpio_unused 0>, /* unused */ + <12 &gpio_unused 0>, /* unused */ + <13 &gpio_pirq 3>, /* trackpad_int_l (pirql) */ + <14 &gpio_pirq 4>, /* touch_int_l (pirqm) */ + <15 &gpio_unused 0>, /* unused (strap) */ + <16 &gpio_input 0>, /* pch_wp */ + <17 &gpio_unused 0>, /* unused */ + <18 &gpio_unused 0>, /* unused */ + <19 &gpio_unused 0>, /* unused */ + <20 &gpio_native 0>, /* pcie_wlan_clkreq_l */ + <21 &gpio_out_high 0>, /* pp3300_ssd_en */ + <22 &gpio_unused 0>, /* unused */ + <23 &gpio_out_low 0>, /* pp3300_autobahn_en */ + <24 &gpio_unused 0>, /* unused */ + <25 &gpio_input 0>, /* ec_in_rw */ + <26 &gpio_unused 0>, /* unused */ + <27 &gpio_acpi_sci 0>, /* pch_wake_l */ + <28 &gpio_unused 0>, /* unused */ + <29 &gpio_unused 0>, /* unused */ + <30 &gpio_native 0>, /* native: pch_suswarn_l */ + <31 &gpio_native 0>, /* native: acok_buf */ + <32 &gpio_native 0>, /* native: lpc_clkrun_l */ + <33 &gpio_native 0>, /* native: ssd_devslp */ + <34 &gpio_acpi_smi 0>, /* ec_smi_l */ + <35 &gpio_acpi_smi 0>, /* pch_nmi_dbg_l (route in nmi_en) */ + <36 &gpio_acpi_sci 0>, /* ec_sci_l */ + <37 &gpio_unused 0>, /* unused */ + <38 &gpio_unused 0>, /* unused */ + <39 &gpio_unused 0>, /* unused */ + <40 &gpio_native 0>, /* native: pch_usb1_oc_l */ + <41 &gpio_native 0>, /* native: pch_usb2_oc_l */ + <42 &gpio_unused 0>, /* wlan_disable_l */ + <43 &gpio_out_high 0>, /* pp1800_codec_en */ + <44 &gpio_unused 0>, /* unused */ + <45 &gpio_acpi_sci 0>, /* dsp_int - codec wake */ + <46 &gpio_pirq 6>, /* hotword_det_l_3v3 (pirqo) - codec irq */ + <47 &gpio_out_low 0>, /* ssd_reset_l */ + <48 &gpio_unused 0>, /* unused */ + <49 &gpio_unused 0>, /* unused */ + <50 &gpio_unused 0>, /* unused */ + <51 &gpio_unused 0>, /* unused */ + <52 &gpio_input 0>, /* sim_det */ + <53 &gpio_unused 0>, /* unused */ + <54 &gpio_unused 0>, /* unused */ + <55 &gpio_unused 0>, /* unused */ + <56 &gpio_unused 0>, /* unused */ + <57 &gpio_out_high 0>, /* codec_reset_l */ + <58 &gpio_unused 0>, /* unused */ + <59 &gpio_out_high 0>, /* lte_disable_l */ + <60 &gpio_unused 0>, /* unused */ + <61 &gpio_native 0>, /* native: pch_sus_stat */ + <62 &gpio_native 0>, /* native: pch_susclk */ + <63 &gpio_native 0>, /* native: pch_slp_s5_l */ + <64 &gpio_unused 0>, /* unused */ + <65 &gpio_input 0>, /* ram_id3 */ + <66 &gpio_input 0>, /* ram_id3_old (strap) */ + <67 &gpio_input 0>, /* ram_id0 */ + <68 &gpio_input 0>, /* ram_id1 */ + <69 &gpio_input 0>, /* ram_id2 */ + <70 &gpio_unused 0>, /* unused */ + <71 &gpio_native 0>, /* native: modphy_en */ + <72 &gpio_unused 0>, /* unused */ + <73 &gpio_unused 0>, /* unused */ + <74 &gpio_unused 0>, /* unused */ + <75 &gpio_unused 0>, /* unused */ + <76 &gpio_unused 0>, /* unused */ + <77 &gpio_unused 0>, /* unused */ + <78 &gpio_unused 0>, /* unused */ + <79 &gpio_unused 0>, /* unused */ + <80 &gpio_unused 0>, /* unused */ + <81 &gpio_unused 0>, /* unused */ + <82 &gpio_native 0>, /* native: ec_rcin_l */ + <83 &gpio_native 0>, /* gspi0_cs */ + <84 &gpio_native 0>, /* gspi0_clk */ + <85 &gpio_native 0>, /* gspi0_miso */ + <86 &gpio_native 0>, /* gspi0_mosi (strap) */ + <87 &gpio_unused 0>, /* unused */ + <88 &gpio_unused 0>, /* unused */ + <89 &gpio_out_high 0>, /* pp3300_sd_en */ + <90 &gpio_unused 0>, /* unused */ + <91 &gpio_unused 0>, /* unused */ + <92 &gpio_unused 0>, /* unused */ + <93 &gpio_unused 0>, /* unused */ + <94 &gpio_unused 0>; /* unused */ + }; + }; + + pci { + compatible = "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xe0000000 0xe0000000 0 0x10000000 + 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000 + 0x01000000 0x0 0x1000 0x1000 0 0xefff>; + + northbridge@0,0 { + reg = <0x00000000 0 0 0 0>; + compatible = "intel,broadwell-northbridge"; + board-id-gpios = <&gpio_c 5 0>, <&gpio_c 4 0>, + <&gpio_c 3 0>, <&gpio_c 1 0>; + u-boot,dm-pre-reloc; + spd { + #address-cells = <1>; + #size-cells = <0>; + samsung_4 { + reg = <6>; + data = [91 20 f1 03 04 11 05 0b + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 11 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ce 01 + 00 00 55 00 00 00 00 00 + 4b 34 45 38 45 33 30 34 + 45 44 2d 45 47 43 45 20 + 20 20 00 00 80 ce 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + hynix-h9ccnnnbltmlar-ntm-lpddr3-32 { + /* + * banks 8, ranks 2, rows 14, + * columns 10, density 4096 mb, x32 + */ + reg = <8>; + data = [91 20 f1 03 04 11 05 0b + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ad 00 + 00 00 55 00 00 00 00 00 + 48 39 43 43 4e 4e 4e 42 + 4c 54 4d 4c 41 52 2d 4e + 54 4d 00 00 80 ad 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + samsung_8 { + reg = <10>; + data = [91 20 f1 03 04 12 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 11 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ce 01 + 00 00 55 00 00 00 00 00 + 4b 34 45 36 45 33 30 34 + 45 44 2d 45 47 43 45 20 + 20 20 00 00 80 ce 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + hynix-h9ccnnnbltmlar-ntm-lpddr3-16 { + /* + * banks 8, ranks 2, rows 14, + * columns 11, density 4096 mb, x16 + */ + reg = <12>; + data = [91 20 f1 03 04 12 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ad 00 + 00 00 55 00 00 00 00 00 + 48 39 43 43 4e 4e 4e 42 + 4c 54 4d 4c 41 52 2d 4e + 54 4d 00 00 80 ad 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + hynix-h9ccnnncltmlar-lpddr3 { + /* + * banks 8, ranks 2, rows 15, + * columns 11, density 8192 mb, x16 + */ + reg = <13>; + data = [91 20 f1 03 05 1a 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 90 06 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ad 00 + 00 00 55 00 00 00 00 00 + 48 39 43 43 4e 4e 4e 43 + 4c 54 4d 4c 41 52 00 00 + 00 00 00 00 80 ad 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + elpida-edfb232a1ma { + /* + * banks 8, ranks 2, rows 15, + * columns 11, density 8192 mb, x16 + */ + reg = <15>; + data = [91 20 f1 03 05 1a 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 90 06 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 02 fe 00 + 00 00 00 00 00 00 00 00 + 45 44 46 42 32 33 32 41 + 31 4d 41 2d 47 44 2d 46 + 00 00 00 00 02 fe 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + }; + }; + + gma@2,0 { + reg = <0x00001000 0 0 0 0>; + compatible = "intel,broadwell-igd"; + intel,dp-hotplug = <6 6 6>; + intel,port-select = <1>; /* eDP */ + intel,power-cycle-delay = <6>; + intel,power-up-delay = <2000>; + intel,power-down-delay = <500>; + intel,power-backlight-on-delay = <2000>; + intel,power-backlight-off-delay = <2000>; + intel,cpu-backlight = <0x00000200>; + intel,pch-backlight = <0x04000200>; + intel,pre-graphics-delay = <200>; + }; + + me@16,0 { + reg = <0x0000b000 0 0 0 0>; + compatible = "intel,me"; + u-boot,dm-pre-reloc; + }; + + usb_1: usb@14,0 { + reg = <0x0000a000 0 0 0 0>; + compatible = "xhci-pci"; + }; + + usb_0: usb@1d,0 { + status = "disabled"; + reg = <0x0000e800 0 0 0 0>; + compatible = "ehci-pci"; + }; + + pch@1f,0 { + reg = <0x0000f800 0 0 0 0>; + compatible = "intel,broadwell-pch"; + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + intel,pirq-routing = <0x8b 0x8a 0x8b 0x8b + 0x80 0x80 0x80 0x80>; + intel,gpi-routing = <0 0 0 0 0 0 0 2 + 1 0 0 0 0 0 0 0>; + /* Enable EC SMI source */ + intel,alt-gp-smi-enable = <0x0040>; + + /* EC-SCI is GPIO36 */ + intel,gpe0-en = <0 0x10 0 0>; + + power-enable-gpio = <&gpio_a 23 0>; + + spi: spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich9-spi"; + spi-flash@0 { + #size-cells = <1>; + #address-cells = <1>; + reg = <0>; + compatible = "winbond,w25q64", + "spi-flash"; + memory-map = <0xff800000 0x00800000>; + rw-mrc-cache { + label = "rw-mrc-cache"; + reg = <0x003e0000 0x00010000>; + }; + }; + }; + + gpio_a: gpioa { + compatible = "intel,broadwell-gpio"; + u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; + reg = <0 0>; + bank-name = "A"; + }; + + gpio_b: gpiob { + compatible = "intel,broadwell-gpio"; + u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; + reg = <1 0>; + bank-name = "B"; + }; + + gpio_c: gpioc { + compatible = "intel,broadwell-gpio"; + u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; + reg = <2 0>; + bank-name = "C"; + }; + + lpc { + compatible = "intel,broadwell-lpc"; + #address-cells = <1>; + #size-cells = <0>; + u-boot,dm-pre-reloc; + intel,gen-dec = <0x800 0xfc 0x900 0xfc>; + cros-ec@200 { + compatible = "google,cros-ec-lpc"; + reg = <0x204 1 0x200 1 0x880 0x80>; + + /* + * Describes the flash memory within + * the EC + */ + #address-cells = <1>; + #size-cells = <1>; + flash@8000000 { + reg = <0x08000000 0x20000>; + erase-value = <0xff>; + }; + }; + }; + }; + + sata@1f,2 { + compatible = "intel,wildcatpoint-ahci"; + reg = <0x0000fa00 0 0 0 0>; + u-boot,dm-pre-reloc; + intel,sata-mode = "ahci"; + intel,sata-port-map = <1>; + intel,sata-port0-gen3-tx = <0x72>; + reset-gpio = <&gpio_b 15 GPIO_ACTIVE_LOW>; + }; + + smbus: smbus@1f,3 { + compatible = "intel,ich-i2c"; + reg = <0x0000fb00 0 0 0 0>; + u-boot,dm-pre-reloc; + }; + }; + + tpm { + reg = <0xfed40000 0x5000>; + compatible = "infineon,slb9635lpc"; + }; + + microcode { + update@0 { +#include "microcode/mc0306d4_00000018.dtsi" + }; + }; + +}; diff --git a/board/google/Kconfig b/board/google/Kconfig index e9559c9..7ba73a2 100644 --- a/board/google/Kconfig +++ b/board/google/Kconfig @@ -36,9 +36,22 @@ config TARGET_CHROMEBOX_PANTHER video output and a 16GB SATA solid state drive. There is no Chrome OS EC on this model.
+config TARGET_CHROMEBOOK_SAMUS + bool "Chromebook samus" + help + This is the Chromebook Pixel released in 2015. It uses an Intel + Broadwell U Core i5 or Core i7 CPU with either 8GB or 16GB of + LPDDR3 SDRAM. It has PCIe WiFi and Bluetooth. It also includes a + 720p webcam, USB SD reader, microphone and speakers, 2 USB 3 Type + C ports which can support charging and up to a 4K external display. + There is a solid state drive, either 32GB or 64GB. There is a + Chrome OS EC connected on LPC, and it provides a 2560x1700 high + resolution touch-enabled LCD display. + endchoice
source "board/google/chromebook_link/Kconfig" source "board/google/chromebox_panther/Kconfig" +source "board/google/chromebook_samus/Kconfig"
endif diff --git a/board/google/chromebook_samus/Kconfig b/board/google/chromebook_samus/Kconfig new file mode 100644 index 0000000..f2b9481 --- /dev/null +++ b/board/google/chromebook_samus/Kconfig @@ -0,0 +1,40 @@ +if TARGET_CHROMEBOOK_SAMUS + +config SYS_BOARD + default "chromebook_samus" + +config SYS_VENDOR + default "google" + +config SYS_SOC + default "broadwell" + +config SYS_CONFIG_NAME + default "chromebook_samus" + +config SYS_TEXT_BASE + default 0xffe00000 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select X86_RESET_VECTOR + select INTEL_BROADWELL + select HAVE_INTEL_ME + select BOARD_ROMSIZE_KB_8192 + +config PCIE_ECAM_BASE + default 0xf0000000 + +config EARLY_POST_CROS_EC + bool "Enable early post to Chrome OS EC" + default y + +config SYS_CAR_ADDR + hex + default 0xff7c0000 + +config SYS_CAR_SIZE + hex + default 0x40000 + +endif diff --git a/board/google/chromebook_samus/MAINTAINERS b/board/google/chromebook_samus/MAINTAINERS new file mode 100644 index 0000000..5500e46 --- /dev/null +++ b/board/google/chromebook_samus/MAINTAINERS @@ -0,0 +1,6 @@ +CHROMEBOOK SAMUS BOARD +M: Simon Glass sjg@chromium.org +S: Maintained +F: board/google/chromebook_samus/ +F: include/configs/chromebook_samus.h +F: configs/chromebook_samus_defconfig diff --git a/board/google/chromebook_samus/Makefile b/board/google/chromebook_samus/Makefile new file mode 100644 index 0000000..1522286 --- /dev/null +++ b/board/google/chromebook_samus/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (c) 2016 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += samus.o diff --git a/board/google/chromebook_samus/samus.c b/board/google/chromebook_samus/samus.c new file mode 100644 index 0000000..3c3f5d4 --- /dev/null +++ b/board/google/chromebook_samus/samus.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/cpu.h> + +int arch_early_init_r(void) +{ + return cpu_run_reference_code(); +} + +int board_early_init_f(void) +{ + return 0; +} diff --git a/configs/chromebook_samus_defconfig b/configs/chromebook_samus_defconfig new file mode 100644 index 0000000..448446d --- /dev/null +++ b/configs/chromebook_samus_defconfig @@ -0,0 +1,51 @@ +CONFIG_X86=y +CONFIG_SYS_MALLOC_F_LEN=0x1800 +CONFIG_VENDOR_GOOGLE=y +CONFIG_DEFAULT_DEVICE_TREE="chromebook_samus" +CONFIG_TARGET_CHROMEBOOK_SAMUS=y +CONFIG_ENABLE_MRC_CACHE=y +CONFIG_HAVE_MRC=y +CONFIG_HAVE_REFCODE=y +CONFIG_SMP=y +CONFIG_HAVE_VGA_BIOS=y +CONFIG_CMD_CPU=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NFS is not set +CONFIG_BOOTSTAGE=y +CONFIG_BOOTSTAGE_REPORT=y +CONFIG_CMD_BOOTSTAGE=y +CONFIG_CMD_TPM=y +CONFIG_CMD_TPM_TEST=y +CONFIG_OF_CONTROL=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CPU=y +CONFIG_INTEL_BROADWELL_GPIO=y +CONFIG_CMD_CROS_EC=y +CONFIG_CROS_EC=y +CONFIG_CROS_EC_LPC=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_DM_PCI=y +CONFIG_DM_RTC=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0x3f8 +CONFIG_DEBUG_UART_CLOCK=1843200 +CONFIG_DEBUG_UART_BOARD_INIT=y +CONFIG_SYS_NS16550=y +CONFIG_ICH_SPI=y +CONFIG_TIMER=y +CONFIG_TPM_TIS_LPC=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_DM_VIDEO=y +CONFIG_FRAMEBUFFER_SET_VESA_MODE=y +CONFIG_FRAMEBUFFER_VESA_MODE_11A=y +CONFIG_VIDEO_BROADWELL_IGD=y +CONFIG_USE_PRIVATE_LIBGCC=y +CONFIG_TPM=y diff --git a/doc/README.x86 b/doc/README.x86 index 5b51559..c5c3010 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -105,6 +105,87 @@ $ make all
---
+Chromebook Samus (2015 Pixel) instructions for bare mode: + +First, you need the following binary blobs: + +* descriptor.bin - Intel flash descriptor +* me.bin - Intel Management Engine +* mrc.bin - Memory Reference Code, which sets up SDRAM +* refcode.elf - Additional Reference code +* vga.bin - video ROM, which sets up the display + +If you have a samus you can obtain them from your flash, for example, in +developer mode on the Chromebook (use Ctrl-Alt-F2 to obtain a terminal and +log in as 'root'): + + cd /tmp + flashrom -w samus.bin + scp samus.bin username@ip_address:/path/to/somewhere + +If not see the coreboot tree [4] where you can use: + + bash crosfirmware.sh samus + +to get the image. There is also an 'extract_blobs.sh' scripts that you can use +on the 'coreboot-Google_Samus.*' file to short-circuit some of the below. + +Then 'ifdtool -x samus.bin' on your development machine will produce: + + flashregion_0_flashdescriptor.bin + flashregion_1_bios.bin + flashregion_2_intel_me.bin + +Rename flashregion_0_flashdescriptor.bin to descriptor.bin +Rename flashregion_2_intel_me.bin to me.bin +You can ignore flashregion_1_bios.bin - it is not used. + +To get the rest, use 'cbfstool samus.bin print': + +samus.bin: 8192 kB, bootblocksize 2864, romsize 8388608, offset 0x700000 +alignment: 64 bytes, architecture: x86 + +Name Offset Type Size +cmos_layout.bin 0x700000 cmos_layout 1164 +pci8086,0406.rom 0x7004c0 optionrom 65536 +spd.bin 0x710500 (unknown) 4096 +cpu_microcode_blob.bin 0x711540 microcode 70720 +fallback/romstage 0x722a00 stage 54210 +fallback/ramstage 0x72fe00 stage 96382 +config 0x7476c0 raw 6075 +fallback/vboot 0x748ec0 stage 15980 +fallback/refcode 0x74cd80 stage 75578 +fallback/payload 0x75f500 payload 62878 +u-boot.dtb 0x76eb00 (unknown) 5318 +(empty) 0x770000 null 196504 +mrc.bin 0x79ffc0 (unknown) 222876 +(empty) 0x7d66c0 null 167320 + +You can extract what you need: + + cbfstool samus.bin extract -n pci8086,0406.rom -f vga.bin + cbfstool samus.bin extract -n fallback/refcode -f refcode.rmod + cbfstool samus.bin extract -n mrc.bin -f mrc.bin + cbfstool samus.bin extract -n fallback/refcode -f refcode.bin -U + +Note that the -U flag is only supported by the latest cbfstool. It unpacks +and decompresses the stage to produce a coreboot rmodule. This is a simple +representation of an ELF file. You need the patch "Support decoding a stage +with compression". + +Put all 5 files into board/google/chromebook_samus. + +Now you can build U-Boot and obtain u-boot.rom: + +$ make chromebook_link_defconfig +$ make all + +If you are using em100, then this command will flash write -Boot: + + em100 -s -d filename.rom -c W25Q64CV -r + +--- + Intel Crown Bay specific instructions for bare mode:
U-Boot support of Intel Crown Bay board [4] relies on a binary blob called diff --git a/include/configs/chromebook_samus.h b/include/configs/chromebook_samus.h new file mode 100644 index 0000000..b89ba41 --- /dev/null +++ b/include/configs/chromebook_samus.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2008 + * Graeme Russ, graeme.russ@gmail.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <configs/x86-common.h> +#include <configs/x86-chromebook.h> + +#undef CONFIG_CFB_CONSOLE + +#undef CONFIG_STD_DEVICES_SETTINGS +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,i8042-kbd,serial\0" \ + "stdout=vidconsole,serial\0" \ + "stderr=vidconsole,serial\0" + +#define CONFIG_ENV_SECT_SIZE 0x1000 +#define CONFIG_ENV_OFFSET 0x003f8000 + +#endif /* __CONFIG_H */ diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h index c94096a..312987e 100644 --- a/include/configs/x86-chromebook.h +++ b/include/configs/x86-chromebook.h @@ -21,7 +21,8 @@ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE}, \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6}, \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}, \ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_AHCI} + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_AHCI}, \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_AHCI}
#define CONFIG_PCI_MEM_BUS 0xe0000000 #define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS

On Wed, Mar 16, 2016 at 9:44 PM, Simon Glass sjg@chromium.org wrote:
This adds basic support for chromebook_samus. This is the 2015 Pixel and is based on an Intel broadwell platform.
Supported so far are:
- Serial
- SPI flash
- SDRAM init (with MRC cache)
- SATA
- Video (on the internal LCD panel)
- Keyboard
Various less-visible drivers are provided to make the above work (e.g. PCH, power control and LPC).
The platform requires various binary blobs which are documented in the README. The major missing feature is USB3 since the existing U-Boot support does not work correctly with Intel XHCI controllers.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2: None
arch/x86/dts/Makefile | 1 + arch/x86/dts/chromebook_samus.dts | 628 ++++++++++++++++++++++++++++++ board/google/Kconfig | 13 + board/google/chromebook_samus/Kconfig | 40 ++ board/google/chromebook_samus/MAINTAINERS | 6 + board/google/chromebook_samus/Makefile | 7 + board/google/chromebook_samus/samus.c | 18 + configs/chromebook_samus_defconfig | 51 +++ doc/README.x86 | 81 ++++ include/configs/chromebook_samus.h | 29 ++ include/configs/x86-chromebook.h | 3 +- 11 files changed, 876 insertions(+), 1 deletion(-) create mode 100644 arch/x86/dts/chromebook_samus.dts create mode 100644 board/google/chromebook_samus/Kconfig create mode 100644 board/google/chromebook_samus/MAINTAINERS create mode 100644 board/google/chromebook_samus/Makefile create mode 100644 board/google/chromebook_samus/samus.c create mode 100644 configs/chromebook_samus_defconfig create mode 100644 include/configs/chromebook_samus.h
applied to u-boot-x86, thanks!
participants (2)
-
Bin Meng
-
Simon Glass