summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2018-12-03 07:26:16 -0500
committerTom Rini <trini@konsulko.com>2018-12-03 07:26:16 -0500
commite54457f7495e6fe527d1bad0d8cc7b717558a759 (patch)
tree5fe3560f24686a1152053805b3555c7423d52271
parent952061352acfd24034e6990b6b7d32cded020c0a (diff)
parent6ef705b1575045f7b63bf011a0774228159715b2 (diff)
Merge tag 'arc-updates-for-2019.01-rc1' of git://git.denx.de/u-boot-arc
We introduce much better automatic identification of ARC cores. 1. Try to match found HW features to known ARC core templates 2. Print CPU frequency for all ARC boards 3. Add more board-specific info
-rw-r--r--arch/arc/include/asm/arcregs.h25
-rw-r--r--arch/arc/lib/cpu.c200
-rw-r--r--board/synopsys/axs10x/axs10x.c8
-rw-r--r--board/synopsys/emsdp/emsdp.c70
-rw-r--r--board/synopsys/hsdk/hsdk.c8
-rw-r--r--board/synopsys/iot_devkit/iot_devkit.c10
-rw-r--r--include/configs/emsdp.h2
7 files changed, 274 insertions, 49 deletions
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 9920d2e7195..fff6591c681 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -16,6 +16,20 @@
* access: "lr"/"sr".
*/
+/*
+ * Typically 8 least significant bits of Build Configuration Register (BCR)
+ * describe version of the HW block in question. Moreover if decoded version
+ * is 0 this means given HW block is absent - this is especially useful because
+ * we may safely read BRC regardless HW block existence while an attempt to
+ * access any other AUX regs associated with this HW block lead to imediate
+ * "instruction error" exception.
+ *
+ * I.e. before using any cofigurable HW block it's required to make sure it
+ * exists at all, and for that we introduce a special macro below.
+ */
+#define ARC_BCR_VERSION_MASK GENMASK(7, 0)
+#define ARC_FEATURE_EXISTS(bcr) !!(__builtin_arc_lr(bcr) & ARC_BCR_VERSION_MASK)
+
#define ARC_AUX_IDENTITY 0x04
#define ARC_AUX_STATUS32 0x0a
@@ -73,7 +87,7 @@
#define ARC_BCR_CLUSTER 0xcf
/* MMU Management regs */
-#define ARC_AUX_MMU_BCR 0x06f
+#define ARC_AUX_MMU_BCR 0x6f
/* IO coherency related auxiliary registers */
#define ARC_AUX_IO_COH_ENABLE 0x500
@@ -81,6 +95,15 @@
#define ARC_AUX_IO_COH_AP0_BASE 0x508
#define ARC_AUX_IO_COH_AP0_SIZE 0x509
+/* XY-memory related */
+#define ARC_AUX_XY_BUILD 0x79
+
+/* DSP-extensions related auxiliary registers */
+#define ARC_AUX_DSP_BUILD 0x7A
+
+/* ARC Subsystems related auxiliary registers */
+#define ARC_AUX_SUBSYS_BUILD 0xF0
+
#ifndef __ASSEMBLY__
/* Accessors for auxiliary registers */
#define read_aux_reg(reg) __builtin_arc_lr(reg)
diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c
index a969a167228..07daaa8d155 100644
--- a/arch/arc/lib/cpu.c
+++ b/arch/arc/lib/cpu.c
@@ -4,6 +4,7 @@
*/
#include <common.h>
+#include <malloc.h>
#include <asm/arcregs.h>
#include <asm/cache.h>
@@ -35,34 +36,193 @@ int dram_init(void)
}
#ifdef CONFIG_DISPLAY_CPUINFO
-const char *decode_identity(void)
+const char *arc_700_version(int arcver, char *name, int name_len)
{
- int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
+ const char *arc_ver;
+
+ switch (arcver) {
+ case 0x32:
+ arc_ver = "v4.4-4.5";
+ break;
+ case 0x33:
+ arc_ver = "v4.6-v4.9";
+ break;
+ case 0x34:
+ arc_ver = "v4.10";
+ break;
+ case 0x35:
+ arc_ver = "v4.11";
+ break;
+ default:
+ arc_ver = "unknown version";
+ }
+
+ snprintf(name, name_len, "ARC 700 %s", arc_ver);
+
+ return name;
+}
+
+struct em_template_t {
+ const bool cache;
+ const bool dsp;
+ const bool xymem;
+ const char name[8];
+};
+
+static const struct em_template_t em_versions[] = {
+ {false, false, false, "EM4"},
+ {true, false, false, "EM6"},
+ {false, true, false, "EM5D"},
+ {true, true, false, "EM7D"},
+ {false, true, true, "EM9D"},
+ {true, true, true, "EM11D"},
+};
+
+const char *arc_em_version(int arcver, char *name, int name_len)
+{
+ const char *arc_name = "EM";
+ const char *arc_ver;
+ bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
+ bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
+ bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
+ int i;
+
+ for (i = 0; i++ < sizeof(em_versions) / sizeof(struct em_template_t);) {
+ if (em_versions[i].cache == cache &&
+ em_versions[i].dsp == dsp &&
+ em_versions[i].xymem == xymem) {
+ arc_name = em_versions[i].name;
+ break;
+ }
+ }
+
+ switch (arcver) {
+ case 0x41:
+ arc_ver = "v1.1a";
+ break;
+ case 0x42:
+ arc_ver = "v3.0";
+ break;
+ case 0x43:
+ arc_ver = "v4.0";
+ break;
+ case 0x44:
+ arc_ver = "v5.0";
+ break;
+ default:
+ arc_ver = "unknown version";
+ }
+
+ snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
+
+ return name;
+}
+
+struct hs_template_t {
+ const bool cache;
+ const bool mmu;
+ const bool dual_issue;
+ const bool dsp;
+ const char name[8];
+};
+
+static const struct hs_template_t hs_versions[] = {
+ {false, false, false, false, "HS34"},
+ {true, false, false, false, "HS36"},
+ {true, true, false, false, "HS38"},
+ {false, false, true, false, "HS44"},
+ {true, false, true, false, "HS46"},
+ {true, true, true, false, "HS48"},
+ {false, false, true, true, "HS45D"},
+ {true, false, true, true, "HS47D"},
+};
+
+const char *arc_hs_version(int arcver, char *name, int name_len)
+{
+ const char *arc_name = "HS";
+ const char *arc_ver;
+ bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
+ bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
+ bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
+ bool dual_issue = arcver == 0x54 ? true : false;
+ int i;
+
+ for (i = 0; i++ < sizeof(hs_versions) / sizeof(struct hs_template_t);) {
+ if (hs_versions[i].cache == cache &&
+ hs_versions[i].mmu == mmu &&
+ hs_versions[i].dual_issue == dual_issue &&
+ hs_versions[i].dsp == dsp) {
+ arc_name = hs_versions[i].name;
+ break;
+ }
+ }
switch (arcver) {
- /* ARCompact cores */
- case 0x32: return "ARC 700 v4.4-4.5";
- case 0x33: return "ARC 700 v4.6-v4.9";
- case 0x34: return "ARC 700 v4.10";
- case 0x35: return "ARC 700 v4.11";
-
- /* ARCv2 cores */
- case 0x41: return "ARC EM v1.1a";
- case 0x42: return "ARC EM v3.0";
- case 0x43: return "ARC EM v4.0";
- case 0x50: return "ARC HS v1.0";
- case 0x51: return "ARC EM v2.0";
- case 0x52: return "ARC EM v2.1";
- case 0x53: return "ARC HS v3.0";
- case 0x54: return "ARC HS v4.0";
-
- default: return "Unknown ARC core";
+ case 0x50:
+ arc_ver = "v1.0";
+ break;
+ case 0x51:
+ arc_ver = "v2.0";
+ break;
+ case 0x52:
+ arc_ver = "v2.1c";
+ break;
+ case 0x53:
+ arc_ver = "v3.0";
+ break;
+ case 0x54:
+ arc_ver = "v4.0";
+ break;
+ default:
+ arc_ver = "unknown version";
}
+
+ snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
+
+ return name;
+}
+
+const char *decode_identity(void)
+{
+#define MAX_CPU_NAME_LEN 64
+
+ int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
+ char *name = malloc(MAX_CPU_NAME_LEN);
+
+ if (arcver >= 0x50)
+ return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
+ else if (arcver >= 0x40)
+ return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
+ else if (arcver >= 0x30)
+ return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
+ else
+ return "Unknown ARC core";
+}
+
+const char *decode_subsystem(void)
+{
+ int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);
+
+ switch (subsys_type) {
+ case 0: return NULL;
+ case 2: return "ARC Sensor & Control IP Subsystem";
+ case 3: return "ARC Data Fusion IP Subsystem";
+ case 4: return "ARC Secure Subsystem";
+ default: return "Unknown subsystem";
+ };
}
__weak int print_cpuinfo(void)
{
- printf("CPU: %s\n", decode_identity());
+ const char *subsys_name = decode_subsystem();
+ char mhz[8];
+
+ printf("CPU: %s at %s MHz\n", decode_identity(),
+ strmhz(mhz, gd->cpu_clk));
+
+ if (subsys_name)
+ printf("Subsys:%s\n", subsys_name);
+
return 0;
}
#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/board/synopsys/axs10x/axs10x.c b/board/synopsys/axs10x/axs10x.c
index c95f7af7a76..ffa7c154b54 100644
--- a/board/synopsys/axs10x/axs10x.c
+++ b/board/synopsys/axs10x/axs10x.c
@@ -109,3 +109,11 @@ void smp_kick_all_cpus(void)
writel(cmd, (void __iomem *)AXC003_CREG_CPU_START);
}
#endif
+
+int checkboard(void)
+{
+ printf("Board: ARC Software Development Platform AXS%s\n",
+ is_isa_arcv2() ? "103" : "101");
+
+ return 0;
+};
diff --git a/board/synopsys/emsdp/emsdp.c b/board/synopsys/emsdp/emsdp.c
index b5ec7f17ec1..c0770b58c1f 100644
--- a/board/synopsys/emsdp/emsdp.c
+++ b/board/synopsys/emsdp/emsdp.c
@@ -7,10 +7,46 @@
#include <dwmmc.h>
#include <malloc.h>
+#include <asm/arcregs.h>
+
DECLARE_GLOBAL_DATA_PTR;
-#define ARC_PERIPHERAL_BASE 0xF0000000
-#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0x10000)
+#define ARC_PERIPHERAL_BASE 0xF0000000
+
+#define CGU_ARC_FMEAS_ARC (void *)(ARC_PERIPHERAL_BASE + 0x84)
+#define CGU_ARC_FMEAS_ARC_START BIT(31)
+#define CGU_ARC_FMEAS_ARC_DONE BIT(30)
+#define CGU_ARC_FMEAS_ARC_CNT_MASK GENMASK(14, 0)
+#define CGU_ARC_FMEAS_ARC_RCNT_OFFSET 0
+#define CGU_ARC_FMEAS_ARC_FCNT_OFFSET 15
+
+#define SDIO_BASE (void *)(ARC_PERIPHERAL_BASE + 0x10000)
+
+int mach_cpu_init(void)
+{
+ int rcnt, fcnt;
+ u32 data;
+
+ /* Start frequency measurement */
+ writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);
+
+ /* Poll DONE bit */
+ do {
+ data = readl(CGU_ARC_FMEAS_ARC);
+ } while (!(data & CGU_ARC_FMEAS_ARC_DONE));
+
+ /* Amount of reference 100 MHz clocks */
+ rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
+ CGU_ARC_FMEAS_ARC_CNT_MASK);
+
+ /* Amount of CPU clocks */
+ fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
+ CGU_ARC_FMEAS_ARC_CNT_MASK);
+
+ gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
+
+ return 0;
+}
int board_mmc_init(bd_t *bis)
{
@@ -24,7 +60,7 @@ int board_mmc_init(bd_t *bis)
memset(host, 0, sizeof(struct dwmci_host));
host->name = "Synopsys Mobile storage";
- host->ioaddr = (void *)SDIO_BASE;
+ host->ioaddr = SDIO_BASE;
host->buswidth = 4;
host->dev_index = 0;
host->bus_hz = 50000000;
@@ -42,31 +78,32 @@ int board_mmc_getcd(struct mmc *mmc)
}
#define CREG_BASE 0xF0001000
-#define CREG_BOOT_OFFSET 0
-#define CREG_BOOT_WP_OFFSET 8
+#define CREG_BOOT (void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_SW_RESET (void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_VERSION (void *)(CREG_BASE + 0x0FF8)
-#define CGU_BASE 0xF0000000
-#define CGU_IP_SW_RESET 0x0FF0
+/* Bits in CREG_BOOT register */
+#define CREG_BOOT_WP_BIT BIT(8)
void reset_cpu(ulong addr)
{
- writel(1, (u32 *)(CGU_BASE + CGU_IP_SW_RESET));
+ writel(1, CREG_IP_SW_RESET);
while (1)
; /* loop forever till reset */
}
static int do_emsdp_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
- u32 creg_boot = readl((u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+ u32 creg_boot = readl(CREG_BOOT);
if (!strcmp(argv[1], "unlock"))
- creg_boot &= ~BIT(CREG_BOOT_WP_OFFSET);
+ creg_boot &= ~CREG_BOOT_WP_BIT;
else if (!strcmp(argv[1], "lock"))
- creg_boot |= BIT(CREG_BOOT_WP_OFFSET);
+ creg_boot |= CREG_BOOT_WP_BIT;
else
return CMD_RET_USAGE;
- writel(creg_boot, (u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+ writel(creg_boot, CREG_BOOT);
return CMD_RET_SUCCESS;
}
@@ -97,3 +134,12 @@ U_BOOT_CMD(
"rom unlock - Unlock non-volatile memory for writing\n"
"emsdp rom lock - Lock non-volatile memory to prevent writing\n"
);
+
+int checkboard(void)
+{
+ int version = readl(CREG_IP_VERSION);
+
+ printf("Board: ARC EM Software Development Platform v%d.%d\n",
+ (version >> 16) & 0xff, version & 0xff);
+ return 0;
+};
diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c
index b6aefdbe6d6..8a2c201477c 100644
--- a/board/synopsys/hsdk/hsdk.c
+++ b/board/synopsys/hsdk/hsdk.c
@@ -1054,10 +1054,8 @@ int board_mmc_init(bd_t *bis)
return 0;
}
-#ifdef CONFIG_DISPLAY_CPUINFO
-int print_cpuinfo(void)
+int checkboard(void)
{
- printf("CPU: ARC HS38 v2.1c\n");
+ puts("Board: Synopsys ARC HS Development Kit\n");
return 0;
-}
-#endif /* CONFIG_DISPLAY_CPUINFO */
+};
diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c
index f8838fb3ce8..8424e09bd3c 100644
--- a/board/synopsys/iot_devkit/iot_devkit.c
+++ b/board/synopsys/iot_devkit/iot_devkit.c
@@ -189,13 +189,3 @@ int checkboard(void)
puts("Board: Synopsys IoT Development Kit\n");
return 0;
};
-
-#ifdef CONFIG_DISPLAY_CPUINFO
-int print_cpuinfo(void)
-{
- char mhz[8];
-
- printf("CPU: ARC EM9D at %s MHz\n", strmhz(mhz, gd->cpu_clk));
- return 0;
-}
-#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/include/configs/emsdp.h b/include/configs/emsdp.h
index 385d59e3387..9a205edc7c0 100644
--- a/include/configs/emsdp.h
+++ b/include/configs/emsdp.h
@@ -11,7 +11,7 @@
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_SDRAM_BASE 0x10000000
-#define CONFIG_SYS_SDRAM_SIZE SZ_8M
+#define CONFIG_SYS_SDRAM_SIZE SZ_16M
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_1M)