Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6932
-gerrit
commit 539407250a1326ffd36561edc53b44fd1c6ebdfa
Author: Julius Werner <jwerner(a)chromium.org>
Date: Wed Jan 15 14:13:25 2014 -0800
arm: Fix up new cache flush algorithm and replace dcache_*_all() with it
This patch fixes the remaining few bugs in our shiny new cache iteration
by set/way/level algorithm to actually make it work: It makes it start
from cache level 0 (previously it would always start at LoC and be
"done" instantly), fixes up the two shifts that isolate the set bits at
the end (which didn't seem to account for the fact that the first shift
affects the second), and throws an S bit on that last shift so that it
actually affects the conditionals after it.
In addition, also moves the next_level block to the top so that we can
share (and thus eliminate) some code at initialization, and turns the
whole thing into a thrice-instantiated macro to create functions that
fit our existing interface.
Change-Id: I1338a589cbb37d74ea6e7a3d4f67ff827e24edbe
Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/183879
Reviewed-by: Stefan Reinauer <reinauer(a)google.com>
Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
(cherry picked from commit 6d94f8330191c316fe093ddb5288329453da8a4b)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
payloads/libpayload/arch/arm/Makefile.inc | 2 +-
payloads/libpayload/arch/arm/cache.c | 125 ------------------------------
payloads/libpayload/arch/arm/cpu.S | 117 ++++++++++++++++++++++++++++
src/arch/arm/armv7/Makefile.inc | 3 +
src/arch/arm/armv7/cache.c | 125 ------------------------------
src/arch/arm/armv7/cpu.S | 72 ++++++++++-------
6 files changed, 166 insertions(+), 278 deletions(-)
diff --git a/payloads/libpayload/arch/arm/Makefile.inc b/payloads/libpayload/arch/arm/Makefile.inc
index 590bf50..2f8da15 100644
--- a/payloads/libpayload/arch/arm/Makefile.inc
+++ b/payloads/libpayload/arch/arm/Makefile.inc
@@ -36,7 +36,7 @@ libc-y += timer.c coreboot.c util.S
libc-y += virtual.c
libc-y += memcpy.S memset.S memmove.S
libc-y += exception_asm.S exception.c
-libc-y += cache.c
+libc-y += cache.c cpu.S
libcbfs-$(CONFIG_LP_CBFS) += dummy_media.c
# Add other classes here when you put assembly files into them!
diff --git a/payloads/libpayload/arch/arm/cache.c b/payloads/libpayload/arch/arm/cache.c
index 4c222ea..defe640 100644
--- a/payloads/libpayload/arch/arm/cache.c
+++ b/payloads/libpayload/arch/arm/cache.c
@@ -36,21 +36,6 @@
#include <arch/cache.h>
#include <arch/virtual.h>
-#define bitmask(high, low) ((1UL << (high)) + \
- ((1UL << (high)) - 1) - ((1UL << (low)) - 1))
-
-/* Basic log2() implementation. Note: log2(0) is 0 for our purposes. */
-/* FIXME: src/include/lib.h is difficult to work with due to romcc */
-static unsigned long log2(unsigned long u)
-{
- int i = 0;
-
- while (u >>= 1)
- i++;
-
- return i;
-}
-
void tlb_invalidate_all(void)
{
/*
@@ -85,116 +70,6 @@ enum dcache_op {
OP_DCIMVAC,
};
-/*
- * Do a dcache operation on entire cache by set/way. This is done for
- * portability because mapping of memory address to cache location is
- * implementation defined (See note on "Requirements for operations by
- * set/way" in arch ref. manual).
- */
-static void dcache_op_set_way(enum dcache_op op)
-{
- uint32_t ccsidr;
- unsigned int associativity, num_sets, linesize_bytes;
- unsigned int set, way;
- unsigned int level;
-
- level = (read_csselr() >> 1) & 0x7;
-
- /*
- * dcache must be invalidated by set/way for portability since virtual
- * memory mapping is system-defined. The number of sets and
- * associativity is given by CCSIDR. We'll use DCISW to invalidate the
- * dcache.
- */
- ccsidr = read_ccsidr();
-
- /* FIXME: rounding up required here? */
- num_sets = ((ccsidr & bitmask(27, 13)) >> 13) + 1;
- associativity = ((ccsidr & bitmask(12, 3)) >> 3) + 1;
- /* FIXME: do we need to use CTR.DminLine here? */
- linesize_bytes = (1 << ((ccsidr & 0x7) + 2)) * 4;
-
- dsb();
-
- /*
- * Set/way operations require an interesting bit packing. See section
- * B4-35 in the ARMv7 Architecture Reference Manual:
- *
- * A: Log2(associativity)
- * B: L+S
- * L: Log2(linesize)
- * S: Log2(num_sets)
- *
- * The bits are packed as follows:
- * 31 31-A B B-1 L L-1 4 3 1 0
- * |---|-------------|--------|-------|-----|-|
- * |Way| zeros | Set | zeros |level|0|
- * |---|-------------|--------|-------|-----|-|
- */
- for (way = 0; way < associativity; way++) {
- for (set = 0; set < num_sets; set++) {
- uint32_t val = 0;
- val |= way << (32 - log2(associativity));
- val |= set << log2(linesize_bytes);
- val |= level << 1;
- switch(op) {
- case OP_DCCISW:
- dccisw(val);
- break;
- case OP_DCISW:
- dcisw(val);
- break;
- case OP_DCCSW:
- dccsw(val);
- break;
- default:
- break;
- }
- }
- }
- isb();
-}
-
-static void dcache_foreach(enum dcache_op op)
-{
- uint32_t clidr;
- int level;
-
- clidr = read_clidr();
- for (level = 0; level < 7; level++) {
- unsigned int ctype = (clidr >> (level * 3)) & 0x7;
- uint32_t csselr;
-
- switch(ctype) {
- case 0x2:
- case 0x3:
- case 0x4:
- csselr = level << 1;
- write_csselr(csselr);
- dcache_op_set_way(op);
- break;
- default:
- /* no cache, icache only, or reserved */
- break;
- }
- }
-}
-
-void dcache_clean_all(void)
-{
- dcache_foreach(OP_DCCSW);
-}
-
-void dcache_clean_invalidate_all(void)
-{
- dcache_foreach(OP_DCCISW);
-}
-
-void dcache_invalidate_all(void)
-{
- dcache_foreach(OP_DCISW);
-}
-
unsigned int dcache_line_bytes(void)
{
uint32_t ccsidr;
diff --git a/payloads/libpayload/arch/arm/cpu.S b/payloads/libpayload/arch/arm/cpu.S
new file mode 100644
index 0000000..29a19e7
--- /dev/null
+++ b/payloads/libpayload/arch/arm/cpu.S
@@ -0,0 +1,117 @@
+/*
+ * Optimized assembly for low-level CPU operations on ARMv7 processors.
+ *
+ * Cache flushing code based off sys/arch/arm/arm/cpufunc_asm_armv7.S in NetBSD
+ *
+ * Copyright (c) 2010 Per Odlund <per.odlund(a)armagedon.se>
+ * Copyright (c) 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <arch/asm.h>
+
+/*
+ * Dcache invalidations by set/way work by passing a [way:sbz:set:sbz:level:0]
+ * bitfield in a register to the appropriate MCR instruction. This algorithm
+ * works by initializing a bitfield with the highest-numbered set and way, and
+ * generating a "set decrement" and a "way decrement". The former just contains
+ * the LSB of the set field, but the latter contains the LSB of the way field
+ * minus the highest valid set field... such that when you subtract it from a
+ * [way:0:level] field you end up with a [way - 1:highest_set:level] field
+ * through the magic of double subtraction. It's quite ingenius, really.
+ * Takes care to only use r0-r3 and ip so it's pefectly ABI-compatible without
+ * needing to write to memory.
+ */
+
+.macro dcache_apply_all crm
+ dsb
+ mov r3, #-2 @ initialize level so that we start at 0
+
+1: @next_level
+ add r3, r3, #2 @ increment level
+
+ mrc p15, 1, r0, c0, c0, 1 @ read CLIDR
+ and ip, r0, #0x07000000 @ narrow to LoC
+ lsr ip, ip, #23 @ left align LoC (low 4 bits)
+ cmp r3, ip @ compare
+ bge 3f @done @ else fall through (r0 == CLIDR)
+
+ add r2, r3, r3, lsr #1 @ r2 = (level << 1) * 3 / 2
+ mov r1, r0, lsr r2 @ r1 = cache type
+ bfc r1, #3, #28
+ cmp r1, #2 @ is it data or i&d?
+ blt 1b @next_level @ nope, skip level
+
+ mcr p15, 2, r3, c0, c0, 0 @ select cache level
+ isb
+ mrc p15, 1, r0, c0, c0, 0 @ read CCSIDR
+
+ ubfx ip, r0, #0, #3 @ get linesize from CCSIDR
+ add ip, ip, #4 @ apply bias
+ ubfx r2, r0, #13, #15 @ get numsets - 1 from CCSIDR
+ lsl r2, r2, ip @ shift to set position
+ orr r3, r3, r2 @ merge set into way/set/level
+ mov r1, #1
+ lsl r1, r1, ip @ r1 = set decr
+
+ ubfx ip, r0, #3, #10 @ get numways - 1 from [to be discarded] CCSIDR
+ clz r2, ip @ number of bits to MSB of way
+ lsl ip, ip, r2 @ shift by that into way position
+ mov r0, #1
+ lsl r2, r0, r2 @ r2 now contains the way decr
+ mov r0, r3 @ get sets/level (no way yet)
+ orr r3, r3, ip @ merge way into way/set/level
+ bfc r0, #0, #4 @ clear low 4 bits (level) to get numset - 1
+ sub r2, r2, r0 @ subtract from way decr
+
+ /* r3 = ways/sets/level, r2 = way decr, r1 = set decr, r0 and ip are free */
+2: mcr p15, 0, r3, c7, \crm, 2 @ writeback and/or invalidate line
+ cmp r3, #15 @ are we done with this level (way/set == 0)
+ bls 1b @next_level @ yes, go to next level
+ lsr r0, r3, #4 @ clear level bits leaving only way/set bits
+ lsls r0, r0, #14 @ clear way bits leaving only set bits
+ subne r3, r3, r1 @ non-zero?, decrement set #
+ subeq r3, r3, r2 @ zero?, decrement way # and restore set count
+ b 2b
+
+3: @done
+ mov r0, #0 @ default back to cache level 0
+ mcr p15, 2, r0, c0, c0, 0 @ select cache level
+ dsb
+ isb
+ bx lr
+.endm
+
+ENTRY(dcache_invalidate_all)
+ dcache_apply_all crm=c6
+ENDPROC(dcache_invalidate_all)
+
+ENTRY(dcache_clean_all)
+ dcache_apply_all crm=c10
+ENDPROC(dcache_clean_all)
+
+ENTRY(dcache_clean_invalidate_all)
+ dcache_apply_all crm=c14
+ENDPROC(dcache_clean_invalidate_all)
diff --git a/src/arch/arm/armv7/Makefile.inc b/src/arch/arm/armv7/Makefile.inc
index 62e687b..b03879a 100644
--- a/src/arch/arm/armv7/Makefile.inc
+++ b/src/arch/arm/armv7/Makefile.inc
@@ -36,6 +36,7 @@ bootblock-$(CONFIG_BOOTBLOCK_SIMPLE) += bootblock_simple.c
endif
bootblock-y += cache.c
+bootblock-y += cpu.S
bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += exception.c
bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += exception_asm.S
bootblock-y += mmu.c
@@ -52,6 +53,7 @@ endif # CONFIG_ARCH_BOOTBLOCK_ARMV7
ifeq ($(CONFIG_ARCH_ROMSTAGE_ARMV7),y)
romstage-y += cache.c
+romstage-y += cpu.S
romstage-y += exception.c
romstage-y += exception_asm.S
romstage-y += mmu.c
@@ -68,6 +70,7 @@ endif # CONFIG_ARCH_ROMSTAGE_ARMV7
ifeq ($(CONFIG_ARCH_RAMSTAGE_ARMV7),y)
ramstage-y += cache.c
+ramstage-y += cpu.S
ramstage-y += exception.c
ramstage-y += exception_asm.S
ramstage-y += mmu.c
diff --git a/src/arch/arm/armv7/cache.c b/src/arch/arm/armv7/cache.c
index 4ee2687..7db86c8 100644
--- a/src/arch/arm/armv7/cache.c
+++ b/src/arch/arm/armv7/cache.c
@@ -35,21 +35,6 @@
#include <arch/cache.h>
-#define bitmask(high, low) ((1UL << (high)) + \
- ((1UL << (high)) - 1) - ((1UL << (low)) - 1))
-
-/* Basic log2() implementation. Note: log2(0) is 0 for our purposes. */
-/* FIXME: src/include/lib.h is difficult to work with due to romcc */
-static unsigned long log2(unsigned long u)
-{
- int i = 0;
-
- while (u >>= 1)
- i++;
-
- return i;
-}
-
void tlb_invalidate_all(void)
{
/*
@@ -84,116 +69,6 @@ enum dcache_op {
OP_DCIMVAC,
};
-/*
- * Do a dcache operation on entire cache by set/way. This is done for
- * portability because mapping of memory address to cache location is
- * implementation defined (See note on "Requirements for operations by
- * set/way" in arch ref. manual).
- */
-static void dcache_op_set_way(enum dcache_op op)
-{
- uint32_t ccsidr;
- unsigned int associativity, num_sets, linesize_bytes;
- unsigned int set, way;
- unsigned int level;
-
- level = (read_csselr() >> 1) & 0x7;
-
- /*
- * dcache must be invalidated by set/way for portability since virtual
- * memory mapping is system-defined. The number of sets and
- * associativity is given by CCSIDR. We'll use DCISW to invalidate the
- * dcache.
- */
- ccsidr = read_ccsidr();
-
- /* FIXME: rounding up required here? */
- num_sets = ((ccsidr & bitmask(27, 13)) >> 13) + 1;
- associativity = ((ccsidr & bitmask(12, 3)) >> 3) + 1;
- /* FIXME: do we need to use CTR.DminLine here? */
- linesize_bytes = (1 << ((ccsidr & 0x7) + 2)) * 4;
-
- dsb();
-
- /*
- * Set/way operations require an interesting bit packing. See section
- * B4-35 in the ARMv7 Architecture Reference Manual:
- *
- * A: Log2(associativity)
- * B: L+S
- * L: Log2(linesize)
- * S: Log2(num_sets)
- *
- * The bits are packed as follows:
- * 31 31-A B B-1 L L-1 4 3 1 0
- * |---|-------------|--------|-------|-----|-|
- * |Way| zeros | Set | zeros |level|0|
- * |---|-------------|--------|-------|-----|-|
- */
- for (way = 0; way < associativity; way++) {
- for (set = 0; set < num_sets; set++) {
- uint32_t val = 0;
- val |= way << (32 - log2(associativity));
- val |= set << log2(linesize_bytes);
- val |= level << 1;
- switch(op) {
- case OP_DCCISW:
- dccisw(val);
- break;
- case OP_DCISW:
- dcisw(val);
- break;
- case OP_DCCSW:
- dccsw(val);
- break;
- default:
- break;
- }
- }
- }
- isb();
-}
-
-static void dcache_foreach(enum dcache_op op)
-{
- uint32_t clidr;
- int level;
-
- clidr = read_clidr();
- for (level = 0; level < 7; level++) {
- unsigned int ctype = (clidr >> (level * 3)) & 0x7;
- uint32_t csselr;
-
- switch(ctype) {
- case 0x2:
- case 0x3:
- case 0x4:
- csselr = level << 1;
- write_csselr(csselr);
- dcache_op_set_way(op);
- break;
- default:
- /* no cache, icache only, or reserved */
- break;
- }
- }
-}
-
-void dcache_clean_all(void)
-{
- dcache_foreach(OP_DCCSW);
-}
-
-void dcache_clean_invalidate_all(void)
-{
- dcache_foreach(OP_DCCISW);
-}
-
-void dcache_invalidate_all(void)
-{
- dcache_foreach(OP_DCISW);
-}
-
unsigned int dcache_line_bytes(void)
{
uint32_t ccsidr;
diff --git a/src/arch/arm/armv7/cpu.S b/src/arch/arm/armv7/cpu.S
index 42e2354..29a19e7 100644
--- a/src/arch/arm/armv7/cpu.S
+++ b/src/arch/arm/armv7/cpu.S
@@ -30,25 +30,39 @@
* SUCH DAMAGE.
*/
+#include <arch/asm.h>
+
/*
- * These work very hard to not push registers onto the stack and to limit themselves
- * to use r0-r3 and ip.
+ * Dcache invalidations by set/way work by passing a [way:sbz:set:sbz:level:0]
+ * bitfield in a register to the appropriate MCR instruction. This algorithm
+ * works by initializing a bitfield with the highest-numbered set and way, and
+ * generating a "set decrement" and a "way decrement". The former just contains
+ * the LSB of the set field, but the latter contains the LSB of the way field
+ * minus the highest valid set field... such that when you subtract it from a
+ * [way:0:level] field you end up with a [way - 1:highest_set:level] field
+ * through the magic of double subtraction. It's quite ingenius, really.
+ * Takes care to only use r0-r3 and ip so it's pefectly ABI-compatible without
+ * needing to write to memory.
*/
-/* * LINTSTUB: void armv7_dcache_wbinv_all(void); */
-ENTRY_NP(armv7_dcache_wbinv_all)
+.macro dcache_apply_all crm
+ dsb
+ mov r3, #-2 @ initialize level so that we start at 0
+
+1: @next_level
+ add r3, r3, #2 @ increment level
+
mrc p15, 1, r0, c0, c0, 1 @ read CLIDR
- ands r3, r0, #0x07000000
- beq .Ldone_wbinv
- lsr r3, r3, #23 @ left align loc (low 4 bits)
+ and ip, r0, #0x07000000 @ narrow to LoC
+ lsr ip, ip, #23 @ left align LoC (low 4 bits)
+ cmp r3, ip @ compare
+ bge 3f @done @ else fall through (r0 == CLIDR)
- mov r1, #0
-.Lstart_wbinv:
- add r2, r3, r3, lsr #1 @ r2 = level * 3 / 2
+ add r2, r3, r3, lsr #1 @ r2 = (level << 1) * 3 / 2
mov r1, r0, lsr r2 @ r1 = cache type
bfc r1, #3, #28
cmp r1, #2 @ is it data or i&d?
- blt .Lnext_level_wbinv @ nope, skip level
+ blt 1b @next_level @ nope, skip level
mcr p15, 2, r3, c0, c0, 0 @ select cache level
isb
@@ -65,7 +79,7 @@ ENTRY_NP(armv7_dcache_wbinv_all)
ubfx ip, r0, #3, #10 @ get numways - 1 from [to be discarded] CCSIDR
clz r2, ip @ number of bits to MSB of way
lsl ip, ip, r2 @ shift by that into way position
- mov r0, #1 @
+ mov r0, #1
lsl r2, r0, r2 @ r2 now contains the way decr
mov r0, r3 @ get sets/level (no way yet)
orr r3, r3, ip @ merge way into way/set/level
@@ -73,27 +87,31 @@ ENTRY_NP(armv7_dcache_wbinv_all)
sub r2, r2, r0 @ subtract from way decr
/* r3 = ways/sets/level, r2 = way decr, r1 = set decr, r0 and ip are free */
-1: mcr p15, 0, r3, c7, c14, 2 @ writeback and invalidate line
+2: mcr p15, 0, r3, c7, \crm, 2 @ writeback and/or invalidate line
cmp r3, #15 @ are we done with this level (way/set == 0)
- bls .Lnext_level_wbinv @ yes, go to next level
- lsl r0, r3, #10 @ clear way bits leaving only set/level bits
- lsr r0, r0, #4 @ clear level bits leaving only set bits
+ bls 1b @next_level @ yes, go to next level
+ lsr r0, r3, #4 @ clear level bits leaving only way/set bits
+ lsls r0, r0, #14 @ clear way bits leaving only set bits
subne r3, r3, r1 @ non-zero?, decrement set #
subeq r3, r3, r2 @ zero?, decrement way # and restore set count
- b 1b
+ b 2b
-.Lnext_level_wbinv:
- mrc p15, 1, r0, c0, c0, 1 @ read CLIDR
- and ip, r0, #0x07000000 @ narrow to LoC
- lsr ip, ip, #23 @ left align LoC (low 4 bits)
- add r3, r3, #2 @ go to next level
- cmp r3, ip @ compare
- blt .Lstart_wbinv @ not done, next level (r0 == CLIDR)
-
-.Ldone_wbinv:
+3: @done
mov r0, #0 @ default back to cache level 0
mcr p15, 2, r0, c0, c0, 0 @ select cache level
dsb
isb
bx lr
-END(armv7_dcache_wbinv_all)
+.endm
+
+ENTRY(dcache_invalidate_all)
+ dcache_apply_all crm=c6
+ENDPROC(dcache_invalidate_all)
+
+ENTRY(dcache_clean_all)
+ dcache_apply_all crm=c10
+ENDPROC(dcache_clean_all)
+
+ENTRY(dcache_clean_invalidate_all)
+ dcache_apply_all crm=c14
+ENDPROC(dcache_clean_invalidate_all)
Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6931
-gerrit
commit 4bbab45c25d944203bc801e59aadb287fd303fcd
Author: Julius Werner <jwerner(a)chromium.org>
Date: Mon Jan 13 11:13:23 2014 -0800
arm: Import armv7_dcache_wbinv_all function from NetBSD
This patch pulls in NetBSD's full cache flushing algorithm for ARM, to
replace our old, slow and slightly overzealous C-only implementation.
It's a beautiful piece of code that manages to run on only caller-saved
registers (meaning it doesn't need to write to memory) in a very tight
loop, and it's BSD-licensed to boot (which we need for libpayload).
Unfortunately it's also not quite correct, but I can fix that. Pulling
the original in a separate commit to make it more obvious what changes
are mine.
Change-Id: I7a71c9e570866a6e25f756cb09ae2b6445048d83
Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/183878
Reviewed-by: Stefan Reinauer <reinauer(a)google.com>
Reviewed-by: Vincent Palatin <vpalatin(a)chromium.org>
Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
(cherry picked from commit 4698467320613d7ddc39714f40aacbc990af9399)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
src/arch/arm/armv7/cpu.S | 99 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/src/arch/arm/armv7/cpu.S b/src/arch/arm/armv7/cpu.S
new file mode 100644
index 0000000..42e2354
--- /dev/null
+++ b/src/arch/arm/armv7/cpu.S
@@ -0,0 +1,99 @@
+/*
+ * Optimized assembly for low-level CPU operations on ARMv7 processors.
+ *
+ * Cache flushing code based off sys/arch/arm/arm/cpufunc_asm_armv7.S in NetBSD
+ *
+ * Copyright (c) 2010 Per Odlund <per.odlund(a)armagedon.se>
+ * Copyright (c) 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * These work very hard to not push registers onto the stack and to limit themselves
+ * to use r0-r3 and ip.
+ */
+
+/* * LINTSTUB: void armv7_dcache_wbinv_all(void); */
+ENTRY_NP(armv7_dcache_wbinv_all)
+ mrc p15, 1, r0, c0, c0, 1 @ read CLIDR
+ ands r3, r0, #0x07000000
+ beq .Ldone_wbinv
+ lsr r3, r3, #23 @ left align loc (low 4 bits)
+
+ mov r1, #0
+.Lstart_wbinv:
+ add r2, r3, r3, lsr #1 @ r2 = level * 3 / 2
+ mov r1, r0, lsr r2 @ r1 = cache type
+ bfc r1, #3, #28
+ cmp r1, #2 @ is it data or i&d?
+ blt .Lnext_level_wbinv @ nope, skip level
+
+ mcr p15, 2, r3, c0, c0, 0 @ select cache level
+ isb
+ mrc p15, 1, r0, c0, c0, 0 @ read CCSIDR
+
+ ubfx ip, r0, #0, #3 @ get linesize from CCSIDR
+ add ip, ip, #4 @ apply bias
+ ubfx r2, r0, #13, #15 @ get numsets - 1 from CCSIDR
+ lsl r2, r2, ip @ shift to set position
+ orr r3, r3, r2 @ merge set into way/set/level
+ mov r1, #1
+ lsl r1, r1, ip @ r1 = set decr
+
+ ubfx ip, r0, #3, #10 @ get numways - 1 from [to be discarded] CCSIDR
+ clz r2, ip @ number of bits to MSB of way
+ lsl ip, ip, r2 @ shift by that into way position
+ mov r0, #1 @
+ lsl r2, r0, r2 @ r2 now contains the way decr
+ mov r0, r3 @ get sets/level (no way yet)
+ orr r3, r3, ip @ merge way into way/set/level
+ bfc r0, #0, #4 @ clear low 4 bits (level) to get numset - 1
+ sub r2, r2, r0 @ subtract from way decr
+
+ /* r3 = ways/sets/level, r2 = way decr, r1 = set decr, r0 and ip are free */
+1: mcr p15, 0, r3, c7, c14, 2 @ writeback and invalidate line
+ cmp r3, #15 @ are we done with this level (way/set == 0)
+ bls .Lnext_level_wbinv @ yes, go to next level
+ lsl r0, r3, #10 @ clear way bits leaving only set/level bits
+ lsr r0, r0, #4 @ clear level bits leaving only set bits
+ subne r3, r3, r1 @ non-zero?, decrement set #
+ subeq r3, r3, r2 @ zero?, decrement way # and restore set count
+ b 1b
+
+.Lnext_level_wbinv:
+ mrc p15, 1, r0, c0, c0, 1 @ read CLIDR
+ and ip, r0, #0x07000000 @ narrow to LoC
+ lsr ip, ip, #23 @ left align LoC (low 4 bits)
+ add r3, r3, #2 @ go to next level
+ cmp r3, ip @ compare
+ blt .Lstart_wbinv @ not done, next level (r0 == CLIDR)
+
+.Ldone_wbinv:
+ mov r0, #0 @ default back to cache level 0
+ mcr p15, 2, r0, c0, c0, 0 @ select cache level
+ dsb
+ isb
+ bx lr
+END(armv7_dcache_wbinv_all)
Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6930
-gerrit
commit a0334bb97779e1a11daec8fd956f0406cb2bddcb
Author: Julius Werner <jwerner(a)chromium.org>
Date: Mon Jan 13 13:24:30 2014 -0800
arm: Thumb ALL the things!
This patch switches every last part of Coreboot on ARM over to Thumb
mode: libpayload, the internal libgcc, and assorted assembly files. In
combination with the respective depthcharge patch, this will switch to
Thumb mode right after the entry point of the bootblock and not switch
back to ARM until the final assembly stub that jumps to the kernel.
The required changes to make this work include some new headers and
Makefile flags to handle assembly files (using the unified syntax and
the same helper macros as Linux), modifying our custom-written libgcc
code for 64-bit division to support Thumb (removing some stale old files
that were never really used for clarity), and flipping the general
CFLAGS to Thumb (some more cleanup there as well while I'm at it).
Change-Id: I80c04281e3adbf74f9f477486a96b9fafeb455b3
Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/182212
Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
(cherry picked from commit 5f65c17cbfae165a95354146ae79e06c512c2c5a)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
payloads/libpayload/arch/arm/Makefile.inc | 7 ++++++-
payloads/libpayload/include/arm/arch/asm.h | 19 +++++++++++++------
src/arch/arm/Makefile.inc | 10 +++++-----
src/arch/arm/armv7/Makefile.inc | 10 ++++++----
src/arch/arm/armv7/bootblock.S | 23 ++++++++++-------------
src/arch/arm/include/arch/asm.h | 19 +++++++++++++------
src/soc/nvidia/tegra124/maincpu.S | 10 +++++-----
7 files changed, 58 insertions(+), 40 deletions(-)
diff --git a/payloads/libpayload/arch/arm/Makefile.inc b/payloads/libpayload/arch/arm/Makefile.inc
index 53a52df..590bf50 100644
--- a/payloads/libpayload/arch/arm/Makefile.inc
+++ b/payloads/libpayload/arch/arm/Makefile.inc
@@ -27,7 +27,8 @@
## SUCH DAMAGE.
##
-CFLAGS += -mfloat-abi=hard -marm -mabi=aapcs-linux -march=armv7-a
+CFLAGS += -mthumb -march=armv7-a
+arm_asm_flags = -Wa,-mthumb -Wa,-mimplicit-it=always -Wa,-mno-warn-deprecated
head.o-y += head.S
libc-y += main.c sysinfo.c
@@ -37,3 +38,7 @@ libc-y += memcpy.S memset.S memmove.S
libc-y += exception_asm.S exception.c
libc-y += cache.c
libcbfs-$(CONFIG_LP_CBFS) += dummy_media.c
+
+# Add other classes here when you put assembly files into them!
+head.o-S-ccopts += $(arm_asm_flags)
+libc-S-ccopts += $(arm_asm_flags)
diff --git a/payloads/libpayload/include/arm/arch/asm.h b/payloads/libpayload/include/arm/arch/asm.h
index 2f88599..9e9e7ce 100644
--- a/payloads/libpayload/include/arm/arch/asm.h
+++ b/payloads/libpayload/include/arm/arch/asm.h
@@ -20,16 +20,17 @@
#ifndef __ARM_ASM_H
#define __ARM_ASM_H
-#if defined __arm__
-# define ARM(x...) x
-# define THUMB(x...)
-# define W(instr) instr
-#elif defined __thumb__
+/* __arm__ is defined regardless of Thumb mode, so need to order this right */
+#if defined __thumb2__
# define ARM(x...)
# define THUMB(x...) x
# define W(instr) instr.w
+#elif defined __thumb__
+# error You are not compiling Thumb2, this won't work!
#else
-# error Not in ARM or thumb mode!
+# define ARM(x...) x
+# define THUMB(x...)
+# define W(instr) instr
#endif
#define ALIGN .align 0
@@ -46,4 +47,10 @@
#define END(name) \
.size name, .-name
+/* Everything should go into the text section by default. */
+ .text
+
+/* Thumb code uses the (new) unified assembly syntax. */
+THUMB( .syntax unified )
+
#endif /* __ARM_ASM_H */
diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc
index 027fbe1..0f0bab3 100644
--- a/src/arch/arm/Makefile.inc
+++ b/src/arch/arm/Makefile.inc
@@ -2,7 +2,7 @@
##
## This file is part of the coreboot project.
##
-## Copyright (C) 2012 The ChromiumOS Authors
+## Copyright (C) 2012-2013 The ChromiumOS Authors
## Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
## Copyright (C) 2009-2010 coresystems GmbH
## Copyright (C) 2009 Ronald G. Minnich
@@ -64,7 +64,7 @@ $(objcbfs)/bootblock.debug: $(src)/arch/arm/bootblock.ld $(obj)/ldoptions $$(boo
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
$(LD_bootblock) -m armelf_linux_eabi -static -o $@ -L$(obj) $< -T $(src)/arch/arm/bootblock.ld
else
- $(CC_bootblock) $(CFLAGS_bootblock) -nostartfiles -static -o $@ -L$(obj) -T $(src)/arch/arm/bootblock.ld -Wl,--start-group $(bootblock-objs) $(LIBGCC_FILE_NAME_bootblock) -Wl,--end-group
+ $(CC_bootblock) $(CFLAGS_bootblock) -nostdlib -static -o $@ -L$(obj) -T $(src)/arch/arm/bootblock.ld -Wl,--start-group $(bootblock-objs) $(LIBGCC_FILE_NAME_bootblock) -Wl,--end-group
endif
endif # CONFIG_ARCH_BOOTBLOCK_ARM
@@ -87,9 +87,9 @@ VBOOT_STUB_DEPS += $(obj)/arch/arm/eabi_compat.rmodules_arm.o
$(objcbfs)/romstage.debug: $$(romstage-objs) $(src)/arch/arm/romstage.ld $(obj)/ldoptions
@printf " LINK $(subst $(obj)/,,$(@))\n"
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
- $(LD_romstage) -nostdlib -nostartfiles -static -o $@ -L$(obj) $(romstage-objs) -T $(src)/arch/arm/romstage.ld
+ $(LD_romstage) -nostdlib -nostdlib -static -o $@ -L$(obj) $(romstage-objs) -T $(src)/arch/arm/romstage.ld
else
- $(CC_romstage) $(CFLAGS_romstage) -nostartfiles -static -o $@ -L$(obj) -T $(src)/arch/arm/romstage.ld -Wl,--start-group $(romstage-objs) $(LIBGCC_FILE_NAME_romstage) -Wl,--end-group
+ $(CC_romstage) $(CFLAGS_romstage) -nostdlib -static -o $@ -L$(obj) -T $(src)/arch/arm/romstage.ld -Wl,--start-group $(romstage-objs) $(LIBGCC_FILE_NAME_romstage) -Wl,--end-group
endif
endif # CONFIG_ARCH_ROMSTAGE_ARM
@@ -116,7 +116,7 @@ $(objcbfs)/ramstage.debug: $$(ramstage-objs) $(LIBGCC_FILE_NAME_ramstage) $(src)
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
$(LD_ramstage) -m armelf_linux_eabi -o $@ -L$(obj) $< -T $(src)/arch/arm/ramstage.ld
else
- $(CC_ramstage) $(CFLAGS_ramstage) -nostdlib -nostartfiles -static -o $@ -L$(obj) -Wl,--start-group $(ramstage-objs) $(LIBGCC_FILE_NAME_ramstage) -Wl,--end-group -T $(src)/arch/arm/ramstage.ld
+ $(CC_ramstage) $(CFLAGS_ramstage) -nostdlib -nostdlib -static -o $@ -L$(obj) -Wl,--start-group $(ramstage-objs) $(LIBGCC_FILE_NAME_ramstage) -Wl,--end-group -T $(src)/arch/arm/ramstage.ld
endif
$(objgenerated)/ramstage.o: $(stages_o) $$(ramstage-objs) $(LIBGCC_FILE_NAME_ramstage)
diff --git a/src/arch/arm/armv7/Makefile.inc b/src/arch/arm/armv7/Makefile.inc
index 033d498..62e687b 100644
--- a/src/arch/arm/armv7/Makefile.inc
+++ b/src/arch/arm/armv7/Makefile.inc
@@ -19,8 +19,10 @@
##
###############################################################################
-armv7_flags = -march=armv7-a -mthumb -mthumb-interwork \
+armv7_flags = -march=armv7-a -mthumb \
-I$(src)/arch/arm/include/armv7/ -D__COREBOOT_ARM_ARCH__=7
+armv7_asm_flags = $(armv7_flags) -Wa,-mthumb -Wa,-mimplicit-it=always \
+ -Wa,-mno-warn-deprecated
###############################################################################
# bootblock
@@ -39,7 +41,7 @@ bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += exception_asm.S
bootblock-y += mmu.c
CFLAGS_bootblock += $(armv7_flags)
-CPPFLAGS_bootblock += $(armv7_flags)
+CPPFLAGS_bootblock += $(armv7_asm_flags)
endif # CONFIG_ARCH_BOOTBLOCK_ARMV7
@@ -55,7 +57,7 @@ romstage-y += exception_asm.S
romstage-y += mmu.c
CFLAGS_romstage += $(armv7_flags)
-CPPFLAGS_romstage += $(armv7_flags)
+CPPFLAGS_romstage += $(armv7_asm_flags)
endif # CONFIG_ARCH_ROMSTAGE_ARMV7
@@ -71,6 +73,6 @@ ramstage-y += exception_asm.S
ramstage-y += mmu.c
CFLAGS_ramstage += $(armv7_flags)
-CPPFLAGS_ramstage += $(armv7_flags)
+CPPFLAGS_ramstage += $(armv7_asm_flags)
endif # CONFIG_ARCH_RAMSTAGE_ARMV7
diff --git a/src/arch/arm/armv7/bootblock.S b/src/arch/arm/armv7/bootblock.S
index a8d0973..4258caf 100644
--- a/src/arch/arm/armv7/bootblock.S
+++ b/src/arch/arm/armv7/bootblock.S
@@ -32,6 +32,7 @@
#include <arch/asm.h>
.section ".start", "a", %progbits
+.arm
ENTRY(_start)
/*
* Set the cpu to System mode with IRQ and FIQ disabled. Prefetch/Data
@@ -40,7 +41,11 @@ ENTRY(_start)
* causes it.
*/
msr cpsr_cxf, #0xdf
+ bl _thumb_start
+ENDPROC(_start)
+.thumb
+ENTRY(_thumb_start)
/*
* From Cortex-A Series Programmer's Guide:
* Only CPU 0 performs initialization. Other CPUs go into WFI
@@ -72,25 +77,17 @@ call_bootblock:
ldr sp, .Stack /* Set up stack pointer */
ldr r0,=0x00000000
/*
- * The current design of cpu_info places the
- * struct at the top of the stack. The number of
- * words pushed must be at least as large as that
- * struct.
+ * The current design of cpu_info places the struct at the top of the
+ * stack. Free enough space to accomodate for that, but make sure it's
+ * 8-byte aligned for ABI compliance.
*/
- push {r0-r2}
- bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- /*
- * Use "bl" instead of "b" even though we do not intend to return.
- * "bl" gets compiled to "blx" if we're transitioning from ARM to
- * Thumb. However, "b" will not and GCC may attempt to create a
- * wrapper which is currently broken.
- */
+ sub sp, sp, #16
bl main
wait_for_interrupt:
wfi
mov pc, lr @ back to my caller
-ENDPROC(_start)
+ENDPROC(_thumb_start)
/* we do it this way because it's a 32-bit constant and
* in some cases too far away to be loaded as just an offset
diff --git a/src/arch/arm/include/arch/asm.h b/src/arch/arm/include/arch/asm.h
index 5f3e55f..a57ce4d 100644
--- a/src/arch/arm/include/arch/asm.h
+++ b/src/arch/arm/include/arch/asm.h
@@ -20,19 +20,20 @@
#ifndef __ARM_ASM_H
#define __ARM_ASM_H
-#if defined __arm__
-# define ARM(x...) x
-# define THUMB(x...)
-# define W(instr) instr
-#elif defined __thumb__
+/* __arm__ is defined regardless of Thumb mode, so need to order this right */
+#if defined __thumb2__
# define ARM(x...)
# define THUMB(x...) x
# define W(instr) instr.w
# if __COREBOOT_ARM_ARCH__ < 7
# error thumb mode has not been tested with ARM < v7!
# endif
+#elif defined __thumb__
+# error You are not compiling Thumb2, this won't work!
#else
-# error Not in ARM or thumb mode!
+# define ARM(x...) x
+# define THUMB(x...)
+# define W(instr) instr
#endif
#define ALIGN .align 0
@@ -49,4 +50,10 @@
#define END(name) \
.size name, .-name
+/* Everything should go into the text section by default. */
+ .text
+
+/* Thumb code uses the (new) unified assembly syntax. */
+THUMB( .syntax unified )
+
#endif /* __ARM_ASM_H */
diff --git a/src/soc/nvidia/tegra124/maincpu.S b/src/soc/nvidia/tegra124/maincpu.S
index 7b217d8..91981ac 100644
--- a/src/soc/nvidia/tegra124/maincpu.S
+++ b/src/soc/nvidia/tegra124/maincpu.S
@@ -27,8 +27,9 @@
* SUCH DAMAGE.
*/
+#include <arch/asm.h>
+
.align 2
- .arm
.global maincpu_stack_pointer
maincpu_stack_pointer:
@@ -38,10 +39,8 @@ maincpu_stack_pointer:
maincpu_entry_point:
.word 0
- .global maincpu_setup
- .type maincpu_setup, function
- maincpu_setup:
-
+.arm
+ENTRY(maincpu_setup)
/*
* Set the cpu to System mode with IRQ and FIQ disabled. Prefetch/Data
* aborts may happen early and crash before the abort handlers are
@@ -54,3 +53,4 @@ maincpu_entry_point:
eor lr, lr
ldr r0, maincpu_entry_point
bx r0
+ENDPROC(maincpu_setup)
Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6928
-gerrit
commit 8a481388c00e379a43a66b12e7dbc891ce5dbd92
Author: Gabe Black <gabeblack(a)google.com>
Date: Wed Jan 22 20:50:27 2014 -0800
pit: Rename pit to peach_pit.
The name pit goes by in many places in chromeos is peach_pit, where peach is
the base name and pit is the name of this particular variant. To make it
easier to work with within chromeos and to make the board names a little less
ambiguous, this change renames the pit board to peach_pit, and from Pit to
Peach Pit.
Change-Id: I51c89ba3785cf4cb9769a989b1cac71bcd1b0a05
Signed-off-by: Gabe Black <gabeblack(a)google.com>
Reviewed-on: https://chromium-review.googlesource.com/183552
Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
Tested-by: Gabe Black <gabeblack(a)chromium.org>
(cherry picked from commit cbbe1e9f04e34436a1bbae28628e0b5630d41054)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
src/mainboard/google/Kconfig | 6 +-
src/mainboard/google/peach_pit/Kconfig | 53 +++
src/mainboard/google/peach_pit/Makefile.inc | 27 ++
src/mainboard/google/peach_pit/chromeos.c | 101 ++++++
src/mainboard/google/peach_pit/devicetree.cb | 33 ++
src/mainboard/google/peach_pit/mainboard.c | 498 +++++++++++++++++++++++++++
src/mainboard/google/peach_pit/memory.c | 116 +++++++
src/mainboard/google/peach_pit/romstage.c | 279 +++++++++++++++
src/mainboard/google/peach_pit/wakeup.c | 28 ++
src/mainboard/google/pit/Kconfig | 53 ---
src/mainboard/google/pit/Makefile.inc | 27 --
src/mainboard/google/pit/chromeos.c | 101 ------
src/mainboard/google/pit/devicetree.cb | 33 --
src/mainboard/google/pit/mainboard.c | 498 ---------------------------
src/mainboard/google/pit/memory.c | 116 -------
src/mainboard/google/pit/romstage.c | 279 ---------------
src/mainboard/google/pit/wakeup.c | 28 --
17 files changed, 1138 insertions(+), 1138 deletions(-)
diff --git a/src/mainboard/google/Kconfig b/src/mainboard/google/Kconfig
index 538f0d8..08a2b26 100644
--- a/src/mainboard/google/Kconfig
+++ b/src/mainboard/google/Kconfig
@@ -35,10 +35,10 @@ config BOARD_GOOGLE_PANTHER
bool "Panther"
config BOARD_GOOGLE_PARROT
bool "Parrot"
+config BOARD_GOOGLE_PEACH_PIT
+ bool "Peach Pit"
config BOARD_GOOGLE_PEPPY
bool "Peppy"
-config BOARD_GOOGLE_PIT
- bool "Pit"
config BOARD_GOOGLE_RAMBI
bool "Rambi"
config BOARD_GOOGLE_SAMUS
@@ -59,8 +59,8 @@ source "src/mainboard/google/link/Kconfig"
source "src/mainboard/google/nyan/Kconfig"
source "src/mainboard/google/panther/Kconfig"
source "src/mainboard/google/parrot/Kconfig"
+source "src/mainboard/google/peach_pit/Kconfig"
source "src/mainboard/google/peppy/Kconfig"
-source "src/mainboard/google/pit/Kconfig"
source "src/mainboard/google/rambi/Kconfig"
source "src/mainboard/google/samus/Kconfig"
source "src/mainboard/google/slippy/Kconfig"
diff --git a/src/mainboard/google/peach_pit/Kconfig b/src/mainboard/google/peach_pit/Kconfig
new file mode 100644
index 0000000..66ab6a7
--- /dev/null
+++ b/src/mainboard/google/peach_pit/Kconfig
@@ -0,0 +1,53 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright 2013 Google Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+if BOARD_GOOGLE_PEACH_PIT
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select CPU_SAMSUNG_EXYNOS5420
+ select EC_GOOGLE_CHROMEEC
+ select EC_GOOGLE_CHROMEEC_SPI
+ select BOARD_ROMSIZE_KB_4096
+ select MAINBOARD_HAS_CHROMEOS
+ select MAINBOARD_HAS_NATIVE_VGA_INIT
+ select MAINBOARD_DO_NATIVE_VGA_INIT
+ select DRIVER_PARADE_PS8625
+
+config MAINBOARD_DIR
+ string
+ default google/peach_pit
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "Peach Pit"
+
+config DRAM_SIZE_MB
+ int
+ default 2048
+
+config EC_GOOGLE_CHROMEEC_SPI_BUS
+ hex
+ default 2
+
+config UART_FOR_CONSOLE
+ int
+ default 3
+
+endif # BOARD_GOOGLE_PEACH_PIT
diff --git a/src/mainboard/google/peach_pit/Makefile.inc b/src/mainboard/google/peach_pit/Makefile.inc
new file mode 100644
index 0000000..2858743
--- /dev/null
+++ b/src/mainboard/google/peach_pit/Makefile.inc
@@ -0,0 +1,27 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright 2012 Google Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+bootblock-y += wakeup.c
+
+romstage-y += memory.c
+romstage-y += romstage.c
+romstage-y += wakeup.c
+
+ramstage-y += mainboard.c
+ramstage-y += chromeos.c
diff --git a/src/mainboard/google/peach_pit/chromeos.c b/src/mainboard/google/peach_pit/chromeos.c
new file mode 100644
index 0000000..7b0807c
--- /dev/null
+++ b/src/mainboard/google/peach_pit/chromeos.c
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <boot/coreboot_tables.h>
+#include <console/console.h>
+#include <ec/google/chromeec/ec.h>
+#include <ec/google/chromeec/ec_commands.h>
+#include <string.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+#include <bootmode.h>
+#include <soc/samsung/exynos5420/cpu.h>
+#include <soc/samsung/exynos5420/gpio.h>
+
+void fill_lb_gpios(struct lb_gpios *gpios)
+{
+ int count = 0;
+
+ /* Write Protect: active low */
+ gpios->gpios[count].port = EXYNOS5_GPX3;
+ gpios->gpios[count].polarity = ACTIVE_LOW;
+ gpios->gpios[count].value = gpio_get_value(GPIO_X30); // WP_GPIO
+ strncpy((char *)gpios->gpios[count].name, "write protect",
+ GPIO_MAX_NAME_LENGTH);
+ count++;
+
+ /* Recovery: active low */
+ gpios->gpios[count].port = -1;
+ gpios->gpios[count].polarity = ACTIVE_HIGH;
+ gpios->gpios[count].value = get_recovery_mode_switch();
+ strncpy((char *)gpios->gpios[count].name, "recovery",
+ GPIO_MAX_NAME_LENGTH);
+ count++;
+
+ /* Lid: active high */
+ gpios->gpios[count].port = EXYNOS5_GPX3;
+ gpios->gpios[count].polarity = ACTIVE_HIGH;
+ gpios->gpios[count].value = gpio_get_value(GPIO_X34); // LID_GPIO
+ strncpy((char *)gpios->gpios[count].name, "lid", GPIO_MAX_NAME_LENGTH);
+ count++;
+
+ /* Power: virtual GPIO active low */
+ gpios->gpios[count].port = EXYNOS5_GPX1;
+ gpios->gpios[count].polarity = ACTIVE_LOW;
+ gpios->gpios[count].value =
+ gpio_get_value(GPIO_X12); // POWER_GPIO
+ strncpy((char *)gpios->gpios[count].name, "power",
+ GPIO_MAX_NAME_LENGTH);
+ count++;
+
+ /* Developer: virtual GPIO active high */
+ gpios->gpios[count].port = -1;
+ gpios->gpios[count].polarity = ACTIVE_HIGH;
+ gpios->gpios[count].value = get_developer_mode_switch();
+ strncpy((char *)gpios->gpios[count].name, "developer",
+ GPIO_MAX_NAME_LENGTH);
+ count++;
+
+ gpios->size = sizeof(*gpios) + (count * sizeof(struct lb_gpio));
+ gpios->count = count;
+
+ printk(BIOS_ERR, "Added %d GPIOS size %d\n", count, gpios->size);
+}
+
+int get_developer_mode_switch(void)
+{
+ return 0;
+}
+
+int get_recovery_mode_switch(void)
+{
+ uint32_t ec_events;
+
+ /* The GPIO is active low. */
+ if (!gpio_get_value(GPIO_X07)) // RECMODE_GPIO
+ return 1;
+
+ ec_events = google_chromeec_get_events_b();
+ return !!(ec_events &
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
+}
+
+int get_write_protect_state(void)
+{
+ return !gpio_get_value(GPIO_X30);
+}
diff --git a/src/mainboard/google/peach_pit/devicetree.cb b/src/mainboard/google/peach_pit/devicetree.cb
new file mode 100644
index 0000000..568daf8
--- /dev/null
+++ b/src/mainboard/google/peach_pit/devicetree.cb
@@ -0,0 +1,33 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright 2012 Google Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+chip soc/samsung/exynos5420
+ device cpu_cluster 0 on end
+ register "xres" = "1366"
+ register "yres" = "768"
+ register "framebuffer_bits_per_pixel" = "16"
+ # complex magic timing!
+ register "clkval_f" = "2"
+ register "upper_margin" = "14"
+ register "lower_margin" = "3"
+ register "vsync" = "5"
+ register "left_margin" = "80"
+ register "right_margin" = "48"
+ register "hsync" = "32"
+end
diff --git a/src/mainboard/google/peach_pit/mainboard.c b/src/mainboard/google/peach_pit/mainboard.c
new file mode 100644
index 0000000..1fb441d
--- /dev/null
+++ b/src/mainboard/google/peach_pit/mainboard.c
@@ -0,0 +1,498 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/i2c.h>
+#include <cbmem.h>
+#include <delay.h>
+#include <edid.h>
+#include <vbe.h>
+#include <boot/coreboot_tables.h>
+#include <arch/cache.h>
+#include <soc/samsung/exynos5420/tmu.h>
+#include <soc/samsung/exynos5420/clk.h>
+#include <soc/samsung/exynos5420/cpu.h>
+#include <soc/samsung/exynos5420/gpio.h>
+#include <soc/samsung/exynos5420/power.h>
+#include <soc/samsung/exynos5420/i2c.h>
+#include <soc/samsung/exynos5420/dp.h>
+#include <soc/samsung/exynos5420/fimd.h>
+#include <soc/samsung/exynos5420/usb.h>
+#include <drivers/parade/ps8625/ps8625.h>
+#include <ec/google/chromeec/ec.h>
+#include <stdlib.h>
+
+/* convenient shorthand (in MB) */
+#define DRAM_START (CONFIG_SYS_SDRAM_BASE >> 20)
+#define DRAM_SIZE CONFIG_DRAM_SIZE_MB
+
+/* Arbitrary range of DMA memory for depthcharge's drivers */
+#define DMA_START (0x77300000)
+#define DMA_SIZE (0x00100000)
+
+static struct edid edid = {
+ .ha = 1366,
+ .va = 768,
+ .framebuffer_bits_per_pixel = 16,
+ .x_resolution = 1366,
+ .y_resolution = 768,
+ .bytes_per_line = 2 * 1366
+};
+
+/* from the fdt */
+static struct vidinfo vidinfo = {
+ .vl_freq = 60,
+ .vl_col = 1366,
+ .vl_row = 768,
+ .vl_width = 1366,
+ .vl_height = 768,
+ .vl_clkp = 1,
+ .vl_dp = 1,
+ .vl_bpix = 4,
+ .vl_hspw = 32,
+ .vl_hbpd = 40,
+ .vl_hfpd = 40,
+ .vl_vspw = 6,
+ .vl_vbpd = 10,
+ .vl_vfpd = 12,
+ .vl_cmd_allow_len = 0xf,
+ .win_id = 3,
+ .dp_enabled = 1,
+ .dual_lcd_enabled = 0,
+ .interface_mode = FIMD_RGB_INTERFACE,
+};
+
+static unsigned char panel_edid[] = {
+ 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
+ 0x06,0xaf,0x5c,0x31,0x00,0x00,0x00,0x00,
+ 0x00,0x16,0x01,0x03,0x80,0x1a,0x0e,0x78,
+ 0x0a,0x99,0x85,0x95,0x55,0x56,0x92,0x28,
+ 0x22,0x50,0x54,0x00,0x00,0x00,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0xa3,0x1b,
+ 0x56,0x7e,0x50,0x00,0x16,0x30,0x30,0x20,
+ 0x36,0x00,0x00,0x90,0x10,0x00,0x00,0x18,
+ 0x6d,0x12,0x56,0x7e,0x50,0x00,0x16,0x30,
+ 0x30,0x20,0x36,0x00,0x00,0x90,0x10,0x00,
+ 0x00,0x18,0x00,0x00,0x00,0xfe,0x00,0x41,
+ 0x55,0x4f,0x0a,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xfe,
+ 0x00,0x42,0x31,0x31,0x36,0x58,0x57,0x30,
+ 0x33,0x20,0x56,0x31,0x20,0x0a,0x00,0x3d,
+ 0x00,0xc0,0x00,0x00,0x27,0xfd,0x00,0x20,
+ 0x02,0x59,0x07,0x00,0x64,0x3e,0x07,0x02,
+ 0x00,0x00,0xcd,0x12,0x59,0xff,0x10,0x03,
+ 0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0x9c,0x3f,0x07,0x02,0x31,0xf9,0x00,0x20,
+ 0x59,0xff,0x10,0x03,0x00,0x00,0x00,0x00,
+ 0xbc,0x3e,0x07,0x02,0xc0,0x9b,0x01,0x20,
+ 0x00,0x00,0x00,0x00,0xdb,0xf8,0x00,0x20,
+ 0x98,0x3e,0x07,0x02,0x8b,0xaf,0x00,0x20,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe5,0xcd,0x16,0x00,0xe9,0xcd,0x16,0x00,
+ 0xe8,0x03,0x00,0x00,0x6c,0x55,0x01,0x20,
+ 0x2c,0x01,0x00,0x00,0x85,0xbb,0x00,0x20,
+ 0xe8,0x03,0x00,0x00,0xe9,0xcd,0x16,0x00,
+};
+
+static const struct parade_write parade_writes[] = {
+ { 0x02, 0xa1, 0x01 }, /* HPD low */
+ /*
+ * SW setting
+ * [1:0] SW output 1.2V voltage is lower to 96%
+ */
+ { 0x04, 0x14, 0x01 },
+ /*
+ * RCO SS setting
+ * [5:4] = b01 0.5%, b10 1%, b11 1.5%
+ */
+ { 0x04, 0xe3, 0x20 },
+ { 0x04, 0xe2, 0x80 }, /* [7] RCO SS enable */
+ /*
+ * RPHY Setting
+ * [3:2] CDR tune wait cycle before
+ * measure for fine tune b00: 1us,
+ * 01: 0.5us, 10:2us, 11:4us.
+ */
+ { 0x04, 0x8a, 0x0c },
+ { 0x04, 0x89, 0x08 }, /* [3] RFD always on */
+ /*
+ * CTN lock in/out:
+ * 20000ppm/80000ppm. Lock out 2
+ * times.
+ */
+ { 0x04, 0x71, 0x2d },
+ /*
+ * 2.7G CDR settings
+ * NOF=40LSB for HBR CDR setting
+ */
+ { 0x04, 0x7d, 0x07 },
+ { 0x04, 0x7b, 0x00 }, /* [1:0] Fmin=+4bands */
+ { 0x04, 0x7a, 0xfd }, /* [7:5] DCO_FTRNG=+-40% */
+ /*
+ * 1.62G CDR settings
+ * [5:2]NOF=64LSB [1:0]DCO scale is 2/5
+ */
+ { 0x04, 0xc0, 0x12 },
+ { 0x04, 0xc1, 0x92 }, /* Gitune=-37% */
+ { 0x04, 0xc2, 0x1c }, /* Fbstep=100% */
+ { 0x04, 0x32, 0x80 }, /* [7] LOS signal disable */
+ /*
+ * RPIO Setting
+ * [7:4] LVDS driver bias current :
+ * 75% (250mV swing)
+ */
+ { 0x04, 0x00, 0xb0 },
+ /*
+ * [7:6] Right-bar GPIO output strength is 8mA
+ */
+ { 0x04, 0x15, 0x40 },
+ /* EQ Training State Machine Setting */
+ { 0x04, 0x54, 0x10 }, /* RCO calibration start */
+ /* [4:0] MAX_LANE_COUNT set to one lane */
+ { 0x01, 0x02, 0x81 },
+ /* [4:0] LANE_COUNT_SET set to one lane */
+ { 0x01, 0x21, 0x81 },
+ { 0x00, 0x52, 0x20 },
+ { 0x00, 0xf1, 0x03 }, /* HPD CP toggle enable */
+ { 0x00, 0x62, 0x41 },
+ /* Counter number, add 1ms counter delay */
+ { 0x00, 0xf6, 0x01 },
+ /*
+ * [6]PWM function control by
+ * DPCD0040f[7], default is PWM
+ * block always works.
+ */
+ { 0x00, 0x77, 0x06 },
+ /*
+ * 04h Adjust VTotal tolerance to
+ * fix the 30Hz no display issue
+ */
+ { 0x00, 0x4c, 0x04 },
+ /* DPCD00400='h00, Parade OUI = 'h001cf8 */
+ { 0x01, 0xc0, 0x00 },
+ { 0x01, 0xc1, 0x1c }, /* DPCD00401='h1c */
+ { 0x01, 0xc2, 0xf8 }, /* DPCD00402='hf8 */
+ /*
+ * DPCD403~408 = ASCII code
+ * D2SLV5='h4432534c5635
+ */
+ { 0x01, 0xc3, 0x44 },
+ { 0x01, 0xc4, 0x32 }, /* DPCD404 */
+ { 0x01, 0xc5, 0x53 }, /* DPCD405 */
+ { 0x01, 0xc6, 0x4c }, /* DPCD406 */
+ { 0x01, 0xc7, 0x56 }, /* DPCD407 */
+ { 0x01, 0xc8, 0x35 }, /* DPCD408 */
+ /*
+ * DPCD40A, Initial Code major revision
+ * '01'
+ */
+ { 0x01, 0xca, 0x01 },
+ /* DPCD40B, Initial Code minor revision '05' */
+ { 0x01, 0xcb, 0x05 },
+ /* DPCD720, Select external PWM */
+ { 0x01, 0xa5, 0x80 },
+ /*
+ * Set LVDS output as 6bit-VESA mapping,
+ * single LVDS channel
+ */
+ { 0x01, 0xcc, 0x13 },
+ /* Enable SSC set by register */
+ { 0x02, 0xb1, 0x20 },
+ /*
+ * Set SSC enabled and +/-1% central
+ * spreading
+ */
+ { 0x04, 0x10, 0x16 },
+ /* MPU Clock source: LC => RCO */
+ { 0x04, 0x59, 0x60 },
+ { 0x04, 0x54, 0x14 }, /* LC -> RCO */
+ { 0x02, 0xa1, 0x91 } /* HPD high */
+};
+
+/* TODO: transplanted DP stuff, clean up once we have something that works */
+static enum exynos5_gpio_pin dp_pd_l = GPIO_X35; /* active low */
+static enum exynos5_gpio_pin dp_rst_l = GPIO_Y77; /* active low */
+static enum exynos5_gpio_pin dp_hpd = GPIO_X26; /* active high */
+static enum exynos5_gpio_pin bl_pwm = GPIO_B20; /* active high */
+static enum exynos5_gpio_pin bl_en = GPIO_X22; /* active high */
+
+static void parade_dp_bridge_setup(void)
+{
+ int i;
+
+ gpio_set_value(dp_pd_l, 1);
+ gpio_cfg_pin(dp_pd_l, GPIO_OUTPUT);
+ gpio_set_pull(dp_pd_l, GPIO_PULL_NONE);
+
+ gpio_set_value(dp_rst_l, 0);
+ gpio_cfg_pin(dp_rst_l, GPIO_OUTPUT);
+ gpio_set_pull(dp_rst_l, GPIO_PULL_NONE);
+ udelay(10);
+ gpio_set_value(dp_rst_l, 1);
+
+
+ gpio_set_pull(dp_hpd, GPIO_PULL_NONE);
+ gpio_cfg_pin(dp_hpd, GPIO_INPUT);
+
+ /* De-assert PD (and possibly RST) to power up the bridge. */
+ gpio_set_value(dp_pd_l, 1);
+ gpio_set_value(dp_rst_l, 1);
+
+ /* Hang around for the bridge to come up. */
+ mdelay(40);
+
+ /* Configure the bridge chip. */
+ exynos_pinmux_i2c7();
+ i2c_init(7, 100000, 0x00);
+
+ parade_ps8625_bridge_setup(7, 0x48, parade_writes,
+ ARRAY_SIZE(parade_writes));
+ /* Spin until the display is ready.
+ * It's quite important to try really hard to get the display up,
+ * so be generous. It will typically be ready in only 5 ms. and
+ * we're out of here.
+ * If it's not ready after a second, then we're in big trouble.
+ */
+ for(i = 0; i < 1000; i++){
+ if (gpio_get_value(dp_hpd))
+ break;
+ mdelay(1);
+ }
+}
+
+/*
+ * This delay is T3 in the LCD timing spec (defined as >200ms). We set
+ * this down to 60ms since that's the approximate maximum amount of time
+ * it'll take a bridge to start outputting LVDS data. The delay of
+ * >200ms is just a conservative value to avoid turning on the backlight
+ * when there's random LCD data on the screen. Shaving 140ms off the
+ * boot is an acceptable trade-off.
+ */
+#define LCD_T3_DELAY_MS 60
+
+#define LCD_T5_DELAY_MS 10
+#define LCD_T6_DELAY_MS 10
+
+static void backlight_pwm(void)
+{
+ /*Configure backlight PWM as a simple output high (100% brightness) */
+ gpio_direction_output(bl_pwm, 1);
+ udelay(LCD_T6_DELAY_MS * 1000);
+}
+
+static void backlight_en(void)
+{
+ /* Configure GPIO for LCD_BL_EN */
+ gpio_direction_output(bl_en, 1);
+}
+
+static enum exynos5_gpio_pin usb_drd0_vbus = GPIO_H00;
+static enum exynos5_gpio_pin usb_drd1_vbus = GPIO_H01;
+/* static enum exynos5_gpio_pin hsic_reset_l = GPIO_X24; */
+
+static void prepare_usb(void)
+{
+ /* Kick these resets off early so they get at least 100ms to settle */
+ reset_usb_drd0_dwc3();
+ reset_usb_drd1_dwc3();
+}
+
+static void setup_usb(void)
+{
+ /* HSIC and USB HOST port not needed in firmware on this board */
+ setup_usb_drd0_phy();
+ setup_usb_drd1_phy();
+
+ setup_usb_drd0_dwc3();
+ setup_usb_drd1_dwc3();
+
+ gpio_direction_output(usb_drd0_vbus, 1);
+ gpio_direction_output(usb_drd1_vbus, 1);
+}
+
+static struct edp_video_info dp_video_info = {
+ .master_mode = 0,
+ .h_sync_polarity = 0,
+ .v_sync_polarity = 0,
+ .interlaced = 0,
+ .color_space = COLOR_RGB,
+ .dynamic_range = VESA,
+ .ycbcr_coeff = COLOR_YCBCR601,
+ .color_depth = COLOR_8,
+};
+
+/* FIXME: move some place more appropriate */
+#define MAX_DP_TRIES 5
+
+static void setup_storage(void)
+{
+ /* MMC0: Fixed, 8 bit mode, connected with GPIO. */
+ if (clock_set_dwmci(PERIPH_ID_SDMMC0))
+ printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
+ exynos_pinmux_sdmmc0();
+
+ /* MMC2: Removable, 4 bit mode, no GPIO. */
+ /* (Must be after romstage to avoid breaking SDMMC boot.) */
+ clock_set_dwmci(PERIPH_ID_SDMMC2);
+ exynos_pinmux_sdmmc2();
+}
+
+static void gpio_init(void)
+{
+ /* Set up the I2C busses. */
+ exynos_pinmux_i2c2();
+ exynos_pinmux_i2c4();
+ exynos_pinmux_i2c7();
+ exynos_pinmux_i2c8();
+ exynos_pinmux_i2c9();
+ exynos_pinmux_i2c10();
+}
+
+enum {
+ FET_CTRL_WAIT = 3 << 2,
+ FET_CTRL_ADENFET = 1 << 1,
+ FET_CTRL_ENFET = 1 << 0
+};
+
+static void tps65090_thru_ec_fet_set(int index)
+{
+ uint8_t value = FET_CTRL_ADENFET | FET_CTRL_WAIT | FET_CTRL_ENFET;
+
+ if (google_chromeec_i2c_xfer(0x48, 0xe + index, 1, &value, 1, 0)) {
+ printk(BIOS_ERR,
+ "Error sending i2c pass through command to EC.\n");
+ return;
+ }
+}
+
+static void lcd_vdd(void)
+{
+ /* Enable FET6, lcd panel */
+ tps65090_thru_ec_fet_set(6);
+}
+
+static void backlight_vdd(void)
+{
+ /* Enable FET1, backlight */
+ tps65090_thru_ec_fet_set(1);
+}
+
+static void sdmmc_vdd(void)
+{
+ /* Enable FET4, P3.3V_SDCARD */
+ tps65090_thru_ec_fet_set(4);
+}
+
+/* this happens after cpu_init where exynos resources are set */
+static void mainboard_init(device_t dev)
+{
+ /* we'll stick with the crummy u-boot struct for now.*/
+ /* doing this as an auto since the struct has to be writeable */
+ struct edp_device_info device_info;
+
+ void *fb_addr = (void *)(get_fb_base_kb() * KiB);
+
+ prepare_usb();
+ gpio_init();
+ setup_storage();
+ tmu_init(&exynos5420_tmu_info);
+
+ /* Clock Gating all the unused IP's to save power */
+ clock_gate();
+
+ sdmmc_vdd();
+
+ set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);
+
+ /*
+ * The reset value for FIMD SYSMMU register MMU_CTRL:0x14640000
+ * should be 0 according to the datasheet, but has experimentally
+ * been found to come up as 3. This means FIMD SYSMMU is on by
+ * default on Exynos5420. For now we are disabling FIMD SYSMMU.
+ */
+ writel(0x0, (void *)0x14640000);
+ writel(0x0, (void *)0x14680000);
+
+ lcd_vdd();
+
+ /* Start the fimd running before you do the phy and lcd setup.
+ * why do fimd before training etc?
+ * because we need a data stream from
+ * the fimd or the clock recovery step fails.
+ */
+ vidinfo.screen_base = fb_addr;
+ exynos_fimd_lcd_init(&vidinfo);
+
+ parade_dp_bridge_setup();
+
+ /* this might get more dynamic in future ... */
+ memset(&device_info, 0, sizeof(device_info));
+ device_info.disp_info.name = (char *)"Peach Pit display";
+ device_info.disp_info.h_total = 1366;
+ device_info.disp_info.v_total = 768;
+ device_info.video_info = dp_video_info;
+ device_info.raw_edid = panel_edid;
+ exynos_init_dp(&device_info);
+
+ backlight_vdd();
+ backlight_pwm();
+ backlight_en();
+
+ setup_usb();
+}
+
+static void mainboard_enable(device_t dev)
+{
+ dev->ops->init = &mainboard_init;
+
+ /* set up caching for the DRAM */
+ mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
+ mmu_config_range(DMA_START >> 20, DMA_SIZE >> 20, DCACHE_OFF);
+ tlb_invalidate_all();
+
+ const unsigned epll_hz = 192000000;
+ const unsigned sample_rate = 48000;
+ const unsigned lr_frame_size = 256;
+ clock_epll_set_rate(epll_hz);
+ clock_select_i2s_clk_source();
+ clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);
+
+ power_enable_xclkout();
+}
+
+struct chip_operations mainboard_ops = {
+ .name = "Samsung/Google ARM Chromebook",
+ .enable_dev = mainboard_enable,
+};
+
+void lb_board(struct lb_header *header)
+{
+ struct lb_range *dma;
+
+ dma = (struct lb_range *)lb_new_record(header);
+ dma->tag = LB_TAB_DMA;
+ dma->size = sizeof(*dma);
+ dma->range_start = (intptr_t)DMA_START;
+ dma->range_size = DMA_SIZE;
+}
diff --git a/src/mainboard/google/peach_pit/memory.c b/src/mainboard/google/peach_pit/memory.c
new file mode 100644
index 0000000..8a9f454
--- /dev/null
+++ b/src/mainboard/google/peach_pit/memory.c
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * Copyright 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <console/console.h>
+
+#include <soc/samsung/exynos5420/gpio.h>
+#include <soc/samsung/exynos5420/dmc.h>
+#include <soc/samsung/exynos5420/setup.h>
+#include <soc/samsung/exynos5420/clk.h>
+
+const struct mem_timings mem_timings = {
+ .mem_manuf = MEM_MANUF_SAMSUNG,
+ .mem_type = DDR_MODE_DDR3,
+ .frequency_mhz = 800,
+ .direct_cmd_msr = {
+ 0x00020018, 0x00030000, 0x00010046, 0x00000d70,
+ 0x00000c70
+ },
+ .timing_ref = 0x000000bb,
+ .timing_row = 0x6836650f,
+ .timing_data = 0x3630580b,
+ .timing_power = 0x41000a26,
+ .phy0_dqs = 0x08080808,
+ .phy1_dqs = 0x08080808,
+ .phy0_dq = 0x08080808,
+ .phy1_dq = 0x08080808,
+ .phy0_tFS = 0x8,
+ .phy1_tFS = 0x8,
+ .phy0_pulld_dqs = 0xf,
+ .phy1_pulld_dqs = 0xf,
+
+ .lpddr3_ctrl_phy_reset = 0x1,
+ .ctrl_start_point = 0x10,
+ .ctrl_inc = 0x10,
+ .ctrl_start = 0x1,
+ .ctrl_dll_on = 0x1,
+ .ctrl_ref = 0x8,
+
+ .ctrl_force = 0x1a,
+ .ctrl_rdlat = 0x0b,
+ .ctrl_bstlen = 0x08,
+
+ .fp_resync = 0x8,
+ .iv_size = 0x7,
+ .dfi_init_start = 1,
+ .aref_en = 1,
+
+ .rd_fetch = 0x3,
+
+ .zq_mode_dds = 0x7,
+ .zq_mode_term = 0x1,
+ .zq_mode_noterm = 1,
+
+ /*
+ * Dynamic Clock: Always Running
+ * Memory Burst length: 8
+ * Number of chips: 1
+ * Memory Bus width: 32 bit
+ * Memory Type: DDR3
+ * Additional Latancy for PLL: 0 Cycle
+ */
+ .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
+ DMC_MEMCONTROL_DPWRDN_DISABLE |
+ DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
+ DMC_MEMCONTROL_DSREF_DISABLE |
+ DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
+ DMC_MEMCONTROL_MEM_TYPE_DDR3 |
+ DMC_MEMCONTROL_MEM_WIDTH_32BIT |
+ DMC_MEMCONTROL_NUM_CHIP_1 |
+ DMC_MEMCONTROL_BL_8 |
+ DMC_MEMCONTROL_PZQ_DISABLE |
+ DMC_MEMCONTROL_MRR_BYTE_7_0,
+ /*
+ * For channel interleaving, the chip_base needs to be set to
+ * half the bus address. So for a base address of 0x2000_0000,
+ * the chip_base value is 0x20 without interleaving and 0x10
+ * with channel interleaving. See note in section 17.14.
+ */
+ .membaseconfig0 = (0x10 << 16) | DMC_CHIP_MASK_1GB,
+ .memconfig = DMC_MEMCONFIG_CHIP_MAP_SPLIT |
+ DMC_MEMCONFIGx_CHIP_COL_10 |
+ DMC_MEMCONFIGx_CHIP_ROW_15 |
+ DMC_MEMCONFIGx_CHIP_BANK_8,
+ .prechconfig_tp_cnt = 0xff,
+ .dpwrdn_cyc = 0xff,
+ .dsref_cyc = 0xffff,
+ .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
+ DMC_CONCONTROL_TIMEOUT_LEVEL0 |
+ DMC_CONCONTROL_RD_FETCH_DISABLE |
+ DMC_CONCONTROL_AREF_EN_DISABLE |
+ DMC_CONCONTROL_IO_PD_CON_DISABLE,
+ .dmc_channels = 1,
+ .chips_per_channel = 1,
+ .chips_to_configure = 1,
+ .send_zq_init = 1,
+ .gate_leveling_enable = 1,
+};
diff --git a/src/mainboard/google/peach_pit/romstage.c b/src/mainboard/google/peach_pit/romstage.c
new file mode 100644
index 0000000..16dc997
--- /dev/null
+++ b/src/mainboard/google/peach_pit/romstage.c
@@ -0,0 +1,279 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <stdlib.h>
+
+#include <armv7.h>
+#include <cbfs.h>
+#include <cbmem.h>
+
+#include <arch/cache.h>
+#include <arch/exception.h>
+#include <soc/samsung/exynos5420/i2c.h>
+#include <soc/samsung/exynos5420/clk.h>
+#include <soc/samsung/exynos5420/cpu.h>
+#include <soc/samsung/exynos5420/dmc.h>
+#include <soc/samsung/exynos5420/gpio.h>
+#include <soc/samsung/exynos5420/setup.h>
+#include <soc/samsung/exynos5420/periph.h>
+#include <soc/samsung/exynos5420/power.h>
+#include <soc/samsung/exynos5420/trustzone.h>
+#include <soc/samsung/exynos5420/wakeup.h>
+#include <console/console.h>
+#include <arch/stages.h>
+
+#include <drivers/maxim/max77802/max77802.h>
+#include <device/i2c.h>
+
+#define PMIC_I2C_BUS 4
+
+struct pmic_write
+{
+ int or_orig; // Whether to or in the original value.
+ uint8_t reg; // Register to write.
+ uint8_t val; // Value to write.
+};
+
+/*
+ * Use read-modify-write for MAX77802 control registers and clobber the
+ * output voltage setting (BUCK?DVS?) registers.
+ */
+struct pmic_write pmic_writes[] =
+{
+ { 1, MAX77802_REG_PMIC_32KHZ, MAX77802_32KHCP_EN },
+ { 0, MAX77802_REG_PMIC_BUCK1DVS1, MAX77802_BUCK1DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK1CTRL, MAX77802_BUCK_TYPE1_ON |
+ MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK2DVS1, MAX77802_BUCK2DVS1_1_2625V },
+ { 1, MAX77802_REG_PMIC_BUCK2CTRL1, MAX77802_BUCK_TYPE2_ON |
+ MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK3DVS1, MAX77802_BUCK3DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK3CTRL1, MAX77802_BUCK_TYPE2_ON |
+ MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK4DVS1, MAX77802_BUCK4DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK4CTRL1, MAX77802_BUCK_TYPE2_ON |
+ MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK6DVS1, MAX77802_BUCK6DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK6CTRL, MAX77802_BUCK_TYPE1_ON |
+ MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
+ /* Disable Boost(bypass) OUTPUT */
+ { 0, MAX77802_REG_PMIC_BOOSTCTRL, MAX77802_BOOSTCTRL_OFF},
+};
+
+static int setup_power(int is_resume)
+{
+ int error = 0;
+ int i;
+
+ power_init();
+
+ if (is_resume) {
+ return 0;
+ }
+
+ /* Initialize I2C bus to configure PMIC. */
+ exynos_pinmux_i2c4();
+ i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
+
+ for (i = 0; i < ARRAY_SIZE(pmic_writes); i++) {
+ uint8_t data = 0;
+ uint8_t reg = pmic_writes[i].reg;
+
+ if (pmic_writes[i].or_orig)
+ error |= i2c_read(4, MAX77802_I2C_ADDR,
+ reg, sizeof(reg),
+ &data, sizeof(data));
+ data |= pmic_writes[i].val;
+ error |= i2c_write(4, MAX77802_I2C_ADDR,
+ reg, sizeof(reg),
+ &data, sizeof(data));
+ }
+
+ return error;
+}
+
+static void setup_ec(void)
+{
+ /* SPI2 (EC) is slower and needs to work in half-duplex mode with
+ * single byte bus width. */
+ clock_set_rate(PERIPH_ID_SPI2, 5000000);
+ exynos_pinmux_spi2();
+}
+
+static void setup_gpio(void)
+{
+ gpio_direction_input(GPIO_X30); // WP_GPIO
+ gpio_set_pull(GPIO_X30, GPIO_PULL_NONE);
+
+ gpio_direction_input(GPIO_X07); // RECMODE_GPIO
+ gpio_set_pull(GPIO_X07, GPIO_PULL_NONE);
+
+ gpio_direction_input(GPIO_X34); // LID_GPIO
+ gpio_set_pull(GPIO_X34, GPIO_PULL_NONE);
+
+ gpio_direction_input(GPIO_X12); // POWER_GPIO
+ gpio_set_pull(GPIO_X12, GPIO_PULL_NONE);
+}
+
+static void setup_memory(struct mem_timings *mem, int is_resume)
+{
+ printk(BIOS_SPEW, "manufacturer: 0x%x type: 0x%x, div: 0x%x, mhz: %d\n",
+ mem->mem_manuf,
+ mem->mem_type,
+ mem->mpll_mdiv,
+ mem->frequency_mhz);
+
+ if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
+ die("Failed to initialize memory controller.\n");
+ }
+}
+
+#define PRIMITIVE_MEM_TEST 0
+#if PRIMITIVE_MEM_TEST
+static unsigned long primitive_mem_test(void)
+{
+ unsigned long *l = (void *)0x40000000;
+ int bad = 0;
+ unsigned long i;
+ for(i = 0; i < 256*1048576; i++){
+ if (! (i%1048576))
+ printk(BIOS_SPEW, "%lu ...", i);
+ l[i] = 0xffffffff - i;
+ }
+
+ for(i = 0; i < 256*1048576; i++){
+ if (! (i%1048576))
+ printk(BIOS_SPEW, "%lu ...", i);
+ if (l[i] != (0xffffffff - i)){
+ printk(BIOS_SPEW, "%p: want %08lx got %08lx\n", l, l[i], 0xffffffff - i);
+ bad++;
+ }
+ }
+
+ printk(BIOS_SPEW, "%d errors\n", bad);
+
+ return bad;
+}
+#else
+#define primitive_mem_test()
+#endif
+
+#define SIMPLE_SPI_TEST 0
+#if SIMPLE_SPI_TEST
+/* here is a simple SPI debug test, known to fid trouble */
+static void simple_spi_test(void)
+{
+ struct cbfs_media default_media, *media;
+ int i, amt = 4 * MiB, errors = 0;
+ //u32 *data = (void *)0x40000000;
+ u32 data[1024];
+ u32 in;
+
+ amt = sizeof(data);
+ media = &default_media;
+ if (init_default_cbfs_media(media) != 0) {
+ printk(BIOS_SPEW, "Failed to initialize default media.\n");
+ return;
+ }
+
+
+ media->open(media);
+ if (media->read(media, data, (size_t) 0, amt) < amt){
+ printk(BIOS_SPEW, "simple_spi_test fails\n");
+ return;
+ }
+
+
+ for(i = 0; i < amt; i += 4){
+ if (media->read(media, &in, (size_t) i, 4) < 1){
+ printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
+ return;
+ }
+ if (data[i/4] != in){
+ errors++;
+ printk(BIOS_SPEW, "BAD at %d(%p):\nRAM %08lx\nSPI %08lx\n",
+ i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
+ /* reread it to see which is wrong. */
+ if (media->read(media, &in, (size_t) i, 4) < 1){
+ printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
+ return;
+ }
+ printk(BIOS_SPEW, "RTRY at %d(%p):\nRAM %08lx\nSPI %08lx\n",
+ i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
+ }
+
+ }
+ printk(BIOS_SPEW, "%d errors\n", errors);
+}
+#else
+#define simple_spi_test()
+#endif
+
+void main(void)
+{
+
+ extern struct mem_timings mem_timings;
+ void *entry;
+ int is_resume = (get_wakeup_state() != IS_NOT_WAKEUP);
+ int power_init_failed;
+
+ exynos5420_config_smp();
+ power_init_failed = setup_power(is_resume);
+
+ /* Clock must be initialized before console_init, otherwise you may need
+ * to re-initialize serial console drivers again. */
+ system_clock_init();
+
+ exynos_pinmux_uart3();
+ console_init();
+ exception_init();
+
+ if (power_init_failed)
+ die("Failed to intialize power.\n");
+
+ /* re-initialize PMIC I2C channel after (re-)setting system clocks */
+ i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
+
+ setup_memory(&mem_timings, is_resume);
+
+ primitive_mem_test();
+
+ trustzone_init();
+
+ if (is_resume) {
+ wakeup();
+ }
+
+ setup_gpio();
+ setup_ec();
+
+ simple_spi_test();
+ /* Set SPI (primary CBFS media) clock to 50MHz. */
+ /* if this is uncommented SPI will not work correctly. */
+ clock_set_rate(PERIPH_ID_SPI1, 50000000);
+ exynos_pinmux_spi1();
+ simple_spi_test();
+
+ cbmem_initialize_empty();
+
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/ramstage");
+ simple_spi_test();
+ stage_exit(entry);
+}
diff --git a/src/mainboard/google/peach_pit/wakeup.c b/src/mainboard/google/peach_pit/wakeup.c
new file mode 100644
index 0000000..130282c
--- /dev/null
+++ b/src/mainboard/google/peach_pit/wakeup.c
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <soc/samsung/exynos5420/gpio.h>
+#include <soc/samsung/exynos5420/wakeup.h>
+
+int wakeup_need_reset(void)
+{
+ /* The "wake up" event is not reliable (known as "bad wakeup") and needs
+ * reset if the TPM reset mask GPIO value is high. */
+ return gpio_get_value(GPIO_X06);
+}
diff --git a/src/mainboard/google/pit/Kconfig b/src/mainboard/google/pit/Kconfig
deleted file mode 100644
index 5196c2c..0000000
--- a/src/mainboard/google/pit/Kconfig
+++ /dev/null
@@ -1,53 +0,0 @@
-##
-## This file is part of the coreboot project.
-##
-## Copyright 2013 Google Inc.
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; version 2 of the License.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-##
-
-if BOARD_GOOGLE_PIT
-
-config BOARD_SPECIFIC_OPTIONS # dummy
- def_bool y
- select CPU_SAMSUNG_EXYNOS5420
- select EC_GOOGLE_CHROMEEC
- select EC_GOOGLE_CHROMEEC_SPI
- select BOARD_ROMSIZE_KB_4096
- select MAINBOARD_HAS_CHROMEOS
- select MAINBOARD_HAS_NATIVE_VGA_INIT
- select MAINBOARD_DO_NATIVE_VGA_INIT
- select DRIVER_PARADE_PS8625
-
-config MAINBOARD_DIR
- string
- default google/pit
-
-config MAINBOARD_PART_NUMBER
- string
- default "Pit"
-
-config DRAM_SIZE_MB
- int
- default 2048
-
-config EC_GOOGLE_CHROMEEC_SPI_BUS
- hex
- default 2
-
-config UART_FOR_CONSOLE
- int
- default 3
-
-endif # BOARD_GOOGLE_PIT
diff --git a/src/mainboard/google/pit/Makefile.inc b/src/mainboard/google/pit/Makefile.inc
deleted file mode 100644
index 2858743..0000000
--- a/src/mainboard/google/pit/Makefile.inc
+++ /dev/null
@@ -1,27 +0,0 @@
-##
-## This file is part of the coreboot project.
-##
-## Copyright 2012 Google Inc.
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; version 2 of the License.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-##
-
-bootblock-y += wakeup.c
-
-romstage-y += memory.c
-romstage-y += romstage.c
-romstage-y += wakeup.c
-
-ramstage-y += mainboard.c
-ramstage-y += chromeos.c
diff --git a/src/mainboard/google/pit/chromeos.c b/src/mainboard/google/pit/chromeos.c
deleted file mode 100644
index 7b0807c..0000000
--- a/src/mainboard/google/pit/chromeos.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <boot/coreboot_tables.h>
-#include <console/console.h>
-#include <ec/google/chromeec/ec.h>
-#include <ec/google/chromeec/ec_commands.h>
-#include <string.h>
-#include <vendorcode/google/chromeos/chromeos.h>
-#include <bootmode.h>
-#include <soc/samsung/exynos5420/cpu.h>
-#include <soc/samsung/exynos5420/gpio.h>
-
-void fill_lb_gpios(struct lb_gpios *gpios)
-{
- int count = 0;
-
- /* Write Protect: active low */
- gpios->gpios[count].port = EXYNOS5_GPX3;
- gpios->gpios[count].polarity = ACTIVE_LOW;
- gpios->gpios[count].value = gpio_get_value(GPIO_X30); // WP_GPIO
- strncpy((char *)gpios->gpios[count].name, "write protect",
- GPIO_MAX_NAME_LENGTH);
- count++;
-
- /* Recovery: active low */
- gpios->gpios[count].port = -1;
- gpios->gpios[count].polarity = ACTIVE_HIGH;
- gpios->gpios[count].value = get_recovery_mode_switch();
- strncpy((char *)gpios->gpios[count].name, "recovery",
- GPIO_MAX_NAME_LENGTH);
- count++;
-
- /* Lid: active high */
- gpios->gpios[count].port = EXYNOS5_GPX3;
- gpios->gpios[count].polarity = ACTIVE_HIGH;
- gpios->gpios[count].value = gpio_get_value(GPIO_X34); // LID_GPIO
- strncpy((char *)gpios->gpios[count].name, "lid", GPIO_MAX_NAME_LENGTH);
- count++;
-
- /* Power: virtual GPIO active low */
- gpios->gpios[count].port = EXYNOS5_GPX1;
- gpios->gpios[count].polarity = ACTIVE_LOW;
- gpios->gpios[count].value =
- gpio_get_value(GPIO_X12); // POWER_GPIO
- strncpy((char *)gpios->gpios[count].name, "power",
- GPIO_MAX_NAME_LENGTH);
- count++;
-
- /* Developer: virtual GPIO active high */
- gpios->gpios[count].port = -1;
- gpios->gpios[count].polarity = ACTIVE_HIGH;
- gpios->gpios[count].value = get_developer_mode_switch();
- strncpy((char *)gpios->gpios[count].name, "developer",
- GPIO_MAX_NAME_LENGTH);
- count++;
-
- gpios->size = sizeof(*gpios) + (count * sizeof(struct lb_gpio));
- gpios->count = count;
-
- printk(BIOS_ERR, "Added %d GPIOS size %d\n", count, gpios->size);
-}
-
-int get_developer_mode_switch(void)
-{
- return 0;
-}
-
-int get_recovery_mode_switch(void)
-{
- uint32_t ec_events;
-
- /* The GPIO is active low. */
- if (!gpio_get_value(GPIO_X07)) // RECMODE_GPIO
- return 1;
-
- ec_events = google_chromeec_get_events_b();
- return !!(ec_events &
- EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
-}
-
-int get_write_protect_state(void)
-{
- return !gpio_get_value(GPIO_X30);
-}
diff --git a/src/mainboard/google/pit/devicetree.cb b/src/mainboard/google/pit/devicetree.cb
deleted file mode 100644
index 568daf8..0000000
--- a/src/mainboard/google/pit/devicetree.cb
+++ /dev/null
@@ -1,33 +0,0 @@
-##
-## This file is part of the coreboot project.
-##
-## Copyright 2012 Google Inc.
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; version 2 of the License.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-##
-
-chip soc/samsung/exynos5420
- device cpu_cluster 0 on end
- register "xres" = "1366"
- register "yres" = "768"
- register "framebuffer_bits_per_pixel" = "16"
- # complex magic timing!
- register "clkval_f" = "2"
- register "upper_margin" = "14"
- register "lower_margin" = "3"
- register "vsync" = "5"
- register "left_margin" = "80"
- register "right_margin" = "48"
- register "hsync" = "32"
-end
diff --git a/src/mainboard/google/pit/mainboard.c b/src/mainboard/google/pit/mainboard.c
deleted file mode 100644
index c07db7b..0000000
--- a/src/mainboard/google/pit/mainboard.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <string.h>
-#include <console/console.h>
-#include <device/device.h>
-#include <device/i2c.h>
-#include <cbmem.h>
-#include <delay.h>
-#include <edid.h>
-#include <vbe.h>
-#include <boot/coreboot_tables.h>
-#include <arch/cache.h>
-#include <soc/samsung/exynos5420/tmu.h>
-#include <soc/samsung/exynos5420/clk.h>
-#include <soc/samsung/exynos5420/cpu.h>
-#include <soc/samsung/exynos5420/gpio.h>
-#include <soc/samsung/exynos5420/power.h>
-#include <soc/samsung/exynos5420/i2c.h>
-#include <soc/samsung/exynos5420/dp.h>
-#include <soc/samsung/exynos5420/fimd.h>
-#include <soc/samsung/exynos5420/usb.h>
-#include <drivers/parade/ps8625/ps8625.h>
-#include <ec/google/chromeec/ec.h>
-#include <stdlib.h>
-
-/* convenient shorthand (in MB) */
-#define DRAM_START (CONFIG_SYS_SDRAM_BASE >> 20)
-#define DRAM_SIZE CONFIG_DRAM_SIZE_MB
-
-/* Arbitrary range of DMA memory for depthcharge's drivers */
-#define DMA_START (0x77300000)
-#define DMA_SIZE (0x00100000)
-
-static struct edid edid = {
- .ha = 1366,
- .va = 768,
- .framebuffer_bits_per_pixel = 16,
- .x_resolution = 1366,
- .y_resolution = 768,
- .bytes_per_line = 2 * 1366
-};
-
-/* from the fdt */
-static struct vidinfo vidinfo = {
- .vl_freq = 60,
- .vl_col = 1366,
- .vl_row = 768,
- .vl_width = 1366,
- .vl_height = 768,
- .vl_clkp = 1,
- .vl_dp = 1,
- .vl_bpix = 4,
- .vl_hspw = 32,
- .vl_hbpd = 40,
- .vl_hfpd = 40,
- .vl_vspw = 6,
- .vl_vbpd = 10,
- .vl_vfpd = 12,
- .vl_cmd_allow_len = 0xf,
- .win_id = 3,
- .dp_enabled = 1,
- .dual_lcd_enabled = 0,
- .interface_mode = FIMD_RGB_INTERFACE,
-};
-
-static unsigned char panel_edid[] = {
- 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
- 0x06,0xaf,0x5c,0x31,0x00,0x00,0x00,0x00,
- 0x00,0x16,0x01,0x03,0x80,0x1a,0x0e,0x78,
- 0x0a,0x99,0x85,0x95,0x55,0x56,0x92,0x28,
- 0x22,0x50,0x54,0x00,0x00,0x00,0x01,0x01,
- 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
- 0x01,0x01,0x01,0x01,0x01,0x01,0xa3,0x1b,
- 0x56,0x7e,0x50,0x00,0x16,0x30,0x30,0x20,
- 0x36,0x00,0x00,0x90,0x10,0x00,0x00,0x18,
- 0x6d,0x12,0x56,0x7e,0x50,0x00,0x16,0x30,
- 0x30,0x20,0x36,0x00,0x00,0x90,0x10,0x00,
- 0x00,0x18,0x00,0x00,0x00,0xfe,0x00,0x41,
- 0x55,0x4f,0x0a,0x20,0x20,0x20,0x20,0x20,
- 0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xfe,
- 0x00,0x42,0x31,0x31,0x36,0x58,0x57,0x30,
- 0x33,0x20,0x56,0x31,0x20,0x0a,0x00,0x3d,
- 0x00,0xc0,0x00,0x00,0x27,0xfd,0x00,0x20,
- 0x02,0x59,0x07,0x00,0x64,0x3e,0x07,0x02,
- 0x00,0x00,0xcd,0x12,0x59,0xff,0x10,0x03,
- 0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
- 0x9c,0x3f,0x07,0x02,0x31,0xf9,0x00,0x20,
- 0x59,0xff,0x10,0x03,0x00,0x00,0x00,0x00,
- 0xbc,0x3e,0x07,0x02,0xc0,0x9b,0x01,0x20,
- 0x00,0x00,0x00,0x00,0xdb,0xf8,0x00,0x20,
- 0x98,0x3e,0x07,0x02,0x8b,0xaf,0x00,0x20,
- 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xe5,0xcd,0x16,0x00,0xe9,0xcd,0x16,0x00,
- 0xe8,0x03,0x00,0x00,0x6c,0x55,0x01,0x20,
- 0x2c,0x01,0x00,0x00,0x85,0xbb,0x00,0x20,
- 0xe8,0x03,0x00,0x00,0xe9,0xcd,0x16,0x00,
-};
-
-static const struct parade_write parade_writes[] = {
- { 0x02, 0xa1, 0x01 }, /* HPD low */
- /*
- * SW setting
- * [1:0] SW output 1.2V voltage is lower to 96%
- */
- { 0x04, 0x14, 0x01 },
- /*
- * RCO SS setting
- * [5:4] = b01 0.5%, b10 1%, b11 1.5%
- */
- { 0x04, 0xe3, 0x20 },
- { 0x04, 0xe2, 0x80 }, /* [7] RCO SS enable */
- /*
- * RPHY Setting
- * [3:2] CDR tune wait cycle before
- * measure for fine tune b00: 1us,
- * 01: 0.5us, 10:2us, 11:4us.
- */
- { 0x04, 0x8a, 0x0c },
- { 0x04, 0x89, 0x08 }, /* [3] RFD always on */
- /*
- * CTN lock in/out:
- * 20000ppm/80000ppm. Lock out 2
- * times.
- */
- { 0x04, 0x71, 0x2d },
- /*
- * 2.7G CDR settings
- * NOF=40LSB for HBR CDR setting
- */
- { 0x04, 0x7d, 0x07 },
- { 0x04, 0x7b, 0x00 }, /* [1:0] Fmin=+4bands */
- { 0x04, 0x7a, 0xfd }, /* [7:5] DCO_FTRNG=+-40% */
- /*
- * 1.62G CDR settings
- * [5:2]NOF=64LSB [1:0]DCO scale is 2/5
- */
- { 0x04, 0xc0, 0x12 },
- { 0x04, 0xc1, 0x92 }, /* Gitune=-37% */
- { 0x04, 0xc2, 0x1c }, /* Fbstep=100% */
- { 0x04, 0x32, 0x80 }, /* [7] LOS signal disable */
- /*
- * RPIO Setting
- * [7:4] LVDS driver bias current :
- * 75% (250mV swing)
- */
- { 0x04, 0x00, 0xb0 },
- /*
- * [7:6] Right-bar GPIO output strength is 8mA
- */
- { 0x04, 0x15, 0x40 },
- /* EQ Training State Machine Setting */
- { 0x04, 0x54, 0x10 }, /* RCO calibration start */
- /* [4:0] MAX_LANE_COUNT set to one lane */
- { 0x01, 0x02, 0x81 },
- /* [4:0] LANE_COUNT_SET set to one lane */
- { 0x01, 0x21, 0x81 },
- { 0x00, 0x52, 0x20 },
- { 0x00, 0xf1, 0x03 }, /* HPD CP toggle enable */
- { 0x00, 0x62, 0x41 },
- /* Counter number, add 1ms counter delay */
- { 0x00, 0xf6, 0x01 },
- /*
- * [6]PWM function control by
- * DPCD0040f[7], default is PWM
- * block always works.
- */
- { 0x00, 0x77, 0x06 },
- /*
- * 04h Adjust VTotal tolerance to
- * fix the 30Hz no display issue
- */
- { 0x00, 0x4c, 0x04 },
- /* DPCD00400='h00, Parade OUI = 'h001cf8 */
- { 0x01, 0xc0, 0x00 },
- { 0x01, 0xc1, 0x1c }, /* DPCD00401='h1c */
- { 0x01, 0xc2, 0xf8 }, /* DPCD00402='hf8 */
- /*
- * DPCD403~408 = ASCII code
- * D2SLV5='h4432534c5635
- */
- { 0x01, 0xc3, 0x44 },
- { 0x01, 0xc4, 0x32 }, /* DPCD404 */
- { 0x01, 0xc5, 0x53 }, /* DPCD405 */
- { 0x01, 0xc6, 0x4c }, /* DPCD406 */
- { 0x01, 0xc7, 0x56 }, /* DPCD407 */
- { 0x01, 0xc8, 0x35 }, /* DPCD408 */
- /*
- * DPCD40A, Initial Code major revision
- * '01'
- */
- { 0x01, 0xca, 0x01 },
- /* DPCD40B, Initial Code minor revision '05' */
- { 0x01, 0xcb, 0x05 },
- /* DPCD720, Select external PWM */
- { 0x01, 0xa5, 0x80 },
- /*
- * Set LVDS output as 6bit-VESA mapping,
- * single LVDS channel
- */
- { 0x01, 0xcc, 0x13 },
- /* Enable SSC set by register */
- { 0x02, 0xb1, 0x20 },
- /*
- * Set SSC enabled and +/-1% central
- * spreading
- */
- { 0x04, 0x10, 0x16 },
- /* MPU Clock source: LC => RCO */
- { 0x04, 0x59, 0x60 },
- { 0x04, 0x54, 0x14 }, /* LC -> RCO */
- { 0x02, 0xa1, 0x91 } /* HPD high */
-};
-
-/* TODO: transplanted DP stuff, clean up once we have something that works */
-static enum exynos5_gpio_pin dp_pd_l = GPIO_X35; /* active low */
-static enum exynos5_gpio_pin dp_rst_l = GPIO_Y77; /* active low */
-static enum exynos5_gpio_pin dp_hpd = GPIO_X26; /* active high */
-static enum exynos5_gpio_pin bl_pwm = GPIO_B20; /* active high */
-static enum exynos5_gpio_pin bl_en = GPIO_X22; /* active high */
-
-static void parade_dp_bridge_setup(void)
-{
- int i;
-
- gpio_set_value(dp_pd_l, 1);
- gpio_cfg_pin(dp_pd_l, GPIO_OUTPUT);
- gpio_set_pull(dp_pd_l, GPIO_PULL_NONE);
-
- gpio_set_value(dp_rst_l, 0);
- gpio_cfg_pin(dp_rst_l, GPIO_OUTPUT);
- gpio_set_pull(dp_rst_l, GPIO_PULL_NONE);
- udelay(10);
- gpio_set_value(dp_rst_l, 1);
-
-
- gpio_set_pull(dp_hpd, GPIO_PULL_NONE);
- gpio_cfg_pin(dp_hpd, GPIO_INPUT);
-
- /* De-assert PD (and possibly RST) to power up the bridge. */
- gpio_set_value(dp_pd_l, 1);
- gpio_set_value(dp_rst_l, 1);
-
- /* Hang around for the bridge to come up. */
- mdelay(40);
-
- /* Configure the bridge chip. */
- exynos_pinmux_i2c7();
- i2c_init(7, 100000, 0x00);
-
- parade_ps8625_bridge_setup(7, 0x48, parade_writes,
- ARRAY_SIZE(parade_writes));
- /* Spin until the display is ready.
- * It's quite important to try really hard to get the display up,
- * so be generous. It will typically be ready in only 5 ms. and
- * we're out of here.
- * If it's not ready after a second, then we're in big trouble.
- */
- for(i = 0; i < 1000; i++){
- if (gpio_get_value(dp_hpd))
- break;
- mdelay(1);
- }
-}
-
-/*
- * This delay is T3 in the LCD timing spec (defined as >200ms). We set
- * this down to 60ms since that's the approximate maximum amount of time
- * it'll take a bridge to start outputting LVDS data. The delay of
- * >200ms is just a conservative value to avoid turning on the backlight
- * when there's random LCD data on the screen. Shaving 140ms off the
- * boot is an acceptable trade-off.
- */
-#define LCD_T3_DELAY_MS 60
-
-#define LCD_T5_DELAY_MS 10
-#define LCD_T6_DELAY_MS 10
-
-static void backlight_pwm(void)
-{
- /*Configure backlight PWM as a simple output high (100% brightness) */
- gpio_direction_output(bl_pwm, 1);
- udelay(LCD_T6_DELAY_MS * 1000);
-}
-
-static void backlight_en(void)
-{
- /* Configure GPIO for LCD_BL_EN */
- gpio_direction_output(bl_en, 1);
-}
-
-static enum exynos5_gpio_pin usb_drd0_vbus = GPIO_H00;
-static enum exynos5_gpio_pin usb_drd1_vbus = GPIO_H01;
-/* static enum exynos5_gpio_pin hsic_reset_l = GPIO_X24; */
-
-static void prepare_usb(void)
-{
- /* Kick these resets off early so they get at least 100ms to settle */
- reset_usb_drd0_dwc3();
- reset_usb_drd1_dwc3();
-}
-
-static void setup_usb(void)
-{
- /* HSIC and USB HOST port not needed in firmware on this board */
- setup_usb_drd0_phy();
- setup_usb_drd1_phy();
-
- setup_usb_drd0_dwc3();
- setup_usb_drd1_dwc3();
-
- gpio_direction_output(usb_drd0_vbus, 1);
- gpio_direction_output(usb_drd1_vbus, 1);
-}
-
-static struct edp_video_info dp_video_info = {
- .master_mode = 0,
- .h_sync_polarity = 0,
- .v_sync_polarity = 0,
- .interlaced = 0,
- .color_space = COLOR_RGB,
- .dynamic_range = VESA,
- .ycbcr_coeff = COLOR_YCBCR601,
- .color_depth = COLOR_8,
-};
-
-/* FIXME: move some place more appropriate */
-#define MAX_DP_TRIES 5
-
-static void setup_storage(void)
-{
- /* MMC0: Fixed, 8 bit mode, connected with GPIO. */
- if (clock_set_dwmci(PERIPH_ID_SDMMC0))
- printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
- exynos_pinmux_sdmmc0();
-
- /* MMC2: Removable, 4 bit mode, no GPIO. */
- /* (Must be after romstage to avoid breaking SDMMC boot.) */
- clock_set_dwmci(PERIPH_ID_SDMMC2);
- exynos_pinmux_sdmmc2();
-}
-
-static void gpio_init(void)
-{
- /* Set up the I2C busses. */
- exynos_pinmux_i2c2();
- exynos_pinmux_i2c4();
- exynos_pinmux_i2c7();
- exynos_pinmux_i2c8();
- exynos_pinmux_i2c9();
- exynos_pinmux_i2c10();
-}
-
-enum {
- FET_CTRL_WAIT = 3 << 2,
- FET_CTRL_ADENFET = 1 << 1,
- FET_CTRL_ENFET = 1 << 0
-};
-
-static void tps65090_thru_ec_fet_set(int index)
-{
- uint8_t value = FET_CTRL_ADENFET | FET_CTRL_WAIT | FET_CTRL_ENFET;
-
- if (google_chromeec_i2c_xfer(0x48, 0xe + index, 1, &value, 1, 0)) {
- printk(BIOS_ERR,
- "Error sending i2c pass through command to EC.\n");
- return;
- }
-}
-
-static void lcd_vdd(void)
-{
- /* Enable FET6, lcd panel */
- tps65090_thru_ec_fet_set(6);
-}
-
-static void backlight_vdd(void)
-{
- /* Enable FET1, backlight */
- tps65090_thru_ec_fet_set(1);
-}
-
-static void sdmmc_vdd(void)
-{
- /* Enable FET4, P3.3V_SDCARD */
- tps65090_thru_ec_fet_set(4);
-}
-
-/* this happens after cpu_init where exynos resources are set */
-static void mainboard_init(device_t dev)
-{
- /* we'll stick with the crummy u-boot struct for now.*/
- /* doing this as an auto since the struct has to be writeable */
- struct edp_device_info device_info;
-
- void *fb_addr = (void *)(get_fb_base_kb() * KiB);
-
- prepare_usb();
- gpio_init();
- setup_storage();
- tmu_init(&exynos5420_tmu_info);
-
- /* Clock Gating all the unused IP's to save power */
- clock_gate();
-
- sdmmc_vdd();
-
- set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);
-
- /*
- * The reset value for FIMD SYSMMU register MMU_CTRL:0x14640000
- * should be 0 according to the datasheet, but has experimentally
- * been found to come up as 3. This means FIMD SYSMMU is on by
- * default on Exynos5420. For now we are disabling FIMD SYSMMU.
- */
- writel(0x0, (void *)0x14640000);
- writel(0x0, (void *)0x14680000);
-
- lcd_vdd();
-
- /* Start the fimd running before you do the phy and lcd setup.
- * why do fimd before training etc?
- * because we need a data stream from
- * the fimd or the clock recovery step fails.
- */
- vidinfo.screen_base = fb_addr;
- exynos_fimd_lcd_init(&vidinfo);
-
- parade_dp_bridge_setup();
-
- /* this might get more dynamic in future ... */
- memset(&device_info, 0, sizeof(device_info));
- device_info.disp_info.name = (char *)"Pit display";
- device_info.disp_info.h_total = 1366;
- device_info.disp_info.v_total = 768;
- device_info.video_info = dp_video_info;
- device_info.raw_edid = panel_edid;
- exynos_init_dp(&device_info);
-
- backlight_vdd();
- backlight_pwm();
- backlight_en();
-
- setup_usb();
-}
-
-static void mainboard_enable(device_t dev)
-{
- dev->ops->init = &mainboard_init;
-
- /* set up caching for the DRAM */
- mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
- mmu_config_range(DMA_START >> 20, DMA_SIZE >> 20, DCACHE_OFF);
- tlb_invalidate_all();
-
- const unsigned epll_hz = 192000000;
- const unsigned sample_rate = 48000;
- const unsigned lr_frame_size = 256;
- clock_epll_set_rate(epll_hz);
- clock_select_i2s_clk_source();
- clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);
-
- power_enable_xclkout();
-}
-
-struct chip_operations mainboard_ops = {
- .name = "Samsung/Google ARM Chromebook",
- .enable_dev = mainboard_enable,
-};
-
-void lb_board(struct lb_header *header)
-{
- struct lb_range *dma;
-
- dma = (struct lb_range *)lb_new_record(header);
- dma->tag = LB_TAB_DMA;
- dma->size = sizeof(*dma);
- dma->range_start = (intptr_t)DMA_START;
- dma->range_size = DMA_SIZE;
-}
diff --git a/src/mainboard/google/pit/memory.c b/src/mainboard/google/pit/memory.c
deleted file mode 100644
index 8a9f454..0000000
--- a/src/mainboard/google/pit/memory.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Samsung Electronics
- * Copyright 2013 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <console/console.h>
-
-#include <soc/samsung/exynos5420/gpio.h>
-#include <soc/samsung/exynos5420/dmc.h>
-#include <soc/samsung/exynos5420/setup.h>
-#include <soc/samsung/exynos5420/clk.h>
-
-const struct mem_timings mem_timings = {
- .mem_manuf = MEM_MANUF_SAMSUNG,
- .mem_type = DDR_MODE_DDR3,
- .frequency_mhz = 800,
- .direct_cmd_msr = {
- 0x00020018, 0x00030000, 0x00010046, 0x00000d70,
- 0x00000c70
- },
- .timing_ref = 0x000000bb,
- .timing_row = 0x6836650f,
- .timing_data = 0x3630580b,
- .timing_power = 0x41000a26,
- .phy0_dqs = 0x08080808,
- .phy1_dqs = 0x08080808,
- .phy0_dq = 0x08080808,
- .phy1_dq = 0x08080808,
- .phy0_tFS = 0x8,
- .phy1_tFS = 0x8,
- .phy0_pulld_dqs = 0xf,
- .phy1_pulld_dqs = 0xf,
-
- .lpddr3_ctrl_phy_reset = 0x1,
- .ctrl_start_point = 0x10,
- .ctrl_inc = 0x10,
- .ctrl_start = 0x1,
- .ctrl_dll_on = 0x1,
- .ctrl_ref = 0x8,
-
- .ctrl_force = 0x1a,
- .ctrl_rdlat = 0x0b,
- .ctrl_bstlen = 0x08,
-
- .fp_resync = 0x8,
- .iv_size = 0x7,
- .dfi_init_start = 1,
- .aref_en = 1,
-
- .rd_fetch = 0x3,
-
- .zq_mode_dds = 0x7,
- .zq_mode_term = 0x1,
- .zq_mode_noterm = 1,
-
- /*
- * Dynamic Clock: Always Running
- * Memory Burst length: 8
- * Number of chips: 1
- * Memory Bus width: 32 bit
- * Memory Type: DDR3
- * Additional Latancy for PLL: 0 Cycle
- */
- .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
- DMC_MEMCONTROL_DPWRDN_DISABLE |
- DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
- DMC_MEMCONTROL_DSREF_DISABLE |
- DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
- DMC_MEMCONTROL_MEM_TYPE_DDR3 |
- DMC_MEMCONTROL_MEM_WIDTH_32BIT |
- DMC_MEMCONTROL_NUM_CHIP_1 |
- DMC_MEMCONTROL_BL_8 |
- DMC_MEMCONTROL_PZQ_DISABLE |
- DMC_MEMCONTROL_MRR_BYTE_7_0,
- /*
- * For channel interleaving, the chip_base needs to be set to
- * half the bus address. So for a base address of 0x2000_0000,
- * the chip_base value is 0x20 without interleaving and 0x10
- * with channel interleaving. See note in section 17.14.
- */
- .membaseconfig0 = (0x10 << 16) | DMC_CHIP_MASK_1GB,
- .memconfig = DMC_MEMCONFIG_CHIP_MAP_SPLIT |
- DMC_MEMCONFIGx_CHIP_COL_10 |
- DMC_MEMCONFIGx_CHIP_ROW_15 |
- DMC_MEMCONFIGx_CHIP_BANK_8,
- .prechconfig_tp_cnt = 0xff,
- .dpwrdn_cyc = 0xff,
- .dsref_cyc = 0xffff,
- .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
- DMC_CONCONTROL_TIMEOUT_LEVEL0 |
- DMC_CONCONTROL_RD_FETCH_DISABLE |
- DMC_CONCONTROL_AREF_EN_DISABLE |
- DMC_CONCONTROL_IO_PD_CON_DISABLE,
- .dmc_channels = 1,
- .chips_per_channel = 1,
- .chips_to_configure = 1,
- .send_zq_init = 1,
- .gate_leveling_enable = 1,
-};
diff --git a/src/mainboard/google/pit/romstage.c b/src/mainboard/google/pit/romstage.c
deleted file mode 100644
index 16dc997..0000000
--- a/src/mainboard/google/pit/romstage.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <types.h>
-#include <stdlib.h>
-
-#include <armv7.h>
-#include <cbfs.h>
-#include <cbmem.h>
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <soc/samsung/exynos5420/i2c.h>
-#include <soc/samsung/exynos5420/clk.h>
-#include <soc/samsung/exynos5420/cpu.h>
-#include <soc/samsung/exynos5420/dmc.h>
-#include <soc/samsung/exynos5420/gpio.h>
-#include <soc/samsung/exynos5420/setup.h>
-#include <soc/samsung/exynos5420/periph.h>
-#include <soc/samsung/exynos5420/power.h>
-#include <soc/samsung/exynos5420/trustzone.h>
-#include <soc/samsung/exynos5420/wakeup.h>
-#include <console/console.h>
-#include <arch/stages.h>
-
-#include <drivers/maxim/max77802/max77802.h>
-#include <device/i2c.h>
-
-#define PMIC_I2C_BUS 4
-
-struct pmic_write
-{
- int or_orig; // Whether to or in the original value.
- uint8_t reg; // Register to write.
- uint8_t val; // Value to write.
-};
-
-/*
- * Use read-modify-write for MAX77802 control registers and clobber the
- * output voltage setting (BUCK?DVS?) registers.
- */
-struct pmic_write pmic_writes[] =
-{
- { 1, MAX77802_REG_PMIC_32KHZ, MAX77802_32KHCP_EN },
- { 0, MAX77802_REG_PMIC_BUCK1DVS1, MAX77802_BUCK1DVS1_1V },
- { 1, MAX77802_REG_PMIC_BUCK1CTRL, MAX77802_BUCK_TYPE1_ON |
- MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
- { 0, MAX77802_REG_PMIC_BUCK2DVS1, MAX77802_BUCK2DVS1_1_2625V },
- { 1, MAX77802_REG_PMIC_BUCK2CTRL1, MAX77802_BUCK_TYPE2_ON |
- MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
- { 0, MAX77802_REG_PMIC_BUCK3DVS1, MAX77802_BUCK3DVS1_1V },
- { 1, MAX77802_REG_PMIC_BUCK3CTRL1, MAX77802_BUCK_TYPE2_ON |
- MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
- { 0, MAX77802_REG_PMIC_BUCK4DVS1, MAX77802_BUCK4DVS1_1V },
- { 1, MAX77802_REG_PMIC_BUCK4CTRL1, MAX77802_BUCK_TYPE2_ON |
- MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
- { 0, MAX77802_REG_PMIC_BUCK6DVS1, MAX77802_BUCK6DVS1_1V },
- { 1, MAX77802_REG_PMIC_BUCK6CTRL, MAX77802_BUCK_TYPE1_ON |
- MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
- /* Disable Boost(bypass) OUTPUT */
- { 0, MAX77802_REG_PMIC_BOOSTCTRL, MAX77802_BOOSTCTRL_OFF},
-};
-
-static int setup_power(int is_resume)
-{
- int error = 0;
- int i;
-
- power_init();
-
- if (is_resume) {
- return 0;
- }
-
- /* Initialize I2C bus to configure PMIC. */
- exynos_pinmux_i2c4();
- i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
-
- for (i = 0; i < ARRAY_SIZE(pmic_writes); i++) {
- uint8_t data = 0;
- uint8_t reg = pmic_writes[i].reg;
-
- if (pmic_writes[i].or_orig)
- error |= i2c_read(4, MAX77802_I2C_ADDR,
- reg, sizeof(reg),
- &data, sizeof(data));
- data |= pmic_writes[i].val;
- error |= i2c_write(4, MAX77802_I2C_ADDR,
- reg, sizeof(reg),
- &data, sizeof(data));
- }
-
- return error;
-}
-
-static void setup_ec(void)
-{
- /* SPI2 (EC) is slower and needs to work in half-duplex mode with
- * single byte bus width. */
- clock_set_rate(PERIPH_ID_SPI2, 5000000);
- exynos_pinmux_spi2();
-}
-
-static void setup_gpio(void)
-{
- gpio_direction_input(GPIO_X30); // WP_GPIO
- gpio_set_pull(GPIO_X30, GPIO_PULL_NONE);
-
- gpio_direction_input(GPIO_X07); // RECMODE_GPIO
- gpio_set_pull(GPIO_X07, GPIO_PULL_NONE);
-
- gpio_direction_input(GPIO_X34); // LID_GPIO
- gpio_set_pull(GPIO_X34, GPIO_PULL_NONE);
-
- gpio_direction_input(GPIO_X12); // POWER_GPIO
- gpio_set_pull(GPIO_X12, GPIO_PULL_NONE);
-}
-
-static void setup_memory(struct mem_timings *mem, int is_resume)
-{
- printk(BIOS_SPEW, "manufacturer: 0x%x type: 0x%x, div: 0x%x, mhz: %d\n",
- mem->mem_manuf,
- mem->mem_type,
- mem->mpll_mdiv,
- mem->frequency_mhz);
-
- if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
- die("Failed to initialize memory controller.\n");
- }
-}
-
-#define PRIMITIVE_MEM_TEST 0
-#if PRIMITIVE_MEM_TEST
-static unsigned long primitive_mem_test(void)
-{
- unsigned long *l = (void *)0x40000000;
- int bad = 0;
- unsigned long i;
- for(i = 0; i < 256*1048576; i++){
- if (! (i%1048576))
- printk(BIOS_SPEW, "%lu ...", i);
- l[i] = 0xffffffff - i;
- }
-
- for(i = 0; i < 256*1048576; i++){
- if (! (i%1048576))
- printk(BIOS_SPEW, "%lu ...", i);
- if (l[i] != (0xffffffff - i)){
- printk(BIOS_SPEW, "%p: want %08lx got %08lx\n", l, l[i], 0xffffffff - i);
- bad++;
- }
- }
-
- printk(BIOS_SPEW, "%d errors\n", bad);
-
- return bad;
-}
-#else
-#define primitive_mem_test()
-#endif
-
-#define SIMPLE_SPI_TEST 0
-#if SIMPLE_SPI_TEST
-/* here is a simple SPI debug test, known to fid trouble */
-static void simple_spi_test(void)
-{
- struct cbfs_media default_media, *media;
- int i, amt = 4 * MiB, errors = 0;
- //u32 *data = (void *)0x40000000;
- u32 data[1024];
- u32 in;
-
- amt = sizeof(data);
- media = &default_media;
- if (init_default_cbfs_media(media) != 0) {
- printk(BIOS_SPEW, "Failed to initialize default media.\n");
- return;
- }
-
-
- media->open(media);
- if (media->read(media, data, (size_t) 0, amt) < amt){
- printk(BIOS_SPEW, "simple_spi_test fails\n");
- return;
- }
-
-
- for(i = 0; i < amt; i += 4){
- if (media->read(media, &in, (size_t) i, 4) < 1){
- printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
- return;
- }
- if (data[i/4] != in){
- errors++;
- printk(BIOS_SPEW, "BAD at %d(%p):\nRAM %08lx\nSPI %08lx\n",
- i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
- /* reread it to see which is wrong. */
- if (media->read(media, &in, (size_t) i, 4) < 1){
- printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
- return;
- }
- printk(BIOS_SPEW, "RTRY at %d(%p):\nRAM %08lx\nSPI %08lx\n",
- i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
- }
-
- }
- printk(BIOS_SPEW, "%d errors\n", errors);
-}
-#else
-#define simple_spi_test()
-#endif
-
-void main(void)
-{
-
- extern struct mem_timings mem_timings;
- void *entry;
- int is_resume = (get_wakeup_state() != IS_NOT_WAKEUP);
- int power_init_failed;
-
- exynos5420_config_smp();
- power_init_failed = setup_power(is_resume);
-
- /* Clock must be initialized before console_init, otherwise you may need
- * to re-initialize serial console drivers again. */
- system_clock_init();
-
- exynos_pinmux_uart3();
- console_init();
- exception_init();
-
- if (power_init_failed)
- die("Failed to intialize power.\n");
-
- /* re-initialize PMIC I2C channel after (re-)setting system clocks */
- i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
-
- setup_memory(&mem_timings, is_resume);
-
- primitive_mem_test();
-
- trustzone_init();
-
- if (is_resume) {
- wakeup();
- }
-
- setup_gpio();
- setup_ec();
-
- simple_spi_test();
- /* Set SPI (primary CBFS media) clock to 50MHz. */
- /* if this is uncommented SPI will not work correctly. */
- clock_set_rate(PERIPH_ID_SPI1, 50000000);
- exynos_pinmux_spi1();
- simple_spi_test();
-
- cbmem_initialize_empty();
-
- entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/ramstage");
- simple_spi_test();
- stage_exit(entry);
-}
diff --git a/src/mainboard/google/pit/wakeup.c b/src/mainboard/google/pit/wakeup.c
deleted file mode 100644
index 130282c..0000000
--- a/src/mainboard/google/pit/wakeup.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <soc/samsung/exynos5420/gpio.h>
-#include <soc/samsung/exynos5420/wakeup.h>
-
-int wakeup_need_reset(void)
-{
- /* The "wake up" event is not reliable (known as "bad wakeup") and needs
- * reset if the TPM reset mask GPIO value is high. */
- return gpio_get_value(GPIO_X06);
-}
Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6926
-gerrit
commit 7d3b1cd47994095ecaa9e2c20d82380f0d7c7e98
Author: Isaac Christensen <isaac.christensen(a)se-eng.com>
Date: Wed Sep 17 16:14:18 2014 -0600
exynos5250: remove unused ret variable in cpu.c
Showed up as an error when '--gc-sections' was added as a flag to the
compiler.
Change-Id: I214d3e16a72fca0becc677d7af66097464d64247
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
src/soc/samsung/exynos5250/cpu.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/soc/samsung/exynos5250/cpu.c b/src/soc/samsung/exynos5250/cpu.c
index 3a2b62d..b8b88d7 100644
--- a/src/soc/samsung/exynos5250/cpu.c
+++ b/src/soc/samsung/exynos5250/cpu.c
@@ -62,7 +62,6 @@ static void set_cpu_id(void)
static void exynos_displayport_init(device_t dev, u32 lcdbase,
unsigned long fb_size)
{
- int ret;
struct soc_samsung_exynos5250_config *conf = dev->chip_info;
/* put these on the stack. If, at some point, we want to move
* this code to a pre-ram stage, it will be much easier.
@@ -108,7 +107,7 @@ static void exynos_displayport_init(device_t dev, u32 lcdbase,
printk(BIOS_DEBUG, "Initializing Exynos LCD.\n");
- ret = lcd_ctrl_init(fb_size, &panel, (void *)lcdbase);
+ lcd_ctrl_init(fb_size, &panel, (void *)lcdbase);
}
static void cpu_enable(device_t dev)
Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6926
-gerrit
commit b25cbee1f807f2d2f0312704abd69fd18c95fcb4
Author: Isaac Christensen <isaac.christensen(a)se-eng.com>
Date: Wed Sep 17 16:14:18 2014 -0600
exynos5250: remove unused ret variable in cpu.c
Showed up as an error when '-ffunction-sections' and 'fdata-sections'
were added as flags to the compiler.
Change-Id: I214d3e16a72fca0becc677d7af66097464d64247
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
src/soc/samsung/exynos5250/cpu.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/soc/samsung/exynos5250/cpu.c b/src/soc/samsung/exynos5250/cpu.c
index 3a2b62d..b8b88d7 100644
--- a/src/soc/samsung/exynos5250/cpu.c
+++ b/src/soc/samsung/exynos5250/cpu.c
@@ -62,7 +62,6 @@ static void set_cpu_id(void)
static void exynos_displayport_init(device_t dev, u32 lcdbase,
unsigned long fb_size)
{
- int ret;
struct soc_samsung_exynos5250_config *conf = dev->chip_info;
/* put these on the stack. If, at some point, we want to move
* this code to a pre-ram stage, it will be much easier.
@@ -108,7 +107,7 @@ static void exynos_displayport_init(device_t dev, u32 lcdbase,
printk(BIOS_DEBUG, "Initializing Exynos LCD.\n");
- ret = lcd_ctrl_init(fb_size, &panel, (void *)lcdbase);
+ lcd_ctrl_init(fb_size, &panel, (void *)lcdbase);
}
static void cpu_enable(device_t dev)