From: Felipe Balbi <felipe.ba...@linux.intel.com>

Add Intel Tangier SoC support.

Intel Tangier SoC is a core part of Intel Merrifield platform. For
example, Intel Edison board is based on such platform.

The patch is based on work done by the following people (in alphabetical
order):
        Aiden Park <aiden.p...@intel.com>
        Dukjoon Jeon <dukjoon.j...@intel.com>
        eric.park <eric.p...@intel.com>
        Fabien Chereau <fabien.cher...@intel.com>
        Scott D Phillips <scott.d.phill...@intel.com>
        Sebastien Colleur <sebastienx.coll...@intel.com>
        Steve Sakoman <steve.sako...@intel.com>
        Vincent Tinelli <vincent.tine...@intel.com>

Signed-off-by: Vincent Tinelli <vincent.tine...@intel.com>
Signed-off-by: Felipe Balbi <felipe.ba...@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
---
 arch/x86/Kconfig                   |   1 +
 arch/x86/cpu/Makefile              |   1 +
 arch/x86/cpu/tangier/Kconfig       |  20 ++++
 arch/x86/cpu/tangier/Makefile      |   1 +
 arch/x86/cpu/tangier/car.S         |  13 +++
 arch/x86/cpu/tangier/sdram.c       | 234 +++++++++++++++++++++++++++++++++++++
 arch/x86/cpu/tangier/tangier.c     |  36 ++++++
 arch/x86/include/asm/dma-mapping.h |  41 +++++++
 8 files changed, 347 insertions(+)
 create mode 100644 arch/x86/cpu/tangier/Kconfig
 create mode 100644 arch/x86/cpu/tangier/Makefile
 create mode 100644 arch/x86/cpu/tangier/car.S
 create mode 100644 arch/x86/cpu/tangier/sdram.c
 create mode 100644 arch/x86/cpu/tangier/tangier.c
 create mode 100644 arch/x86/include/asm/dma-mapping.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9ead3ebccf..31f2d154d4 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -114,6 +114,7 @@ source "arch/x86/cpu/ivybridge/Kconfig"
 source "arch/x86/cpu/qemu/Kconfig"
 source "arch/x86/cpu/quark/Kconfig"
 source "arch/x86/cpu/queensbay/Kconfig"
+source "arch/x86/cpu/tangier/Kconfig"
 
 # architecture-specific options below
 
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 92a9023b0b..6f3535d216 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_QEMU) += qemu/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
 obj-$(CONFIG_INTEL_QUARK) += quark/
 obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/
+obj-$(CONFIG_INTEL_TANGIER) += tangier/
 obj-y += lapic.o ioapic.o
 obj-y += irq.o
 ifndef CONFIG_$(SPL_)X86_64
