Andrey Petrov (andrey.petrov(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14095
-gerrit
commit b9d2cef9abf46a6f8fea15cbf9d3d097bdf804ec
Author: Andrey Petrov <andrey.petrov(a)intel.com>
Date: Sun Mar 13 16:01:55 2016 -0700
soc/intel/apollolake: enable RAM cache for cbmem region in ramstage
Since ramstage code as well as FSP code is run in cbmem that is
placed in DRAM, it is imporant to have that region cached for
performance reasons. This patch enables WB cache for 16MiB below
cbmem top which is a safe bet ramstage is covered.
Change-Id: I3f2f6e82f3b9060c7350ddff754cd3dbcf457671
Signed-off-by: Andrey Petrov <andrey.petrov(a)intel.com>
---
src/soc/intel/apollolake/romstage.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c
index 7c8924d..45899fd 100644
--- a/src/soc/intel/apollolake/romstage.c
+++ b/src/soc/intel/apollolake/romstage.c
@@ -15,6 +15,7 @@
#include <arch/symbols.h>
#include <cbfs.h>
#include <cbmem.h>
+#include <cpu/x86/mtrr.h>
#include <console/console.h>
#include <device/pci_def.h>
#include <fsp/api.h>
@@ -80,6 +81,7 @@ asmlinkage void car_stage_entry(void)
void *hob_list_ptr;
struct range_entry fsp_mem;
struct range_entry reg_car;
+ uintptr_t top_of_ram;
printk(BIOS_DEBUG, "Starting romstage...\n");
@@ -95,6 +97,24 @@ asmlinkage void car_stage_entry(void)
die("FSP memory init failed. Giving up.");
}
+ /*
+ * Cache 16 MiB area right below cbmem, so that ramstage and FSP
+ * reserved memory ran cached. This assumes address is at least
+ * 16 MiB aligned.
+ *
+ * After this call we get:
+ * - Non-evict mode (NEM) is enabled
+ * - Write-back cache is active for small window in DRAM
+ *
+ * Since NEM mode blocks cache fills, memory operations do not make
+ * it into L2 cache. L1D cache however works in normal mode. Since
+ * L1 size is smaller than the actual working set, we are slower than
+ * fully fledged L2. However it is still about 10x faster than non-
+ * cached memory.
+ */
+ top_of_ram = (uintptr_t) cbmem_top();
+ set_var_mtrr(1, top_of_ram - 16 * MiB, 16 * MiB, MTRR_TYPE_WRBACK);
+
fsp_find_reserved_memory(&fsp_mem, hob_list_ptr);
/* initialize cbmem by adding FSP reserved memory first thing */
the following patch was just integrated into master:
commit 24ae84d2604e0352081a705ab5c074cefdbdd2ec
Author: Martin Roth <martinroth(a)google.com>
Date: Mon Mar 14 15:16:48 2016 -0600
vendorcode/intel/Kconfig: Add broadwell_de symbol to fix lint
The Kconfig lint tool is complaining because this symbol doesn't
exist. Create a temporary definition that can be removed when
the chipset is added.
Change-Id: I6a8abffcc91773aae16721ee1f48c4c64bd6b486
Signed-off-by: Martin Roth <martinroth(a)google.com>
Reviewed-on: https://review.coreboot.org/14091
Reviewed-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Tested-by: build bot (Jenkins)
Reviewed-by: Werner Zeh <werner.zeh(a)siemens.com>
Reviewed-by: Patrick Georgi <pgeorgi(a)google.com>
See https://review.coreboot.org/14091 for details.
-gerrit
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14098
-gerrit
commit 89d9428117673c452220d11b22945b4b924305da
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 15 09:08:34 2016 -0500
cpu/x86/mtrr: remove early_mtrr_* functions
I see no user of any of this code. Remove it.
Change-Id: I776cd3d9ac6578ecb0fe6d98f15611e4463afb7a
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/x86/mtrr/earlymtrr.c | 77 --------------------------------------------
1 file changed, 77 deletions(-)
diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c
index 3d7ad11..a84ecf8 100644
--- a/src/cpu/x86/mtrr/earlymtrr.c
+++ b/src/cpu/x86/mtrr/earlymtrr.c
@@ -18,80 +18,3 @@ void set_var_mtrr(
maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
wrmsr(MTRR_PHYS_MASK(reg), maskm);
}
-
-#if !IS_ENABLED(CONFIG_CACHE_AS_RAM)
-const int addr_det = 0;
-
-/* the fixed and variable MTRRs are power-up with random values,
- * clear them to MTRR_TYPE_UNCACHEABLE for safety.
- */
-static void do_early_mtrr_init(const unsigned long *mtrr_msrs)
-{
- /* Precondition:
- * The cache is not enabled in cr0 nor in MTRR_DEF_TYPE_MSR
- * entry32.inc ensures the cache is not enabled in cr0
- */
- msr_t msr;
- const unsigned long *msr_addr;
-
- /* Initialize all of the relevant msrs to 0 */
- msr.lo = 0;
- msr.hi = 0;
- unsigned long msr_nr;
- for(msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) {
- wrmsr(msr_nr, msr);
- }
-
-#if defined(CONFIG_XIP_ROM_SIZE) && CONFIG_XIP_ROM_SIZE
- /* enable write through caching so we can do execute in place
- * on the flash rom.
- * Determine address by calculating the XIP_ROM_SIZE sized area with
- * XIP_ROM_SIZE alignment that contains the global variable defined above;
- */
- unsigned long f = (unsigned long)&addr_det & ~(CONFIG_XIP_ROM_SIZE - 1);
- set_var_mtrr(1, f, CONFIG_XIP_ROM_SIZE, MTRR_TYPE_WRBACK);
-#endif
-
- /* Set the default memory type and enable fixed and variable MTRRs
- */
- /* Enable Variable MTRRs */
- msr.hi = 0x00000000;
- msr.lo = 0x00000800;
- wrmsr(MTRR_DEF_TYPE_MSR, msr);
-
-}
-
-static inline void early_mtrr_init(void)
-{
- static const unsigned long mtrr_msrs[] = {
- /* fixed mtrr */
- 0x250, 0x258, 0x259,
- 0x268, 0x269, 0x26A,
- 0x26B, 0x26C, 0x26D,
- 0x26E, 0x26F,
- /* var mtrr */
- 0x200, 0x201, 0x202, 0x203,
- 0x204, 0x205, 0x206, 0x207,
- 0x208, 0x209, 0x20A, 0x20B,
- 0x20C, 0x20D, 0x20E, 0x20F,
- /* NULL end of table */
- 0
- };
- disable_cache();
- do_early_mtrr_init(mtrr_msrs);
- enable_cache();
-}
-
-static inline int early_mtrr_init_detected(void)
-{
- msr_t msr;
- /* See if MTRR's are enabled.
- * a #RESET disables them while an #INIT
- * preserves their state. This works
- * on both Intel and AMD cpus, at least
- * according to the documentation.
- */
- msr = rdmsr(MTRR_DEF_TYPE_MSR);
- return msr.lo & MTRR_DEF_TYPE_EN;
-}
-#endif
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14094
-gerrit
commit fcdd64deb0f30d322c9a83375df532cb14b08d3b
Author: Andrey Petrov <andrey.petrov(a)intel.com>
Date: Sun Mar 13 16:01:04 2016 -0700
cpu/x86: compile earlymtrr.c code for romstage as well
In order to make this work earlymtrr.c needed to be removed
from intel/truxton/romstage.c. It's not a ROMCC board so
there's no reason to be including .c files.
Change-Id: If4f5494a53773454b97b90fb856f7e52cadb3f44
Signed-off-by: Andrey Petrov <andrey.petrov(a)intel.com>
---
src/cpu/x86/mtrr/Makefile.inc | 1 +
src/mainboard/intel/truxton/romstage.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cpu/x86/mtrr/Makefile.inc b/src/cpu/x86/mtrr/Makefile.inc
index cecb826..9b7207b 100644
--- a/src/cpu/x86/mtrr/Makefile.inc
+++ b/src/cpu/x86/mtrr/Makefile.inc
@@ -1 +1,2 @@
ramstage-y += mtrr.c
+romstage-y += earlymtrr.c
diff --git a/src/mainboard/intel/truxton/romstage.c b/src/mainboard/intel/truxton/romstage.c
index 3ea6542..36f5495 100644
--- a/src/mainboard/intel/truxton/romstage.c
+++ b/src/mainboard/intel/truxton/romstage.c
@@ -26,7 +26,6 @@
#include "southbridge/intel/i3100/early_lpc.c"
#include <northbridge/intel/i3100/raminit_ep80579.h>
#include <superio/intel/i3100/i3100.h>
-#include "cpu/x86/mtrr/earlymtrr.c"
#include "lib/debug.c" // XXX
#include <cpu/x86/bist.h>
#include <spd.h>
Lin Huang (hl(a)rock-chips.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13916
-gerrit
commit bfa5d83122cd95acfb65b37b463a76f654c4f8df
Author: huang lin <hl(a)rock-chips.com>
Date: Thu Mar 3 14:47:30 2016 +0800
rockchip: rk3399: enable mmu
Change-Id: I66bfde396036d7a66b29517937a28f0767635066
Signed-off-by: huang lin <hl(a)rock-chips.com>
---
src/mainboard/google/gru/romstage.c | 9 ++++++
src/soc/rockchip/rk3399/Makefile.inc | 3 +-
src/soc/rockchip/rk3399/bootblock.c | 2 ++
.../rockchip/rk3399/include/soc/mmu_operations.h | 31 +++++++++++++++++++
src/soc/rockchip/rk3399/mmu_operations.c | 36 ++++++++++++++++++++++
5 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/src/mainboard/google/gru/romstage.c b/src/mainboard/google/gru/romstage.c
index 4786937..93eb41a 100644
--- a/src/mainboard/google/gru/romstage.c
+++ b/src/mainboard/google/gru/romstage.c
@@ -18,17 +18,26 @@
#include <arch/cpu.h>
#include <arch/exception.h>
#include <arch/io.h>
+#include <arch/mmu.h>
#include <cbfs.h>
#include <console/console.h>
#include <delay.h>
#include <program_loading.h>
#include <romstage_handoff.h>
#include <symbols.h>
+#include <soc/mmu_operations.h>
+
+static const uint64_t dram_size = (uint64_t)CONFIG_DRAM_SIZE_MB * MiB;
void main(void)
{
console_init();
exception_init();
+
+ /*TODO: need implement sdram init */
+
+ mmu_config_range((void *)0, (uintptr_t)dram_size, CACHED_MEM);
+ mmu_config_range(_dma_coherent, _dma_coherent_size, UNCACHED_MEM);
cbmem_initialize_empty();
run_ramstage();
}
diff --git a/src/soc/rockchip/rk3399/Makefile.inc b/src/soc/rockchip/rk3399/Makefile.inc
index 2067404..c630b26 100644
--- a/src/soc/rockchip/rk3399/Makefile.inc
+++ b/src/soc/rockchip/rk3399/Makefile.inc
@@ -20,6 +20,7 @@ bootblock-y += bootblock.c
bootblock-y += timer.c
bootblock-y += spi.c
bootblock-y += clock.c
+bootblock-y += mmu_operations.c
ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)
bootblock-$(CONFIG_DRIVERS_UART) += uart.c
endif
@@ -37,7 +38,7 @@ romstage-y += cbmem.c
romstage-y += timer.c
romstage-y += spi.c
romstage-y += clock.c
-
+romstage-y += mmu_operations.c
################################################################################
ramstage-y += cbmem.c
diff --git a/src/soc/rockchip/rk3399/bootblock.c b/src/soc/rockchip/rk3399/bootblock.c
index ae41a08..dc604a1 100644
--- a/src/soc/rockchip/rk3399/bootblock.c
+++ b/src/soc/rockchip/rk3399/bootblock.c
@@ -18,8 +18,10 @@
#include <arch/mmu.h>
#include <bootblock_common.h>
#include <console/console.h>
+#include <soc/mmu_operations.h>
#include <symbols.h>
void bootblock_soc_init(void)
{
+ rockchip_mmu_init();
}
diff --git a/src/soc/rockchip/rk3399/include/soc/mmu_operations.h b/src/soc/rockchip/rk3399/include/soc/mmu_operations.h
new file mode 100644
index 0000000..9772ea3
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/mmu_operations.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_MMU_H__
+#define __SOC_ROCKCHIP_RK3399_MMU_H__
+
+#include <arch/mmu.h>
+
+enum {
+ DEV_MEM = MA_DEV | MA_S | MA_RW,
+ CACHED_MEM = MA_MEM | MA_NS | MA_RW,
+ SECURE_MEM = MA_MEM | MA_S | MA_RW,
+ UNCACHED_MEM = MA_MEM | MA_NS | MA_RW | MA_MEM_NC,
+};
+
+void rockchip_mmu_init(void);
+#endif
+
diff --git a/src/soc/rockchip/rk3399/mmu_operations.c b/src/soc/rockchip/rk3399/mmu_operations.c
new file mode 100644
index 0000000..2c2ef2c
--- /dev/null
+++ b/src/soc/rockchip/rk3399/mmu_operations.c
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#include <arch/io.h>
+#include <arch/mmu.h>
+#include <bootblock_common.h>
+#include <console/console.h>
+#include <soc/mmu_operations.h>
+#include <symbols.h>
+
+void rockchip_mmu_init(void)
+{
+ mmu_init();
+
+ /* Set 0x0 to end of dram as device memory */
+ mmu_config_range((void *)0, (uintptr_t)8192 * MiB, DEV_MEM);
+
+ mmu_config_range(_sram, _sram_size, SECURE_MEM);
+
+ /* set ttb as secure */
+ mmu_config_range(_ttb, _ttb_size, SECURE_MEM);
+ mmu_enable();
+}
Lin Huang (hl(a)rock-chips.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13915
-gerrit
commit ad7bfe3d44a52706c50ba115bf53e2f480db5358
Author: huang lin <hl(a)rock-chips.com>
Date: Wed Mar 2 18:38:40 2016 +0800
coreboot: rk3399: Add a stub implementation of the rk3399 SOC
Most things still needs to be filled in, but this will allow
us to build boards which use this SOC
Change-Id: I6f2407ff578dcd3d0daed86dd03d8f5f4edcac53
Signed-off-by: huang lin <hl(a)rock-chips.com>
---
src/mainboard/google/gru/Kconfig | 64 +++++
src/mainboard/google/gru/Kconfig.name | 2 +
src/mainboard/google/gru/Makefile.inc | 42 ++++
src/mainboard/google/gru/boardid.c | 28 +++
src/mainboard/google/gru/bootblock.c | 25 ++
src/mainboard/google/gru/chromeos.c | 41 ++++
src/mainboard/google/gru/chromeos.fmd | 29 +++
src/mainboard/google/gru/devicetree.cb | 18 ++
src/mainboard/google/gru/mainboard.c | 36 +++
src/mainboard/google/gru/memlayout.ld | 1 +
src/mainboard/google/gru/reset.c | 21 ++
src/mainboard/google/gru/romstage.c | 34 +++
src/soc/rockchip/rk3399/Kconfig | 26 ++
src/soc/rockchip/rk3399/Makefile.inc | 59 +++++
src/soc/rockchip/rk3399/bootblock.c | 25 ++
src/soc/rockchip/rk3399/cbmem.c | 23 ++
src/soc/rockchip/rk3399/clock.c | 21 ++
src/soc/rockchip/rk3399/include/soc/addressmap.h | 58 +++++
src/soc/rockchip/rk3399/include/soc/clock.h | 21 ++
src/soc/rockchip/rk3399/include/soc/memlayout.ld | 36 +++
src/soc/rockchip/rk3399/include/soc/soc.h | 26 ++
src/soc/rockchip/rk3399/include/soc/spi.h | 195 +++++++++++++++
src/soc/rockchip/rk3399/include/soc/timer.h | 39 +++
src/soc/rockchip/rk3399/soc.c | 51 ++++
src/soc/rockchip/rk3399/spi.c | 288 +++++++++++++++++++++++
src/soc/rockchip/rk3399/timer.c | 45 ++++
src/soc/rockchip/rk3399/uart.c | 168 +++++++++++++
27 files changed, 1422 insertions(+)
diff --git a/src/mainboard/google/gru/Kconfig b/src/mainboard/google/gru/Kconfig
new file mode 100644
index 0000000..551bacd
--- /dev/null
+++ b/src/mainboard/google/gru/Kconfig
@@ -0,0 +1,64 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright 2016 Rockchip 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.
+##
+
+if BOARD_GOOGLE_GRU
+
+config BOARD_SPECIFIC_OPTIONS
+ def_bool y
+ select BOARD_ID_AUTO
+ select SOC_ROCKCHIP_RK3399
+ select BOARD_ROMSIZE_KB_4096
+ select MAINBOARD_HAS_CHROMEOS
+ select COMMON_CBFS_SPI_WRAPPER
+ select SPI_FLASH
+ select SPI_FLASH_GIGADEVICE
+ select SPI_FLASH_WINBOND
+ select HAVE_HARD_RESET
+
+config CHROMEOS
+ select CHROMEOS_VBNV_FLASH
+ select VIRTUAL_DEV_SWITCH
+ select VBOOT2_MOCK_SECDATA
+
+config MAINBOARD_DIR
+ string
+ default google/gru
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "gru"
+
+config MAINBOARD_VENDOR
+ string
+ default "Google"
+
+config DRAM_SIZE_MB
+ int
+ default 2048
+
+config EC_GOOGLE_CHROMEEC_SPI_BUS
+ hex
+ default 0
+
+config BOOT_MEDIA_SPI_BUS
+ int
+ default 1
+
+config CONSOLE_SERIAL_UART_ADDRESS
+ hex
+ depends on DRIVERS_UART
+ default 0xFF1A0000
+
+endif # BOARD_GOOGLE_GRU
diff --git a/src/mainboard/google/gru/Kconfig.name b/src/mainboard/google/gru/Kconfig.name
new file mode 100644
index 0000000..7511903
--- /dev/null
+++ b/src/mainboard/google/gru/Kconfig.name
@@ -0,0 +1,2 @@
+config BOARD_GOOGLE_GRU
+ bool "Gru"
diff --git a/src/mainboard/google/gru/Makefile.inc b/src/mainboard/google/gru/Makefile.inc
new file mode 100644
index 0000000..821d08c
--- /dev/null
+++ b/src/mainboard/google/gru/Makefile.inc
@@ -0,0 +1,42 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright 2016 Rockchip 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.
+##
+
+bootblock-y += bootblock.c
+bootblock-y += memlayout.ld
+bootblock-y += chromeos.c
+bootblock-y += boardid.c
+bootblock-y += reset.c
+
+verstage-y += memlayout.ld
+verstage-y += chromeos.c
+verstage-y += boardid.c
+verstage-y += reset.c
+
+romstage-y += chromeos.c
+romstage-y += romstage.c
+romstage-y += memlayout.ld
+romstage-y += boardid.c
+romstage-y += reset.c
+
+ramstage-y += mainboard.c
+ramstage-y += chromeos.c
+ramstage-y += memlayout.ld
+ramstage-y += boardid.c
+ramstage-y += reset.c
+
+bootblock-y += memlayout.ld
+verstage-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/gru/boardid.c b/src/mainboard/google/gru/boardid.c
new file mode 100644
index 0000000..f62fe97
--- /dev/null
+++ b/src/mainboard/google/gru/boardid.c
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#include <boardid.h>
+#include <console/console.h>
+#include <stdlib.h>
+
+uint8_t board_id(void)
+{
+ return 0;
+}
+
+uint32_t ram_code(void)
+{
+ return 0;
+}
diff --git a/src/mainboard/google/gru/bootblock.c b/src/mainboard/google/gru/bootblock.c
new file mode 100644
index 0000000..bdc75dd
--- /dev/null
+++ b/src/mainboard/google/gru/bootblock.c
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#include <bootblock_common.h>
+
+void bootblock_mainboard_early_init(void)
+{
+}
+
+void bootblock_mainboard_init(void)
+{
+}
diff --git a/src/mainboard/google/gru/chromeos.c b/src/mainboard/google/gru/chromeos.c
new file mode 100644
index 0000000..6f9380d
--- /dev/null
+++ b/src/mainboard/google/gru/chromeos.c
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#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>
+
+void fill_lb_gpios(struct lb_gpios *gpios)
+{
+}
+
+int get_developer_mode_switch(void)
+{
+ return 0;
+}
+
+int get_recovery_mode_switch(void)
+{
+ return 0;
+}
+
+int get_write_protect_state(void)
+{
+ return 0;
+}
diff --git a/src/mainboard/google/gru/chromeos.fmd b/src/mainboard/google/gru/chromeos.fmd
new file mode 100644
index 0000000..a18bb6b
--- /dev/null
+++ b/src/mainboard/google/gru/chromeos.fmd
@@ -0,0 +1,29 @@
+FLASH@0x0 0x400000 {
+ WP_RO@0x0 0x200000 {
+ RO_SECTION@0x0 0x1f0000 {
+ BOOTBLOCK@0 128K
+ COREBOOT(CBFS)@0x20000 0xe0000
+ FMAP@0x100000 0x1000
+ GBB@0x101000 0xeef00
+ RO_FRID@0x1eff00 0x100
+ }
+ RO_VPD@0x1f0000 0x10000
+ }
+ RW_SECTION_A@0x200000 0x78000 {
+ VBLOCK_A@0x0 0x2000
+ FW_MAIN_A(CBFS)@0x2000 0x75f00
+ RW_FWID_A@0x77f00 0x100
+ }
+ RW_SHARED@0x278000 0x2000 {
+ SHARED_DATA@0x0 0x2000
+ }
+ RW_NVRAM@0x27a000 0x2000
+ RW_ELOG@0x27c000 0x4000
+ RW_SECTION_B@0x280000 0x78000 {
+ VBLOCK_B@0x0 0x2000
+ FW_MAIN_B(CBFS)@0x2000 0x75f00
+ RW_FWID_B@0x77f00 0x100
+ }
+ RW_VPD@0x2f8000 0x8000
+ RW_LEGACY@0x300000 0x100000
+}
diff --git a/src/mainboard/google/gru/devicetree.cb b/src/mainboard/google/gru/devicetree.cb
new file mode 100644
index 0000000..b349888
--- /dev/null
+++ b/src/mainboard/google/gru/devicetree.cb
@@ -0,0 +1,18 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright 2016 Rockchip 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.
+##
+
+chip soc/rockchip/rk3399
+ device cpu_cluster 0 on end
+end
diff --git a/src/mainboard/google/gru/mainboard.c b/src/mainboard/google/gru/mainboard.c
new file mode 100644
index 0000000..9e83660
--- /dev/null
+++ b/src/mainboard/google/gru/mainboard.c
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#include <arch/cache.h>
+#include <arch/io.h>
+#include <boardid.h>
+#include <boot/coreboot_tables.h>
+#include <device/device.h>
+#include <console/console.h>
+
+static void mainboard_init(device_t dev)
+{
+}
+
+static void mainboard_enable(device_t dev)
+{
+ dev->ops->init = &mainboard_init;
+}
+
+struct chip_operations mainboard_ops = {
+ .name = "gru",
+ .enable_dev = mainboard_enable,
+};
diff --git a/src/mainboard/google/gru/memlayout.ld b/src/mainboard/google/gru/memlayout.ld
new file mode 100644
index 0000000..ead7f47
--- /dev/null
+++ b/src/mainboard/google/gru/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/memlayout.ld>
diff --git a/src/mainboard/google/gru/reset.c b/src/mainboard/google/gru/reset.c
new file mode 100644
index 0000000..31d8b3d
--- /dev/null
+++ b/src/mainboard/google/gru/reset.c
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+void hard_reset(void)
+{
+}
diff --git a/src/mainboard/google/gru/romstage.c b/src/mainboard/google/gru/romstage.c
new file mode 100644
index 0000000..4786937
--- /dev/null
+++ b/src/mainboard/google/gru/romstage.c
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#include <arch/cache.h>
+#include <arch/cpu.h>
+#include <arch/exception.h>
+#include <arch/io.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <delay.h>
+#include <program_loading.h>
+#include <romstage_handoff.h>
+#include <symbols.h>
+
+void main(void)
+{
+ console_init();
+ exception_init();
+ cbmem_initialize_empty();
+ run_ramstage();
+}
diff --git a/src/soc/rockchip/rk3399/Kconfig b/src/soc/rockchip/rk3399/Kconfig
new file mode 100644
index 0000000..c2b6685
--- /dev/null
+++ b/src/soc/rockchip/rk3399/Kconfig
@@ -0,0 +1,26 @@
+config SOC_ROCKCHIP_RK3399
+ bool
+ default n
+ select ARM64_A53_ERRATUM_843419
+ select ARCH_BOOTBLOCK_ARMV8_64
+ select ARCH_RAMSTAGE_ARMV8_64
+ select ARCH_ROMSTAGE_ARMV8_64
+ select ARCH_VERSTAGE_ARMV8_64
+ select BOOTBLOCK_CONSOLE
+ select HAVE_UART_SPECIAL
+ select HAVE_MONOTONIC_TIMER
+ select GENERIC_UDELAY
+ select UNCOMPRESSED_RAMSTAGE
+
+if SOC_ROCKCHIP_RK3399
+
+config CHROMEOS
+ select VBOOT_STARTS_IN_BOOTBLOCK
+ select SEPARATE_VERSTAGE
+ select RETURN_FROM_VERSTAGE
+
+config PMIC_BUS
+ int
+ default -1
+
+endif
diff --git a/src/soc/rockchip/rk3399/Makefile.inc b/src/soc/rockchip/rk3399/Makefile.inc
new file mode 100644
index 0000000..2067404
--- /dev/null
+++ b/src/soc/rockchip/rk3399/Makefile.inc
@@ -0,0 +1,59 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright 2016 Rockchip 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.
+##
+
+ifeq ($(CONFIG_SOC_ROCKCHIP_RK3399),y)
+
+IDBTOOL = util/rockchip/make_idb.py
+bootblock-y += bootblock.c
+bootblock-y += timer.c
+bootblock-y += spi.c
+bootblock-y += clock.c
+ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)
+bootblock-$(CONFIG_DRIVERS_UART) += uart.c
+endif
+
+verstage-$(CONFIG_DRIVERS_UART) += uart.c
+verstage-y += cbmem.c
+verstage-y += timer.c
+verstage-y += spi.c
+verstage-y += clock.c
+
+################################################################################
+
+romstage-$(CONFIG_DRIVERS_UART) += uart.c
+romstage-y += cbmem.c
+romstage-y += timer.c
+romstage-y += spi.c
+romstage-y += clock.c
+
+################################################################################
+
+ramstage-y += cbmem.c
+ramstage-y += soc.c
+ramstage-$(CONFIG_DRIVERS_UART) += uart.c
+ramstage-y += timer.c
+ramstage-y += spi.c
+ramstage-y += clock.c
+
+################################################################################
+
+CPPFLAGS_common += -Isrc/soc/rockchip/rk3399/include
+
+$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin
+ @printf "Generating: $(subst $(obj)/,,$(@))\n"
+ @mkdir -p $(dir $@)
+ @$(IDBTOOL) --from=$< --to=$@ --enable-align --chip=RK33
+
+endif
diff --git a/src/soc/rockchip/rk3399/bootblock.c b/src/soc/rockchip/rk3399/bootblock.c
new file mode 100644
index 0000000..ae41a08
--- /dev/null
+++ b/src/soc/rockchip/rk3399/bootblock.c
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#include <arch/io.h>
+#include <arch/mmu.h>
+#include <bootblock_common.h>
+#include <console/console.h>
+#include <symbols.h>
+
+void bootblock_soc_init(void)
+{
+}
diff --git a/src/soc/rockchip/rk3399/cbmem.c b/src/soc/rockchip/rk3399/cbmem.c
new file mode 100644
index 0000000..3292515
--- /dev/null
+++ b/src/soc/rockchip/rk3399/cbmem.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#include <cbmem.h>
+#include <stddef.h>
+#include <symbols.h>
+
+void *cbmem_top(void)
+{
+ return (void *)((uintptr_t) _dram + (CONFIG_DRAM_SIZE_MB << 20));
+}
diff --git a/src/soc/rockchip/rk3399/clock.c b/src/soc/rockchip/rk3399/clock.c
new file mode 100644
index 0000000..cb7b400
--- /dev/null
+++ b/src/soc/rockchip/rk3399/clock.c
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ *
+ */
+
+#include <soc/clock.h>
+
+void rkclk_configure_spi(unsigned int bus, unsigned int hz)
+{
+}
diff --git a/src/soc/rockchip/rk3399/include/soc/addressmap.h b/src/soc/rockchip/rk3399/include/soc/addressmap.h
new file mode 100644
index 0000000..6ddf7aa
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/addressmap.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_ADDRESSMAP_H__
+#define __SOC_ROCKCHIP_RK3399_ADDRESSMAP_H__
+
+#define PMUGRF_BASE 0xff320000
+#define PMUSGRF_BASE 0xff330000
+#define CRU_BASE 0xff760000
+#define GRF_BASE 0xff770000
+#define TIMER0_BASE 0xff850000
+#define EMMC_BASE 0xfe330000
+#define SDMMC_BASE 0xfe320000
+
+#define GPIO0_BASE 0xff720000
+#define GPIO1_BASE 0xff730000
+#define GPIO2_BASE 0xff780000
+#define GPIO3_BASE 0xff788000
+#define GPIO4_BASE 0xff790000
+
+#define I2C0_BASE 0xff3c0000
+#define I2C1_BASE 0xff110000
+#define I2C2_BASE 0xff120000
+#define I2C3_BASE 0xff130000
+#define I2C4_BASE 0xff3d0000
+#define I2C5_BASE 0xff140000
+#define I2C6_BASE 0xff150000
+#define I2C7_BASE 0xff160000
+#define I2C8_BASE 0xff3e0000
+
+#define UART0_BASE 0xff180000
+#define UART1_BASE 0xff190000
+#define UART2_BASE 0xff1a0000
+#define UART3_BASE 0xff1b0000
+#define UART4_BASE 0xff370000
+
+#define SPI0_BASE 0xff1c0000
+#define SPI1_BASE 0xff1d0000
+#define SPI2_BASE 0xff1e0000
+#define SPI3_BASE 0xff350000
+#define SPI4_BASE 0xff1f0000
+#define SPI5_BASE 0xff200000
+
+#define TSADC_BASE 0xff260000
+
+#endif /* __SOC_ROCKCHIP_RK3399_ADDRESSMAP_H__ */
diff --git a/src/soc/rockchip/rk3399/include/soc/clock.h b/src/soc/rockchip/rk3399/include/soc/clock.h
new file mode 100644
index 0000000..c0ba52c
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/clock.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_CLOCK_H__
+#define __SOC_ROCKCHIP_RK3399_CLOCK_H__
+
+void rkclk_configure_spi(unsigned int bus, unsigned int hz);
+
+#endif /* __SOC_ROCKCHIP_RK3399_CLOCK_H__ */
diff --git a/src/soc/rockchip/rk3399/include/soc/memlayout.ld b/src/soc/rockchip/rk3399/include/soc/memlayout.ld
new file mode 100644
index 0000000..edb246d
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/memlayout.ld
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#include <memlayout.h>
+#include <arch/header.ld>
+
+SECTIONS
+{
+ DRAM_START(0x00000000)
+ POSTRAM_CBFS_CACHE(0x00100000, 1M)
+ RAMSTAGE(0x00300000, 256K)
+ DMA_COHERENT(0x10000000, 2M)
+
+ SRAM_START(0xFF8C0000)
+ BOOTBLOCK(0xFF8C2004, 32K - 4)
+ PRERAM_CBFS_CACHE(0xFF8CA000, 4K)
+ PRERAM_CBMEM_CONSOLE(0xFF8CB000, 4K)
+ OVERLAP_VERSTAGE_ROMSTAGE(0xFF8CC000, 64K)
+ VBOOT2_WORK(0XFF8DC000, 12K)
+ TTB(0xFF8DF000, 32K)
+ TIMESTAMP(0xFF8E7000, 1K)
+ STACK(0xFF8E7400, 24K)
+ SRAM_END(0xFF8F0000)
+}
diff --git a/src/soc/rockchip/rk3399/include/soc/soc.h b/src/soc/rockchip/rk3399/include/soc/soc.h
new file mode 100644
index 0000000..71f9adb
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/soc.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_CPU_H__
+#define __SOC_ROCKCHIP_RK3399_CPU_H__
+
+#include <arch/io.h>
+#include <symbols.h>
+
+#define RK_CLRSETBITS(clr, set) ((((clr) | (set)) << 16) | set)
+#define RK_SETBITS(set) RK_CLRSETBITS(0, set)
+#define RK_CLRBITS(clr) RK_CLRSETBITS(clr, 0)
+
+#endif
diff --git a/src/soc/rockchip/rk3399/include/soc/spi.h b/src/soc/rockchip/rk3399/include/soc/spi.h
new file mode 100644
index 0000000..d0f2ef1
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/spi.h
@@ -0,0 +1,195 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_SPI_H__
+#define __SOC_ROCKCHIP_RK3399_SPI_H__
+
+/* This driver serves as a CBFS media source. */
+#include <spi-generic.h>
+#include <types.h>
+
+struct rockchip_spi {
+ u32 ctrlr0;
+ u32 ctrlr1;
+ u32 spienr;
+ u32 ser;
+ u32 baudr;
+ u32 txftlr;
+ u32 rxftlr;
+ u32 txflr;
+ u32 rxflr;
+ u32 sr;
+ u32 ipr;
+ u32 imr;
+ u32 isr;
+ u32 risr;
+ u32 icr;
+ u32 dmacr;
+ u32 damtdlr;
+ u32 damrdlr;
+ u32 reserved[(0x400-0x48)/4];
+ u32 txdr[0x100];
+ u32 rxdr[0x100];
+};
+check_member(rockchip_spi, rxdr, 0x800);
+
+
+#define SF_READ_DATA_CMD 0x3
+
+/* --------Bit fields in CTRLR0--------begin */
+
+#define SPI_DFS_OFFSET 0 /* Data Frame Size */
+#define SPI_DFS_MASK 0x3
+#define SPI_DFS_4BIT 0x00
+#define SPI_DFS_8BIT 0x01
+#define SPI_DFS_16BIT 0x02
+#define SPI_DFS_RESV 0x03
+
+/* Control Frame Size */
+#define SPI_CFS_OFFSET 2
+#define SPI_CFS_MASK 0xF
+
+/* Serial Clock Phase */
+#define SPI_SCPH_OFFSET 6
+#define SPI_SCPH_MASK 0x1
+
+/* Serial clock toggles in middle of first data bit */
+#define SPI_SCPH_TOGMID 0
+
+/* Serial clock toggles at start of first data bit */
+#define SPI_SCPH_TOGSTA 1
+
+/* Serial Clock Polarity */
+#define SPI_SCOL_OFFSET 7
+#define SPI_SCOL_MASK 0x1
+
+/* Inactive state of clock serial clock is low */
+#define SPI_SCOL_LOW 0
+
+/* Inactive state of clock serial clock is high */
+#define SPI_SCOL_HIGH 1
+
+/* Chip Select Mode */
+#define SPI_CSM_OFFSET 8
+#define SPI_CSM_MASK 0x3
+
+/* ss_n keep low after every frame data is transferred */
+#define SPI_CSM_KEEP 0x00
+
+/*
+ * ss_n be high for half sclk_out cycles after
+ * every frame data is transferred
+ */
+#define SPI_CSM_HALF 0x01
+
+/* ss_n be high for one sclk_out cycle after every frame data is transferred */
+#define SPI_CSM_ONE 0x02
+#define SPI_CSM_RESV 0x03
+
+/* SSN to Sclk_out delay */
+#define SPI_SSN_DELAY_OFFSET 10
+#define SPI_SSN_DELAY_MASK 0x1
+/* the peroid between ss_n active and sclk_out active is half sclk_out cycles */
+#define SPI_SSN_DELAY_HALF 0x00
+/* the peroid between ss_n active and sclk_out active is one sclk_out cycle */
+#define SPI_SSN_DELAY_ONE 0x01
+
+/* Serial Endian Mode */
+#define SPI_SEM_OFFSET 11
+#define SPI_SEM_MASK 0x1
+/* little endian */
+#define SPI_SEM_LITTLE 0x00
+/* big endian */
+#define SPI_SEM_BIG 0x01
+
+/* First Bit Mode */
+#define SPI_FBM_OFFSET 12
+#define SPI_FBM_MASK 0x1
+/* first bit in MSB */
+#define SPI_FBM_MSB 0x00
+/* first bit in LSB */
+#define SPI_FBM_LSB 0x01
+
+/* Byte and Halfword Transform */
+#define SPI_HALF_WORLD_TX_OFFSET 13
+#define SPI_HALF_WORLD_MASK 0x1
+/* apb 16bit write/read, spi 8bit write/read */
+#define SPI_APB_16BIT 0x00
+/* apb 8bit write/read, spi 8bit write/read */
+#define SPI_APB_8BIT 0x01
+
+/* Rxd Sample Delay */
+#define SPI_RXDSD_OFFSET 14
+#define SPI_RXDSD_MASK 0x3
+
+/* Frame Format */
+#define SPI_FRF_OFFSET 16
+#define SPI_FRF_MASK 0x3
+/* motorola spi */
+#define SPI_FRF_SPI 0x00
+/* Texas Instruments SSP*/
+#define SPI_FRF_SSP 0x01
+/* National Semiconductors Microwire */
+#define SPI_FRF_MICROWIRE 0x02
+#define SPI_FRF_RESV 0x03
+
+/* Transfer Mode */
+#define SPI_TMOD_OFFSET 18
+#define SPI_TMOD_MASK 0x3
+/* xmit & recv */
+#define SPI_TMOD_TR 0x00
+/* xmit only */
+#define SPI_TMOD_TO 0x01
+/* recv only */
+#define SPI_TMOD_RO 0x02
+#define SPI_TMOD_RESV 0x03
+
+/* Operation Mode */
+#define SPI_OMOD_OFFSET 20
+#define SPI_OMOD_MASK 0x1
+/* Master Mode */
+#define SPI_OMOD_MASTER 0x00
+/* Slave Mode */
+#define SPI_OMOD_SLAVE 0x01
+
+/* --------Bit fields in CTRLR0--------end */
+/* Bit fields in SR, 7 bits */
+#define SR_MASK 0x7f
+#define SR_BUSY (1 << 0)
+#define SR_TF_FULL (1 << 1)
+#define SR_TF_EMPT (1 << 2)
+#define SR_RF_EMPT (1 << 3)
+#define SR_RF_FULL (1 << 4)
+
+/* Bit fields in ISR, IMR, RISR, 7 bits */
+#define SPI_INT_TXEI (1 << 0)
+#define SPI_INT_TXOI (1 << 1)
+#define SPI_INT_RXUI (1 << 2)
+#define SPI_INT_RXOI (1 << 3)
+#define SPI_INT_RXFI (1 << 4)
+
+/* Bit fields in DMACR */
+#define SPI_DMACR_TX_ENABLE (1 << 1)
+#define SPI_DMACR_RX_ENABLE (1 << 0)
+
+/* Bit fields in ICR */
+#define SPI_CLEAR_INT_ALL (1 << 0)
+#define SPI_CLEAR_INT_RXUI (1 << 1)
+#define SPI_CLEAR_INT_RXOI (1 << 2)
+#define SPI_CLEAR_INT_TXOI (1 << 3)
+
+void rockchip_spi_init(unsigned int bus, unsigned int speed_hz);
+
+#endif
diff --git a/src/soc/rockchip/rk3399/include/soc/timer.h b/src/soc/rockchip/rk3399/include/soc/timer.h
new file mode 100644
index 0000000..8513cfa
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/timer.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_TIMER_H__
+#define __SOC_ROCKCHIP_RK3399_TIMER_H__
+
+#include <inttypes.h>
+#include <soc/addressmap.h>
+#include <timer.h>
+
+static const u32 clocks_per_usec = (24 * 1000 * 1000) / USECS_PER_SEC;
+
+struct rk3399_timer {
+ u32 timer_load_count0;
+ u32 timer_load_count1;
+ u32 timer_cur_value0;
+ u32 timer_cur_value1;
+ u32 timer_load_count2;
+ u32 timer_load_count3;
+ u32 timer_int_status;
+ u32 timer_ctrl_reg;
+};
+
+static struct rk3399_timer * const timer0_ptr = (void *)TIMER0_BASE;
+#define TIMER_LOAD_VAL 0xffffffff
+
+#endif /* __SOC_ROCKCHIP_RK3399_TIMER_H__ */
diff --git a/src/soc/rockchip/rk3399/soc.c b/src/soc/rockchip/rk3399/soc.c
new file mode 100644
index 0000000..aa21038
--- /dev/null
+++ b/src/soc/rockchip/rk3399/soc.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 MediaTek 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.
+ */
+
+#include <cpu/cpu.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <symbols.h>
+
+static void soc_read_resources(device_t dev)
+{
+ ram_resource(dev, 0, (uintptr_t)_dram / KiB,
+ CONFIG_DRAM_SIZE_MB * KiB);
+}
+
+static void soc_init(device_t dev)
+{
+ /* reserve bl31 image, which define in
+ * arm-trusted-firmware/plat/rockchip/rk3399/include/platform_def.h
+ */
+ mmio_resource(dev, 1, (0x500000 / KiB), (0x80000 / KiB));
+}
+
+static struct device_operations soc_ops = {
+ .read_resources = soc_read_resources,
+ .init = soc_init,
+};
+
+static void enable_soc_dev(device_t dev)
+{
+ dev->ops = &soc_ops;
+}
+
+struct chip_operations soc_rockchip_rk3399_ops = {
+ CHIP_NAME("SOC Rockchip RK3399\n")
+ .enable_dev = enable_soc_dev,
+};
diff --git a/src/soc/rockchip/rk3399/spi.c b/src/soc/rockchip/rk3399/spi.c
new file mode 100644
index 0000000..6b788c2
--- /dev/null
+++ b/src/soc/rockchip/rk3399/spi.c
@@ -0,0 +1,288 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#include <arch/io.h>
+#include <assert.h>
+#include <console/console.h>
+#include <delay.h>
+#include <endian.h>
+#include <soc/addressmap.h>
+#include <soc/clock.h>
+#include <soc/spi.h>
+#include <spi-generic.h>
+#include <spi_flash.h>
+#include <stdlib.h>
+#include <timer.h>
+
+struct rockchip_spi_slave {
+ struct spi_slave slave;
+ struct rockchip_spi *regs;
+};
+
+#define SPI_TIMEOUT_US 1000
+#define SPI_SRCCLK_HZ (99*MHz)
+#define SPI_FIFO_DEPTH 32
+
+static struct rockchip_spi_slave rockchip_spi_slaves[3] = {
+ {
+ .slave = {
+ .bus = 0,
+ .rw = SPI_READ_FLAG | SPI_WRITE_FLAG,
+ },
+ .regs = (void *)SPI0_BASE,
+ },
+ {
+ .slave = {.bus = 1, .rw = SPI_READ_FLAG,},
+ .regs = (void *)SPI1_BASE,
+ },
+ {
+ .slave = {
+ .bus = 2,
+ .rw = SPI_READ_FLAG | SPI_WRITE_FLAG,
+ },
+ .regs = (void *)SPI2_BASE,
+ },
+
+};
+
+static struct rockchip_spi_slave *to_rockchip_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct rockchip_spi_slave, slave);
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+{
+ assert(bus >= 0 && bus < 3);
+ return &(rockchip_spi_slaves[bus].slave);
+}
+
+static void spi_cs_activate(struct spi_slave *slave)
+{
+ struct rockchip_spi *regs = to_rockchip_spi(slave)->regs;
+
+ setbits_le32(®s->ser, 1);
+}
+
+static void spi_cs_deactivate(struct spi_slave *slave)
+{
+ struct rockchip_spi *regs = to_rockchip_spi(slave)->regs;
+ clrbits_le32(®s->ser, 1);
+}
+
+static void rockchip_spi_enable_chip(struct rockchip_spi *regs, int enable)
+{
+ if (enable == 1)
+ write32(®s->spienr, 1);
+ else
+ write32(®s->spienr, 0);
+}
+
+static void rockchip_spi_set_clk(struct rockchip_spi *regs, unsigned int hz)
+{
+ unsigned short clk_div = SPI_SRCCLK_HZ / hz;
+ assert(clk_div * hz == SPI_SRCCLK_HZ && !(clk_div & 1));
+ write32(®s->baudr, clk_div);
+}
+
+void rockchip_spi_init(unsigned int bus, unsigned int speed_hz)
+{
+ struct rockchip_spi *regs = rockchip_spi_slaves[bus].regs;
+ unsigned int ctrlr0 = 0;
+
+ rkclk_configure_spi(bus, SPI_SRCCLK_HZ);
+ rockchip_spi_enable_chip(regs, 0);
+ rockchip_spi_set_clk(regs, speed_hz);
+
+ /* Operation Mode */
+ ctrlr0 = (SPI_OMOD_MASTER << SPI_OMOD_OFFSET);
+
+ /* Data Frame Size */
+ ctrlr0 |= SPI_DFS_8BIT << SPI_DFS_OFFSET;
+
+ /* Chip Select Mode */
+ ctrlr0 |= (SPI_CSM_KEEP << SPI_CSM_OFFSET);
+
+ /* SSN to Sclk_out delay */
+ ctrlr0 |= (SPI_SSN_DELAY_ONE << SPI_SSN_DELAY_OFFSET);
+
+ /* Serial Endian Mode */
+ ctrlr0 |= (SPI_SEM_LITTLE << SPI_SEM_OFFSET);
+
+ /* First Bit Mode */
+ ctrlr0 |= (SPI_FBM_MSB << SPI_FBM_OFFSET);
+
+ /* Byte and Halfword Transform */
+ ctrlr0 |= (SPI_APB_8BIT << SPI_HALF_WORLD_TX_OFFSET);
+
+ /* Rxd Sample Delay */
+ ctrlr0 |= (0 << SPI_RXDSD_OFFSET);
+
+ /* Frame Format */
+ ctrlr0 |= (SPI_FRF_SPI << SPI_FRF_OFFSET);
+
+ write32(®s->ctrlr0, ctrlr0);
+
+ /* fifo depth */
+ write32(®s->txftlr, SPI_FIFO_DEPTH / 2 - 1);
+ write32(®s->rxftlr, SPI_FIFO_DEPTH / 2 - 1);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ spi_cs_activate(slave);
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ spi_cs_deactivate(slave);
+}
+
+static int rockchip_spi_wait_till_not_busy(struct rockchip_spi *regs)
+{
+ struct stopwatch sw;
+
+ stopwatch_init_usecs_expire(&sw, SPI_TIMEOUT_US);
+ do {
+ if (!(read32(®s->sr) & SR_BUSY))
+ return 0;
+ } while (!stopwatch_expired(&sw));
+
+ printk(BIOS_DEBUG,
+ "RK SPI: Status keeps busy for 1000us after a read/write!\n");
+ return -1;
+}
+
+static void set_tmod(struct rockchip_spi *regs, unsigned int tmod)
+{
+ clrsetbits_le32(®s->ctrlr0, SPI_TMOD_MASK << SPI_TMOD_OFFSET,
+ tmod << SPI_TMOD_OFFSET);
+}
+
+static void set_transfer_mode(struct rockchip_spi *regs,
+ unsigned int sout, unsigned int sin)
+{
+ if (!sin && !sout)
+ return;
+ else if (sin && sout)
+ set_tmod(regs, SPI_TMOD_TR); /* tx and rx */
+ else if (!sin)
+ set_tmod(regs, SPI_TMOD_TO); /* tx only */
+ else if (!sout)
+ set_tmod(regs, SPI_TMOD_RO); /* rx only */
+}
+
+/* returns 0 to indicate success, <0 otherwise */
+static int do_xfer(struct spi_slave *slave, const void *dout,
+ unsigned int *bytes_out, void *din, unsigned int *bytes_in)
+{
+ struct rockchip_spi *regs = to_rockchip_spi(slave)->regs;
+ uint8_t *in_buf = din;
+ uint8_t *out_buf = (uint8_t *)dout;
+ unsigned int min_xfer;
+
+ if (*bytes_out == 0)
+ min_xfer = *bytes_in;
+ else if (*bytes_in == 0)
+ min_xfer = *bytes_out;
+ else
+ min_xfer = MIN(*bytes_in, *bytes_out);
+
+ while (min_xfer) {
+ uint32_t sr = read32(®s->sr);
+ int xferred = 0; /* in either (or both) directions */
+
+ if (*bytes_out && !(sr & SR_TF_FULL)) {
+ write32(®s->txdr, *out_buf);
+ out_buf++;
+ *bytes_out -= 1;
+ xferred = 1;
+ }
+
+ if (*bytes_in && !(sr & SR_RF_EMPT)) {
+ *in_buf = read32(®s->rxdr) & 0xff;
+ in_buf++;
+ *bytes_in -= 1;
+ xferred = 1;
+ }
+
+ min_xfer -= xferred;
+ }
+
+ if (rockchip_spi_wait_till_not_busy(regs)) {
+ printk(BIOS_ERR, "Timed out waiting on SPI transfer\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+ return min(65535, buf_len);
+}
+
+int spi_xfer(struct spi_slave *slave, const void *dout,
+ unsigned int bytes_out, void *din, unsigned int bytes_in)
+{
+ struct rockchip_spi *regs = to_rockchip_spi(slave)->regs;
+ int ret = 0;
+
+ /*
+ * RK3288 SPI controller can transfer up to 65536 data frames (bytes
+ * in our case) continuously. Break apart large requests as necessary.
+ *
+ * FIXME: And by 65536, we really mean 65535. If 0xffff is written to
+ * ctrlr1, all bytes that we see in rxdr end up being 0x00. 0xffff - 1
+ * seems to work fine.
+ */
+ while (bytes_out || bytes_in) {
+ unsigned int in_now = MIN(bytes_in, 0xffff);
+ unsigned int out_now = MIN(bytes_out, 0xffff);
+ unsigned int in_rem, out_rem;
+
+ rockchip_spi_enable_chip(regs, 0);
+
+ /* Enable/disable transmitter and receiver as needed to
+ * avoid sending or reading spurious bits. */
+ set_transfer_mode(regs, bytes_out, bytes_in);
+
+ /* MAX() in case either counter is 0 */
+ write32(®s->ctrlr1, MAX(in_now, out_now) - 1);
+
+ rockchip_spi_enable_chip(regs, 1);
+
+ in_rem = in_now;
+ out_rem = out_now;
+ ret = do_xfer(slave, dout, &out_rem, din, &in_rem);
+ if (ret < 0)
+ break;
+
+ if (bytes_out) {
+ unsigned int sent = out_now - out_rem;
+ bytes_out -= sent;
+ dout += sent;
+ }
+
+ if (bytes_in) {
+ unsigned int received = in_now - in_rem;
+ bytes_in -= received;
+ din += received;
+ }
+ }
+
+ rockchip_spi_enable_chip(regs, 0);
+ return ret < 0 ? ret : 0;
+}
diff --git a/src/soc/rockchip/rk3399/timer.c b/src/soc/rockchip/rk3399/timer.c
new file mode 100644
index 0000000..96cf540
--- /dev/null
+++ b/src/soc/rockchip/rk3399/timer.c
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#include <arch/io.h>
+#include <delay.h>
+#include <soc/timer.h>
+#include <stdint.h>
+#include <timer.h>
+
+static uint64_t timer_raw_value(void)
+{
+ uint64_t value0;
+ uint64_t value1;
+
+ value0 = (uint64_t)read32(&timer0_ptr->timer_cur_value0);
+ value1 = (uint64_t)read32(&timer0_ptr->timer_cur_value1);
+
+ return value0 | value1<<32;
+}
+
+void timer_monotonic_get(struct mono_time *mt)
+{
+ mono_time_set_usecs(mt, timer_raw_value() / clocks_per_usec);
+}
+
+void init_timer(void)
+{
+ write32(&timer0_ptr->timer_load_count0, TIMER_LOAD_VAL);
+ write32(&timer0_ptr->timer_load_count1, TIMER_LOAD_VAL);
+ write32(&timer0_ptr->timer_load_count2, 0);
+ write32(&timer0_ptr->timer_load_count3, 0);
+ write32(&timer0_ptr->timer_ctrl_reg, 1);
+}
diff --git a/src/soc/rockchip/rk3399/uart.c b/src/soc/rockchip/rk3399/uart.c
new file mode 100644
index 0000000..c13f182
--- /dev/null
+++ b/src/soc/rockchip/rk3399/uart.c
@@ -0,0 +1,168 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip 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.
+ */
+
+#include <arch/io.h>
+#include <boot/coreboot_tables.h>
+#include <console/console.h> /* for __console definition */
+#include <console/uart.h>
+#include <drivers/uart/uart8250reg.h>
+#include <stdint.h>
+
+/*
+ * TODO: Use DRIVERS_UART_8250MEM driver instead.
+ * There is an issue in the IO call functions where x86 and ARM
+ * ordering is reversed. This 8250MEM driver uses the x86 convention.
+ * This driver can be replaced once the IO calls are sorted.
+ */
+
+struct rk3399_uart {
+ union {
+ uint32_t thr; /* Transmit holding register. */
+ uint32_t rbr; /* Receive buffer register. */
+ uint32_t dll; /* Divisor latch lsb. */
+ };
+ union {
+ uint32_t ier; /* Interrupt enable register. */
+ uint32_t dlm; /* Divisor latch msb. */
+ };
+ union {
+ uint32_t iir; /* Interrupt identification register. */
+ uint32_t fcr; /* FIFO control register. */
+ };
+ uint32_t lcr; /* Line control register. */
+ uint32_t mcr; /* Modem control register. */
+ uint32_t lsr; /* Line status register. */
+ uint32_t msr; /* Modem status register. */
+ uint32_t scr;
+ uint32_t reserved1[(0x30 - 0x20) / 4];
+ uint32_t srbr[(0x70 - 0x30) / 4];
+ uint32_t far;
+ uint32_t tfr;
+ uint32_t rfw;
+ uint32_t usr;
+ uint32_t tfl;
+ uint32_t rfl;
+ uint32_t srr;
+ uint32_t srts;
+ uint32_t sbcr;
+ uint32_t sdmam;
+ uint32_t sfe;
+ uint32_t srt;
+ uint32_t stet;
+ uint32_t htx;
+ uint32_t dmasa;
+ uint32_t reserver2[(0xf4 - 0xac) / 4];
+ uint32_t cpr;
+ uint32_t ucv;
+ uint32_t ctr;
+} __attribute__ ((packed));
+
+
+static struct rk3399_uart * const uart_ptr =
+ (void *)CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
+
+static void rk3399_uart_tx_flush(void);
+static int rk3399_uart_tst_byte(void);
+
+static void rk3399_uart_init(void)
+{
+ /* FIXME: Use a hardcoded divisor for now.
+ * uint16_t divisor = (u16) uart_baudrate_divisor(default_baudrate(),
+ * uart_platform_refclk(), 16)
+ */
+ const unsigned divisor = 13;
+ const uint8_t line_config = UART8250_LCR_WLS_8; // 8n1
+
+ rk3399_uart_tx_flush();
+
+ /* Disable interrupts. */
+ write32(&uart_ptr->ier, 0);
+
+ /* Force DTR and RTS to high. */
+ write32(&uart_ptr->mcr, UART8250_MCR_DTR | UART8250_MCR_RTS);
+
+ /* Set line configuration, access divisor latches. */
+ write32(&uart_ptr->lcr, UART8250_LCR_DLAB | line_config);
+
+ /* Set the divisor. */
+ write32(&uart_ptr->dll, divisor & 0xff);
+ write32(&uart_ptr->dlm, (divisor >> 8) & 0xff);
+
+ /* Hide the divisor latches. */
+ write32(&uart_ptr->lcr, line_config);
+
+ /* Enable FIFOs, and clear receive and transmit. */
+ write32(&uart_ptr->fcr, UART8250_FCR_FIFO_EN |
+ UART8250_FCR_CLEAR_RCVR | UART8250_FCR_CLEAR_XMIT);
+}
+
+static void rk3399_uart_tx_byte(unsigned char data)
+{
+ while (!(read32(&uart_ptr->lsr) & UART8250_LSR_THRE));
+ write32(&uart_ptr->thr, data);
+}
+
+static void rk3399_uart_tx_flush(void)
+{
+ while (!(read32(&uart_ptr->lsr) & UART8250_LSR_TEMT));
+}
+
+static unsigned char rk3399_uart_rx_byte(void)
+{
+ if (!rk3399_uart_tst_byte())
+ return 0;
+ return read32(&uart_ptr->rbr);
+}
+
+static int rk3399_uart_tst_byte(void)
+{
+ return (read32(&uart_ptr->lsr) & UART8250_LSR_DR) == UART8250_LSR_DR;
+}
+
+
+
+void uart_init(int idx)
+{
+ rk3399_uart_init();
+}
+
+unsigned char uart_rx_byte(int idx)
+{
+ return rk3399_uart_rx_byte();
+}
+
+void uart_tx_byte(int idx, unsigned char data)
+{
+ rk3399_uart_tx_byte(data);
+}
+
+void uart_tx_flush(int idx)
+{
+ rk3399_uart_tx_flush();
+}
+
+#ifndef __PRE_RAM__
+void uart_fill_lb(void *data)
+{
+ struct lb_serial serial;
+ serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED;
+ serial.baseaddr = CONFIG_CONSOLE_SERIAL_UART_ADDRESS;
+ serial.baud = default_baudrate();
+ serial.regwidth = 4;
+ lb_add_serial(&serial, data);
+
+ lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);
+}
+#endif