aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/baytrail/romstage
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/baytrail/romstage')
-rw-r--r--src/soc/intel/baytrail/romstage/Makefile.inc4
-rw-r--r--src/soc/intel/baytrail/romstage/cache_as_ram.inc280
-rw-r--r--src/soc/intel/baytrail/romstage/raminit.c93
-rw-r--r--src/soc/intel/baytrail/romstage/romstage.c218
-rw-r--r--src/soc/intel/baytrail/romstage/uart.c39
5 files changed, 634 insertions, 0 deletions
diff --git a/src/soc/intel/baytrail/romstage/Makefile.inc b/src/soc/intel/baytrail/romstage/Makefile.inc
new file mode 100644
index 0000000000..188ce44ecd
--- /dev/null
+++ b/src/soc/intel/baytrail/romstage/Makefile.inc
@@ -0,0 +1,4 @@
+cpu_incs += $(src)/soc/intel/baytrail/romstage/cache_as_ram.inc
+romstage-y += romstage.c
+romstage-y += raminit.c
+romstage-$(CONFIG_ENABLE_BUILTIN_COM1) += uart.c
diff --git a/src/soc/intel/baytrail/romstage/cache_as_ram.inc b/src/soc/intel/baytrail/romstage/cache_as_ram.inc
new file mode 100644
index 0000000000..920fbe4b09
--- /dev/null
+++ b/src/soc/intel/baytrail/romstage/cache_as_ram.inc
@@ -0,0 +1,280 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
+ * Copyright (C) 2007-2008 coresystems GmbH
+ *
+ * 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 <cpu/x86/stack.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/post_code.h>
+#include <cbmem.h>
+
+/* The full cache-as-ram size includes the cache-as-ram portion from coreboot
+ * and the space used by the reference code. These 2 values combined should
+ * be a power of 2 because the MTRR setup assumes that. */
+#define CACHE_AS_RAM_SIZE \
+ (CONFIG_DCACHE_RAM_SIZE + CONFIG_DCACHE_RAM_MRC_VAR_SIZE)
+#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
+
+/* Enough room to cache CAR_TILE_SIZE starting at MRC_BIN_ADDRESS */
+#define CACHE_MRC_BASE (CONFIG_MRC_BIN_ADDRESS)
+#define CACHE_MRC_MASK (~(CONFIG_CAR_TILE_SIZE - 1))
+
+#define CPU_PHYSMASK_HI ((1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1)
+
+#define NoEvictMod_MSR 0x2e0
+#define BBL_CR_CTL3_MSR 0x11e
+#define MCG_CAP_MSR 0x179
+
+ /* Save the BIST result. */
+ movl %eax, %ebp
+
+cache_as_ram:
+ post_code(0x20)
+
+ /* Send INIT IPI to all excluding ourself. */
+ movl $0x000C4500, %eax
+ movl $0xFEE00300, %esi
+ movl %eax, (%esi)
+
+ /* All CPUs need to be in Wait for SIPI state */
+wait_for_sipi:
+ movl (%esi), %eax
+ bt $12, %eax
+ jc wait_for_sipi
+
+ post_code(0x21)
+ /* Configure the default memory type to uncacheable as well as disable
+ * fixed and variable range mtrrs. */
+ movl $MTRRdefType_MSR, %ecx
+ rdmsr
+ andl $(~0x00000cff), %eax
+ wrmsr
+
+ post_code(0x22)
+ /* Zero the variable MTRRs. */
+ movl $MCG_CAP_MSR, %ecx
+ rdmsr
+ movzx %al, %ebx
+ /* First variable MTRR. */
+ movl $0x200, %ecx
+ xorl %eax, %eax
+ xorl %edx, %edx
+ 1:
+ wrmsr
+ inc %ecx
+ dec %ebx
+ jnz 1b
+
+ /* Zero out all fixed range and variable range MTRRs. */
+ movl $fixed_mtrr_table, %esi
+ movl $((fixed_mtrr_table_end - fixed_mtrr_table) / 2), %edi
+ xorl %eax, %eax
+ xorl %edx, %edx
+ 1:
+ movw (%esi), %bx
+ movzx %bx, %ecx
+ wrmsr
+ add $2, %esi
+ dec %edi
+ jnz 1b
+
+ post_code(0x23)
+ /* Set Cache-as-RAM base address. */
+ movl $(MTRRphysBase_MSR(0)), %ecx
+ movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
+ xorl %edx, %edx
+ wrmsr
+
+ post_code(0x24)
+ /* Set Cache-as-RAM mask. */
+ movl $(MTRRphysMask_MSR(0)), %ecx
+ movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
+ movl $CPU_PHYSMASK_HI, %edx
+ wrmsr
+
+ post_code(0x25)
+ /* Set Cache-as-RAM base address. */
+ movl $(MTRRphysBase_MSR(1)), %ecx
+ movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
+ xorl %edx, %edx
+ wrmsr
+
+ movl $(MTRRphysMask_MSR(1)), %ecx
+ movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
+ movl $CPU_PHYSMASK_HI, %edx
+ wrmsr
+
+ /* Enable MTRR. */
+ movl $MTRRdefType_MSR, %ecx
+ rdmsr
+ orl $MTRRdefTypeEn, %eax
+ wrmsr
+
+ post_code(0x26)
+
+ /* Enable the L2 cache. */
+ movl $BBL_CR_CTL3_MSR, %ecx
+ rdmsr
+ orl $0x100, %eax
+ wrmsr
+
+ post_code(0x27)
+
+ /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
+ movl %cr0, %eax
+ andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
+ invd
+ movl %eax, %cr0
+
+ /* enable the 'no eviction' mode */
+ movl $NoEvictMod_MSR, %ecx
+ rdmsr
+ orl $1, %eax
+ wrmsr
+
+ post_code(0x28)
+
+ /* Clear the cache memory region. This will also fill up the cache */
+ movl $CACHE_AS_RAM_BASE, %esi
+ movl %esi, %edi
+ movl $(CACHE_AS_RAM_SIZE / 4), %ecx
+ xorl %eax, %eax
+ rep stosl
+
+ /* enable no evict mode */
+ movl $NoEvictMod_MSR, %ecx
+ rdmsr
+ orl $2, %eax
+ wrmsr
+
+ post_code(0x29)
+
+ /* Setup the stack. */
+ movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
+ movl %eax, %esp
+
+ /* Restore the BIST result. */
+ movl %ebp, %eax
+ movl %esp, %ebp
+ pushl %eax
+
+before_romstage:
+ post_code(0x2a)
+ /* Call romstage.c main function. */
+ call romstage_main
+ /* Save return value from romstage_main. It contains the stack to use
+ * after cache-as-ram is torn down. It also contains the information
+ * for setting up MTRRs. */
+ movl %eax, %ebx
+
+ post_code(0x2b)
+
+ /* Disable cache. */
+ movl %cr0, %eax
+ orl $CR0_CacheDisable, %eax
+ movl %eax, %cr0
+
+ post_code(0x2c)
+
+ /* Disable MTRR. */
+ movl $MTRRdefType_MSR, %ecx
+ rdmsr
+ andl $(~MTRRdefTypeEn), %eax
+ wrmsr
+
+ invd
+
+ post_code(0x2d)
+
+ /* Disable the no eviction run state */
+ movl $NoEvictMod_MSR, %ecx
+ rdmsr
+ andl $~2, %eax
+ wrmsr
+
+ /* Disable the no eviction mode */
+ rdmsr
+ andl $~1, %eax
+ wrmsr
+
+ post_code(0x2e)
+
+ /* Setup stack as indicated by return value from ramstage_main(). */
+ movl %ebx, %esp
+
+ /* Get number of MTRRs. */
+ popl %ebx
+ movl $MTRRphysBase_MSR(0), %ecx
+1:
+ testl %ebx, %ebx
+ jz 1f
+
+ /* Low 32 bits of MTRR base. */
+ popl %eax
+ /* Upper 32 bits of MTRR base. */
+ popl %edx
+ /* Write MTRR base. */
+ wrmsr
+ inc %ecx
+ /* Low 32 bits of MTRR mask. */
+ popl %eax
+ /* Upper 32 bits of MTRR mask. */
+ popl %edx
+ /* Write MTRR mask. */
+ wrmsr
+ inc %ecx
+
+ dec %ebx
+ jmp 1b
+1:
+ post_code(0x2f)
+
+ /* And enable cache again after setting MTRRs. */
+ movl %cr0, %eax
+ andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
+ movl %eax, %cr0
+
+ post_code(0x30)
+
+ /* Enable MTRR. */
+ movl $MTRRdefType_MSR, %ecx
+ rdmsr
+ orl $MTRRdefTypeEn, %eax
+ wrmsr
+
+ post_code(0x31)
+
+__main:
+ post_code(POST_PREPARE_RAMSTAGE)
+ cld /* Clear direction flag. */
+ call romstage_after_car
+
+.Lhlt:
+ post_code(POST_DEAD_CODE)
+ hlt
+ jmp .Lhlt
+
+/* Fixed MTRRs */
+fixed_mtrr_table:
+ .word 0x250, 0x258, 0x259
+ .word 0x268, 0x269, 0x26A
+ .word 0x26B, 0x26C, 0x26D
+ .word 0x26E, 0x26F
+fixed_mtrr_table_end:
+
diff --git a/src/soc/intel/baytrail/romstage/raminit.c b/src/soc/intel/baytrail/romstage/raminit.c
new file mode 100644
index 0000000000..68836d3ada
--- /dev/null
+++ b/src/soc/intel/baytrail/romstage/raminit.c
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 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 <arch/io.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <device/pci_def.h>
+#include <baytrail/gpio.h>
+#include <baytrail/mrc_cache.h>
+#include <baytrail/iomap.h>
+#include <baytrail/pci_devs.h>
+#include <baytrail/romstage.h>
+
+
+static void enable_smbus(void)
+{
+ uint32_t reg;
+ const uint32_t smbus_dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
+
+ /* SMBus I/O BAR */
+ reg = SMBUS_BASE_ADDRESS | 2;
+ pci_write_config32(smbus_dev, PCI_BASE_ADDRESS_4, reg);
+ /* Enable decode of I/O space. */
+ reg = pci_read_config16(smbus_dev, PCI_COMMAND);
+ reg |= 0x1;
+ pci_write_config16(smbus_dev, PCI_COMMAND, reg);
+ /* Enable Host Controller */
+ reg = pci_read_config8(smbus_dev, 0x40);
+ reg |= 1;
+ pci_write_config8(smbus_dev, 0x40, reg);
+
+ /* Configure pads to be used for SMBus */
+ score_select_func(PCU_SMB_CLK_PAD, 1);
+ score_select_func(PCU_SMB_DATA_PAD, 1);
+}
+
+void raminit(struct mrc_params *mp, int prev_sleep_state)
+{
+ int ret;
+ mrc_wrapper_entry_t mrc_entry;
+ const struct mrc_saved_data *cache;
+
+ /* Fill in default entries. */
+ mp->version = MRC_PARAMS_VER;
+ mp->console_out = &console_tx_byte;
+ mp->prev_sleep_state = prev_sleep_state;
+
+ if (!mrc_cache_get_current(&cache)) {
+ mp->saved_data_size = cache->size;
+ mp->saved_data = &cache->data[0];
+ } else {
+ printk(BIOS_DEBUG, "No MRC cache found.\n");
+ }
+
+ mrc_entry = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab,
+ NULL);
+
+ if (mrc_entry == NULL) {
+ printk(BIOS_DEBUG, "Couldn't find mrc.bin\n");
+ return;
+ }
+ if (mp->mainboard.dram_info_location == DRAM_INFO_SPD_SMBUS)
+ enable_smbus();
+
+ ret = mrc_entry(mp);
+
+ cbmem_initialize_empty();
+
+ printk(BIOS_DEBUG, "MRC Wrapper returned %d\n", ret);
+ printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", mp->data_to_save,
+ mp->data_to_save_size);
+
+ if (mp->data_to_save != NULL && mp->data_to_save_size > 0)
+ mrc_cache_stash_data(mp->data_to_save, mp->data_to_save_size);
+}
diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c
new file mode 100644
index 0000000000..d3538991bb
--- /dev/null
+++ b/src/soc/intel/baytrail/romstage/romstage.c
@@ -0,0 +1,218 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 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 <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/cbfs.h>
+#include <arch/stages.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <cpu/x86/mtrr.h>
+#include <romstage_handoff.h>
+#include <baytrail/gpio.h>
+#include <baytrail/iomap.h>
+#include <baytrail/iosf.h>
+#include <baytrail/lpc.h>
+#include <baytrail/pci_devs.h>
+#include <baytrail/romstage.h>
+
+/* The cache-as-ram assembly file calls romstage_main() after setting up
+ * cache-as-ram. romstage_main() will then call the mainboards's
+ * mainboard_romstage_entry() function. That function then calls
+ * romstage_common() below. The reason for the back and forth is to provide
+ * common entry point from cache-as-ram while still allowing for code sharing.
+ * Because we can't use global variables the stack is used for allocations --
+ * thus the need to call back and forth. */
+
+static void *setup_stack_and_mttrs(void);
+
+static void program_base_addresses(void)
+{
+ uint32_t reg;
+ const uint32_t lpc_dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
+
+ /* Memory Mapped IO registers. */
+ reg = PMC_BASE_ADDRESS | 2;
+ pci_write_config32(lpc_dev, PBASE, reg);
+ reg = IO_BASE_ADDRESS | 2;
+ pci_write_config32(lpc_dev, IOBASE, reg);
+ reg = ILB_BASE_ADDRESS | 2;
+ pci_write_config32(lpc_dev, IBASE, reg);
+ reg = SPI_BASE_ADDRESS | 2;
+ pci_write_config32(lpc_dev, SBASE, reg);
+ reg = MPHY_BASE_ADDRESS | 2;
+ pci_write_config32(lpc_dev, MPBASE, reg);
+ reg = RCBA_BASE_ADDRESS | 1;
+ pci_write_config32(lpc_dev, RCBA, reg);
+
+ /* IO Port Registers. */
+ reg = ACPI_BASE_ADDRESS | 2;
+ pci_write_config32(lpc_dev, ABASE, reg);
+ reg = GPIO_BASE_ADDRESS | 2;
+ pci_write_config32(lpc_dev, GBASE, reg);
+}
+
+/* Entry from cache-as-ram.inc. */
+void * asmlinkage romstage_main(unsigned long bist)
+{
+ /* Call into mainboard. */
+ mainboard_romstage_entry(bist);
+
+ return setup_stack_and_mttrs();
+}
+
+/* Entry from the mainboard. */
+void romstage_common(const struct romstage_params *params)
+{
+ struct romstage_handoff *handoff;
+
+ program_base_addresses();
+
+ byt_config_com1_and_enable();
+
+ console_init();
+
+ /* Initialize RAM */
+ raminit(params->mrc_params, 5);
+
+ handoff = romstage_handoff_find_or_add();
+ if (handoff != NULL)
+ handoff->s3_resume = 0;
+ else
+ printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
+
+}
+
+static void open_up_spi(void)
+{
+ const uintptr_t sbase = SPI_BASE_ADDRESS;
+
+ /* Disable generating SMI when setting WPD bit. */
+ write32(sbase + 0xf8, read32(sbase + 0xf8) & ~(1 << 7));
+ /* Disable the SMM-only BIOS write and set WPD bit. */
+ write32(sbase + 0xfc, 1 | (read32(sbase + 0xfc) & ~(1 << 5)));
+}
+
+void asmlinkage romstage_after_car(void)
+{
+ /* Allow BIOS to program SPI part. */
+ open_up_spi();
+
+ /* Load the ramstage. */
+ copy_and_run();
+ while (1);
+}
+
+static inline uint32_t *stack_push(u32 *stack, u32 value)
+{
+ stack = &stack[-1];
+ *stack = value;
+ return stack;
+}
+
+/* Romstage needs quite a bit of stack for decompressing images since the lzma
+ * lib keeps its state on the stack during romstage. */
+static unsigned long choose_top_of_stack(void)
+{
+ unsigned long stack_top;
+ const unsigned long romstage_ram_stack_size = 0x5000;
+
+ /* cbmem_add() does a find() before add(). */
+ stack_top = (unsigned long)cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK,
+ romstage_ram_stack_size);
+ stack_top += romstage_ram_stack_size;
+ return stack_top;
+}
+
+/* setup_stack_and_mttrs() determines the stack to use after
+ * cache-as-ram is torn down as well as the MTRR settings to use. */
+static void *setup_stack_and_mttrs(void)
+{
+ unsigned long top_of_stack;
+ int num_mtrrs;
+ uint32_t *slot;
+ uint32_t mtrr_mask_upper;
+ uint32_t top_of_ram;
+
+ /* Top of stack needs to be aligned to a 4-byte boundary. */
+ top_of_stack = choose_top_of_stack() & ~3;
+ slot = (void *)top_of_stack;
+ num_mtrrs = 0;
+
+ /* The upper bits of the MTRR mask need to set according to the number
+ * of physical address bits. */
+ mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1;
+
+ /* The order for each MTRR is value then base with upper 32-bits of
+ * each value coming before the lower 32-bits. The reasoning for
+ * this ordering is to create a stack layout like the following:
+ * +0: Number of MTRRs
+ * +4: MTRR base 0 31:0
+ * +8: MTRR base 0 63:32
+ * +12: MTRR mask 0 31:0
+ * +16: MTRR mask 0 63:32
+ * +20: MTRR base 1 31:0
+ * +24: MTRR base 1 63:32
+ * +28: MTRR mask 1 31:0
+ * +32: MTRR mask 1 63:32
+ */
+
+ /* Cache the ROM as WP just below 4GiB. */
+ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
+ slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRRphysMaskValid);
+ slot = stack_push(slot, 0); /* upper base */
+ slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT);
+ num_mtrrs++;
+
+ /* Cache RAM as WB from 0 -> CONFIG_RAMTOP. */
+ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
+ slot = stack_push(slot, ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid);
+ slot = stack_push(slot, 0); /* upper base */
+ slot = stack_push(slot, 0 | MTRR_TYPE_WRBACK);
+ num_mtrrs++;
+
+ top_of_ram = (uint32_t)cbmem_top();
+ /* Cache 8MiB below the top of ram. The top of ram under 4GiB is the
+ * start of the TSEG region. It is required to be 8MiB aligned. Set
+ * this area as cacheable so it can be used later for ramstage before
+ * setting up the entire RAM as cacheable. */
+ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
+ slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid);
+ slot = stack_push(slot, 0); /* upper base */
+ slot = stack_push(slot, (top_of_ram - (8 << 20)) | MTRR_TYPE_WRBACK);
+ num_mtrrs++;
+
+ /* Cache 8MiB at the top of ram. Top of ram is where the TSEG
+ * region resides. However, it is not restricted to SMM mode until
+ * SMM has been relocated. By setting the region to cacheable it
+ * provides faster access when relocating the SMM handler as well
+ * as using the TSEG region for other purposes. */
+ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
+ slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid);
+ slot = stack_push(slot, 0); /* upper base */
+ slot = stack_push(slot, top_of_ram | MTRR_TYPE_WRBACK);
+ num_mtrrs++;
+
+ /* Save the number of MTRRs to setup. Return the stack location
+ * pointing to the number of MTRRs. */
+ slot = stack_push(slot, num_mtrrs);
+
+ return slot;
+}
diff --git a/src/soc/intel/baytrail/romstage/uart.c b/src/soc/intel/baytrail/romstage/uart.c
new file mode 100644
index 0000000000..dee3be95c3
--- /dev/null
+++ b/src/soc/intel/baytrail/romstage/uart.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 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 <arch/io.h>
+#include <baytrail/gpio.h>
+#include <baytrail/iomap.h>
+#include <baytrail/lpc.h>
+#include <baytrail/pci_devs.h>
+#include <baytrail/romstage.h>
+
+void byt_config_com1_and_enable(void)
+{
+ uint32_t reg;
+
+ /* Enable the UART hardware for COM1. */
+ reg = 1;
+ pci_write_config32(PCI_DEV(0, LPC_DEV, 0), UART_CONT, reg);
+
+ /* Set up the pads to select the UART function. RXD and TXD are
+ * 0x520 and 0x530, respectively. */
+ write32(IO_BASE_ADDRESS + 0x520, read32(IO_BASE_ADDRESS + 0x520) | 1);
+ write32(IO_BASE_ADDRESS + 0x530, read32(IO_BASE_ADDRESS + 0x530) | 1);
+}