diff --git a/arch/x86/cpu/tangier/Kconfig b/arch/x86/cpu/tangier/Kconfig
new file mode 100644
index 0000000000..3545886a65
--- /dev/null
+++ b/arch/x86/cpu/tangier/Kconfig
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2015 Intel, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+config INTEL_TANGIER
+       bool
+       depends on INTEL_MID
+
+config SYS_CAR_ADDR
+       hex
+       default 0x19200000
+
+config SYS_CAR_SIZE
+       hex
+       default 0x4000
+       help
+         Space in bytes in eSRAM used as Cache-As-RAM (CAR).
+         Note this size must not exceed eSRAM's total size.
diff --git a/arch/x86/cpu/tangier/Makefile b/arch/x86/cpu/tangier/Makefile
new file mode 100644
index 0000000000..d937737057
--- /dev/null
+++ b/arch/x86/cpu/tangier/Makefile
@@ -0,0 +1 @@
+obj-y += car.o tangier.o sdram.o
diff --git a/arch/x86/cpu/tangier/car.S b/arch/x86/cpu/tangier/car.S
new file mode 100644
index 0000000000..6982106c19
--- /dev/null
+++ b/arch/x86/cpu/tangier/car.S
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010-2011
+ * Graeme Russ, <graeme.r...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+.section .text
+
+.globl car_init
+car_init:
+       jmp     car_init_ret
diff --git a/arch/x86/cpu/tangier/sdram.c b/arch/x86/cpu/tangier/sdram.c
new file mode 100644
index 0000000000..da046559a1
--- /dev/null
+++ b/arch/x86/cpu/tangier/sdram.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010,2011
+ * Graeme Russ, <graeme.r...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/bootparam.h>
+#include <asm/e820.h>
+#include <asm/global_data.h>
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/sfi.h>
+#include <asm/u-boot-x86.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Memory type definitions */
+enum sfi_mem_type {
+       SFI_MEM_RESERVED,
+       SFI_LOADER_CODE,
+       SFI_LOADER_DATA,
+       SFI_BOOT_SERVICE_CODE,
+       SFI_BOOT_SERVICE_DATA,
+       SFI_RUNTIME_SERVICE_CODE,
+       SFI_RUNTIME_SERVICE_DATA,
+       SFI_MEM_CONV,
+       SFI_MEM_UNUSABLE,
+       SFI_ACPI_RECLAIM,
+       SFI_ACPI_NVS,
+       SFI_MEM_MMIO,
+       SFI_MEM_IOPORT,
+       SFI_PAL_CODE,
+       SFI_MEM_TYPEMAX,
+};
+
+#define SFI_BASE_ADDR          0x000E0000
+#define SFI_LENGTH             0x00020000
+#define SFI_TABLE_LENGTH       16
+
+static int sfi_table_check(struct sfi_table_header *sbh)
+{
+       char chksum = 0;
+       char *pos = (char *)sbh;
+       int i;
+
+       if (sbh->len < SFI_TABLE_LENGTH)
+               return -1;
+
+       if (sbh->len > SFI_LENGTH)
+               return -1;
+
+       for (i = 0; i < sbh->len; i++)
+               chksum += *pos++;
+
+       if (chksum)
+               error("sfi: Invalid checksum\n");
+
+       /* Checksum is OK if zero */
+       return chksum;
+}
+
+static int sfi_table_is_type(struct sfi_table_header *sbh, const char 
*signature)
+{
+       return !strncmp(sbh->sig, signature, SFI_SIGNATURE_SIZE) &&
+              !sfi_table_check(sbh);
+}
+
+static struct sfi_table_simple *sfi_get_table_by_sig(unsigned long addr,
+                                                    const char *signature)
+{
+       struct sfi_table_simple *sb = NULL;
+       int i;
+
+       for (i = 0; i < SFI_LENGTH; i += SFI_TABLE_LENGTH) {
+               sb = (struct sfi_table_simple *)(addr + i);
+               if (sfi_table_is_type(&sb->header, signature))
+                       break;
+       }
+
+       if (i >= SFI_LENGTH || !sb)
+               return NULL;
+
+       return sb;
+}
+
+static struct sfi_table_simple *sfi_search_mmap(void)
+{
+       struct sfi_table_header *sbh;
+       struct sfi_table_simple *sb;
+       u32 sys_entry_cnt;
+       u32 i;
+
+       /* Find SYST table */
+       sb = sfi_get_table_by_sig(SFI_BASE_ADDR, SFI_SIG_SYST);
+       if (!sb) {
+               error("failed to locate SYST table\n");
+               return NULL;
+       }
+
+       sys_entry_cnt = (sb->header.len - sizeof(*sbh)) / 8;
+
+       /* Search through each SYST entry for MMAP table */
+       for (i = 0; i < sys_entry_cnt; i++) {
+               sbh = (struct sfi_table_header *)(unsigned long)sb->pentry[i];
+
+               if (sfi_table_is_type(sbh, SFI_SIG_MMAP))
+                       return (struct sfi_table_simple *) sbh;
+       }
+
+       error("failed to locate SFI MMAP table\n");
+       return NULL;
+}
+
+#define sfi_for_each_mentry(i, sb, mentry)                             \
+       for (i = 0, mentry = (struct sfi_mem_entry *)sb->pentry;        \
+            i < SFI_GET_NUM_ENTRIES(sb, struct sfi_mem_entry);         \
+            i++, mentry++)                                             \
+
+static unsigned sfi_setup_e820(unsigned max_entries, struct e820entry *entries)
+{
+       struct sfi_table_simple *sb;
+       struct sfi_mem_entry *mentry;
+       unsigned long long start, end, size;
+       int type, total = 0;
+       int i;
+
+       sb = sfi_search_mmap();
+       if (!sb)
+               return 0;
+
+       sfi_for_each_mentry(i, sb, mentry) {
+               start = mentry->phys_start;
+               size = mentry->pages << 12;
+               end = start + size;
+
+               if (start > end)
+                       continue;
+
+               /* translate SFI mmap type to E820 map type */
+               switch (mentry->type) {
+               case SFI_MEM_CONV:
+                       type = E820_RAM;
+                       break;
+               case SFI_MEM_UNUSABLE:
+               case SFI_RUNTIME_SERVICE_DATA:
+                       continue;
+               default:
+                       type = E820_RESERVED;
+               }
+
+               if (total == E820MAX)
+                       break;
+               entries[total].addr = start;
+               entries[total].size = size;
+               entries[total].type = type;
+
+               total++;
+       }
+
+       return total;
+}
+
+static int sfi_get_bank_size(void)
+{
+       struct sfi_table_simple *sb;
+       struct sfi_mem_entry *mentry;
+       int bank = 0;
+       int i;
+
+       sb = sfi_search_mmap();
+       if (!sb)
+               return -ENXIO;
+
+       sfi_for_each_mentry(i, sb, mentry) {
+               if (mentry->type != SFI_MEM_CONV)
+                       continue;
+
+               gd->bd->bi_dram[bank].start = mentry->phys_start;
+               gd->bd->bi_dram[bank].size = mentry->pages << 12;
+               bank++;
+       }
+
+       return bank;
+}
+
+static phys_size_t sfi_get_ram_size(void)
+{
+       struct sfi_table_simple *sb;
+       struct sfi_mem_entry *mentry;
+       phys_size_t ram = 0;
+       int i;
+
+       sb = sfi_search_mmap();
+       if (!sb)
+               return 0;
+
+       sfi_for_each_mentry(i, sb, mentry) {
+               if (mentry->type != SFI_MEM_CONV)
+                       continue;
+
+               ram += (mentry->pages << 12);
+       }
+
+       debug("RAM size %llu\n", ram);
+
+       return ram;
+}
+
+unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
+{
+       return sfi_setup_e820(max_entries, entries);
+}
+
+int dram_init_banksize(void)
+{
+       int ret;
+
+       ret = sfi_get_bank_size();
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int dram_init(void)
+{
+       gd->ram_size = sfi_get_ram_size();
+
+       return 0;
+}
diff --git a/arch/x86/cpu/tangier/tangier.c b/arch/x86/cpu/tangier/tangier.c
new file mode 100644
index 0000000000..c06767b915
--- /dev/null
+++ b/arch/x86/cpu/tangier/tangier.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2008
+ * Graeme Russ, graeme.r...@gmail.com.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/scu.h>
+#include <asm/u-boot-x86.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Miscellaneous platform dependent initializations
+ */
+int arch_cpu_init(void)
+{
+       return x86_cpu_init_f();
+}
+
+int checkcpu(void)
+{
+       return 0;
+}
+
+int print_cpuinfo(void)
+{
+       return default_print_cpuinfo();
+}
+
+void reset_cpu(ulong addr)
+{
+       scu_ipc_simple_command(IPCMSG_COLD_RESET, 0);
+}
diff --git a/arch/x86/include/asm/dma-mapping.h 
b/arch/x86/include/asm/dma-mapping.h
new file mode 100644
index 0000000000..7de4c08e36
--- /dev/null
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2007
+ * Stelian Pop <stel...@popies.net>
+ * Lead Tech Design <www.leadtechdesign.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef __ASM_X86_DMA_MAPPING_H
+#define __ASM_X86_DMA_MAPPING_H
+
+#define        dma_mapping_error(x, y) 0
+
+enum dma_data_direction {
+       DMA_BIDIRECTIONAL       = 0,
+       DMA_TO_DEVICE           = 1,
+       DMA_FROM_DEVICE         = 2,
+};
+
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
+{
+       *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
+       return (void *)*handle;
+}
+
+static inline void dma_free_coherent(void *addr)
+{
+       free(addr);
+}
+
+static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
+                                          enum dma_data_direction dir)
+{
+       return (unsigned long)vaddr;
+}
+
+static inline void dma_unmap_single(volatile void *vaddr, size_t len,
+                                   unsigned long paddr)
+{
+}
+
+#endif /* __ASM_X86_DMA_MAPPING_H */
-- 
2.11.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to