summaryrefslogtreecommitdiff
path: root/board/synopsys
diff options
context:
space:
mode:
authorAlexey Brodkin <abrodkin@synopsys.com>2018-01-24 21:37:14 +0300
committerAlexey Brodkin <abrodkin@synopsys.com>2018-10-05 16:57:00 +0300
commit5396e8b1dd0ad9741b04f506ef88b5fb49d4c82a (patch)
treee61be616d3f0cb863c07a130dd24130145538ba0 /board/synopsys
parentf31414a0ed15b4ad39de9500c15c4c46b326cda4 (diff)
arc: Add support for IoT development kit
The DesignWare ARC IoT Development Kit is a versatile platform that includes the necessary hardware and software to accelerate software development and debugging of sensor fusion, voice recognition and face detection designs. More information is avaialble here [1] and here [2]. The board is based on real silicon with ARC EM9D-based Data Fusion IP Subsystem. It sports a rich set of I/O including * DW USB OTG * DW MobileStorage (used for micro SD-card) * GPIO * multiple serial interface including DW APB UART * ADC, PWM and eFlash, SRAM and SPI Flash memory * Real-Time Clock (RTC) * Bluetooth module with worldwide regulatory compliance (FCC, IC, CE, ETSI, TELEC) * On-board 9-axis sensor (gyro, accelerometer and compass) Extensible with Arduino, Pmod, mikroBUS connectors and a 2x18 extension header. One of the most interesting features for developers is built-in Digilent USB JTAG probe so only micro-USB cable is needed! [1] https://www.synopsys.com/dw/ipdir.php?ds=arc_iot_development_kit [2] https://www.synopsys.com/dw/doc.php/ds/cc/iot_dev_kit.pdf Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Diffstat (limited to 'board/synopsys')
-rw-r--r--board/synopsys/iot_devkit/Kconfig12
-rw-r--r--board/synopsys/iot_devkit/MAINTAINERS5
-rw-r--r--board/synopsys/iot_devkit/Makefile7
-rw-r--r--board/synopsys/iot_devkit/config.mk2
-rw-r--r--board/synopsys/iot_devkit/iot_devkit.c168
-rw-r--r--board/synopsys/iot_devkit/u-boot.lds77
6 files changed, 271 insertions, 0 deletions
diff --git a/board/synopsys/iot_devkit/Kconfig b/board/synopsys/iot_devkit/Kconfig
new file mode 100644
index 00000000000..ad956b20f77
--- /dev/null
+++ b/board/synopsys/iot_devkit/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_IOT_DEVKIT
+
+config SYS_BOARD
+ default "iot_devkit"
+
+config SYS_VENDOR
+ default "synopsys"
+
+config SYS_CONFIG_NAME
+ default "iot_devkit"
+
+endif
diff --git a/board/synopsys/iot_devkit/MAINTAINERS b/board/synopsys/iot_devkit/MAINTAINERS
new file mode 100644
index 00000000000..06457cfa6ae
--- /dev/null
+++ b/board/synopsys/iot_devkit/MAINTAINERS
@@ -0,0 +1,5 @@
+IOT DEVKIT BOARD
+M: Alexey Brodkin <abrodkin@synopsys.com>
+S: Maintained
+F: board/synopsys/iot_devkit/
+F: configs/iot_devkit_defconfig
diff --git a/board/synopsys/iot_devkit/Makefile b/board/synopsys/iot_devkit/Makefile
new file mode 100644
index 00000000000..16160246438
--- /dev/null
+++ b/board/synopsys/iot_devkit/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += iot_devkit.o
diff --git a/board/synopsys/iot_devkit/config.mk b/board/synopsys/iot_devkit/config.mk
new file mode 100644
index 00000000000..120733538a4
--- /dev/null
+++ b/board/synopsys/iot_devkit/config.mk
@@ -0,0 +1,2 @@
+PLATFORM_CPPFLAGS += -mlittle-endian -mcode-density -mdiv-rem -mswap -mnorm -mmpy-option=6 -mbarrel-shifter
+LDSCRIPT = $(srctree)/board/synopsys/iot_devkit/u-boot.lds
diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c
new file mode 100644
index 00000000000..c185d5cdb5c
--- /dev/null
+++ b/board/synopsys/iot_devkit/iot_devkit.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <dwmmc.h>
+#include <linux/libfdt.h>
+#include <fdtdec.h>
+
+#include <asm/arcregs.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define SYSCON_BASE 0xf000a000
+#define AHBCKDIV (void *)(SYSCON_BASE + 0x04)
+#define APBCKDIV (void *)(SYSCON_BASE + 0x08)
+#define APBCKEN (void *)(SYSCON_BASE + 0x0C)
+#define CLKSEL (void *)(SYSCON_BASE + 0x24)
+#define CLKSTAT (void *)(SYSCON_BASE + 0x28)
+#define PLLCON (void *)(SYSCON_BASE + 0x2C)
+#define APBCKSEL (void *)(SYSCON_BASE + 0x30)
+#define AHBCKEN (void *)(SYSCON_BASE + 0x34)
+#define USBPHY_PLL (void *)(SYSCON_BASE + 0x78)
+#define USBCFG (void *)(SYSCON_BASE + 0x7c)
+
+#define PLL_MASK_0 0xffcfffff
+#define PLL_MASK_1 0xffcfff00
+#define PLL_MASK_2 0xfbcfff00
+
+#define CLKSEL_DEFAULT 0x5a690000
+
+static int set_cpu_freq(unsigned int clk)
+{
+ clk /= 1000000;
+
+ /* Set clk to ext Xtal (LSN value 0) */
+ writel(CLKSEL_DEFAULT, CLKSEL);
+
+ switch (clk) {
+ case 16:
+ /* Bypass mode */
+ return 0;
+
+ case 50:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1, M=25, N=1, OD=3, PLL_OUT_CLK=50M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x300191, PLLCON);
+ /* pll_off=0, M=25, N=1, OD=3, PLL_OUT_CLK=50M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x300191, PLLCON);
+ break;
+
+ case 72:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1, M=18, N=1, OD=2, PLL_OUT_CLK=72M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x200121, PLLCON);
+ /* pll_off=0, M=18, N=1, OD=2, PLL_OUT_CLK=72M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x200121, PLLCON);
+ break;
+
+ case 100:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1,M=25, N=1, OD=2, PLL_OUT_CLK=100M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x200191, PLLCON);
+ /* pll_off=0,M=25, N=1, OD=2, PLL_OUT_CLK=100M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x200191, PLLCON);
+ break;
+
+ case 144:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x100121, PLLCON);
+ /* pll_off=0, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x100121, PLLCON);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ while (!(readl(CLKSTAT) & 0x4))
+ ;
+
+ /* Set clk from PLL on bus (LSN = 1) */
+ writel(CLKSEL_DEFAULT | BIT(0), CLKSEL);
+
+ return 0;
+}
+
+extern u8 __rom_end[];
+extern u8 __ram_start[];
+extern u8 __ram_end[];
+
+/*
+ * Use mach_cpu_init() for .data section copy as board_early_init_f() will be
+ * too late: initf_dm() will use a value of "av_" variable from not yet
+ * initialized (by copy) area.
+ */
+int mach_cpu_init(void)
+{
+ int offset, freq;
+
+ /* Don't relocate U-Boot */
+ gd->flags |= GD_FLG_SKIP_RELOC;
+
+ /* Copy data from ROM to RAM */
+ u8 *src = __rom_end;
+ u8 *dst = __ram_start;
+
+ while (dst < __ram_end)
+ *dst++ = *src++;
+
+ /* Enable debug uart */
+#define DEBUG_UART_BASE 0x80014000
+#define DEBUG_UART_DLF_OFFSET 0xc0
+ write_aux_reg(DEBUG_UART_BASE + DEBUG_UART_DLF_OFFSET, 1);
+
+ offset = fdt_path_offset(gd->fdt_blob, "/cpu_card/core_clk");
+ if (offset < 0)
+ return offset;
+
+ freq = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0);
+ if (!freq)
+ return -EINVAL;
+
+ /* If CPU freq > 100 MHz, divide eFLASH clock by 2 */
+ if (freq > 100000000) {
+ u32 reg = readl(AHBCKDIV);
+
+ reg &= ~(0xF << 8);
+ reg |= 2 << 8;
+ writel(reg, AHBCKDIV);
+ }
+
+ return set_cpu_freq(freq);
+}
+
+#define ARC_PERIPHERAL_BASE 0xF0000000
+#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xB000)
+
+int board_mmc_init(bd_t *bis)
+{
+ struct dwmci_host *host = NULL;
+
+ host = malloc(sizeof(struct dwmci_host));
+ if (!host) {
+ printf("dwmci_host malloc fail!\n");
+ return -ENOMEM;
+ }
+
+ memset(host, 0, sizeof(struct dwmci_host));
+ host->name = "Synopsys Mobile storage";
+ host->ioaddr = (void *)SDIO_BASE;
+ host->buswidth = 4;
+ host->dev_index = 0;
+ host->bus_hz = 50000000;
+
+ add_dwmci(host, host->bus_hz / 2, 400000);
+
+ return 0;
+}
+
+int checkboard(void)
+{
+ puts("Board: Synopsys IoT Development Kit\n");
+ return 0;
+};
diff --git a/board/synopsys/iot_devkit/u-boot.lds b/board/synopsys/iot_devkit/u-boot.lds
new file mode 100644
index 00000000000..d0831687055
--- /dev/null
+++ b/board/synopsys/iot_devkit/u-boot.lds
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+
+MEMORY {
+ ROM : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
+ RAM : ORIGIN = RAM_DATA_BASE, LENGTH = RAM_DATA_SIZE
+}
+
+OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc")
+OUTPUT_ARCH(arc)
+ENTRY(_start)
+SECTIONS
+{
+ . = CONFIG_SYS_MONITOR_BASE;
+ __image_copy_start = .;
+ .ivt :
+ {
+ __ivt_start = .;
+ KEEP(*(.ivt));
+ __ivt_end = .;
+ } > ROM
+
+ . = ALIGN(1024);
+ .text : {
+ __text_start = .;
+ arch/arc/lib/start.o (.text*)
+ *(.text*)
+ __text_end = .;
+ } > ROM
+
+ . = ALIGN(4);
+ .rodata : {
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } > ROM
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+
+ /* Mark RAM's LMA */
+ . = ALIGN(4);
+ __rom_end = .;
+ } > ROM
+
+ .data : {
+ /* Mark RAM's VMA */
+ . = ALIGN(4);
+
+ /*
+ * Everything between __ram_start and __ram_start will be
+ * copied from ROM to RAM in board_early_init_f().
+ */
+ __ram_start = .;
+
+ *(.data*)
+
+ __ram_end = .;
+ } > RAM AT > ROM
+
+ .bss : {
+ . = ALIGN(1024);
+ __bss_start = .;
+ *(.bss*)
+ __bss_end = .;
+ } > RAM
+
+ /* Keep relocation-related symbols to make linker happy */
+ __rel_dyn_start = .;
+ __rel_dyn_end = .;
+ __image_copy_end = .;
+ __init_end = .;
+}