[coreboot-gerrit] Patch set updated for coreboot: Exynos7: Add timer initialization

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Fri May 20 18:22:41 CEST 2016


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14908

-gerrit

commit bb920b1657848b179a75db6ab8f1c625572386c8
Author: Akshay Saraswat <akshay.s at samsung.com>
Date:   Thu Aug 7 16:15:47 2014 +0530

    Exynos7: Add timer initialization
    
    Adding initial MCT setup for Exynos7.
    
    BUG=None
    BRANCH=None
    TEST=None
    
    Change-Id: I45df0ff9f95ca9165f3cc31d302b6616ee690d35
    Signed-off-by: Akshay Saraswat <akshay.s at samsung.com>
---
 src/soc/samsung/exynos7/Makefile.inc      |  9 ++++
 src/soc/samsung/exynos7/bootblock.c       |  6 +++
 src/soc/samsung/exynos7/include/soc/mct.h | 88 +++++++++++++++++++++++++++++++
 src/soc/samsung/exynos7/mct.c             | 32 +++++++++++
 src/soc/samsung/exynos7/monotonic_timer.c | 31 +++++++++++
 src/soc/samsung/exynos7/timer.c           | 52 ++++++++++++++++++
 6 files changed, 218 insertions(+)

diff --git a/src/soc/samsung/exynos7/Makefile.inc b/src/soc/samsung/exynos7/Makefile.inc
index f2b7b16..eeb9fcf 100644
--- a/src/soc/samsung/exynos7/Makefile.inc
+++ b/src/soc/samsung/exynos7/Makefile.inc
@@ -22,16 +22,25 @@ bootblock-y += bootblock.c
 bootblock-y += clock.c
 bootblock-y += clock_init.c
 bootblock-y += dmc_init_lpddr4.c
+bootblock-y += mct.c
+bootblock-y += monotonic_timer.c
 bootblock-y += power.c
+bootblock-y += timer.c
 
 # ROMSTAGE : Run primitive tests and remaining basic stuff
 romstage-y += clock.c
+romstage-y += mct.c
+romstage-y += monotonic_timer.c
 romstage-y += power.c
+romstage-y += timer.c
 
 # RAMSTAGE : Prepare and load payload
 ramstage-y += clock.c
 ramstage-y += cpu.c
+ramstage-y += mct.c
+ramstage-y += monotonic_timer.c
 ramstage-y += power.c
+ramstage-y += timer.c
 
 $(objcbfs)/bootblock.raw.elf: $(objcbfs)/bootblock.elf
 	cp $< $@
diff --git a/src/soc/samsung/exynos7/bootblock.c b/src/soc/samsung/exynos7/bootblock.c
index c197940..7183731 100644
--- a/src/soc/samsung/exynos7/bootblock.c
+++ b/src/soc/samsung/exynos7/bootblock.c
@@ -21,6 +21,7 @@
 #include <soc/clock.h>
 #include <soc/cpu.h>
 #include <soc/dmc.h>
+#include <soc/mct.h>
 #include <soc/power.h>
 
 void bootblock_cpu_init(void)
@@ -32,6 +33,11 @@ void bootblock_cpu_init(void)
 	if (power_read_reset_status() == EXYNOS7_CHECK_SLEEP)
 		is_resume = 1;
 
+	/* kick off the multi-core timer.
+	 * We want to do this as early as we can.
+	 */
+	mct_start();
+
 	/* SCR_EL3.NS|IRQ|FIQ|EA */
 	raw_write_scr_el3(raw_read_scr_el3() | 0xf);
 
diff --git a/src/soc/samsung/exynos7/include/soc/mct.h b/src/soc/samsung/exynos7/include/soc/mct.h
new file mode 100644
index 0000000..2308daa
--- /dev/null
+++ b/src/soc/samsung/exynos7/include/soc/mct.h
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ *
+ * 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 _CPU_SAMSUNG_EXYNOS7_MCT_H_
+#define _CPU_SAMSUNG_EXYNOS7_MCT_H_
+
+#include <stddef.h>
+#include <soc/cpu.h>
+
+struct exynos_mct {
+	uint32_t	mct_cfg;
+	uint8_t		reserved0[0xfc];
+	uint32_t	g_cnt_l;
+	uint32_t	g_cnt_u;
+	uint8_t		reserved1[0x8];
+	uint32_t	g_cnt_wstat;
+	uint8_t		reserved2[0xec];
+	uint32_t	g_comp0_l;
+	uint32_t	g_comp0_u;
+	uint32_t	g_comp0_addr_incr;
+	uint8_t		reserved3[0x4];
+	uint32_t	g_comp1_l;
+	uint32_t	g_comp1_u;
+	uint32_t	g_comp1_addr_incr;
+	uint8_t		reserved4[0x4];
+	uint32_t	g_comp2_l;
+	uint32_t	g_comp2_u;
+	uint32_t	g_comp2_addr_incr;
+	uint8_t		reserved5[0x4];
+	uint32_t	g_comp3_l;
+	uint32_t	g_comp3_u;
+	uint32_t	g_comp3_addr_incr;
+	uint8_t		reserved6[0x4];
+	uint32_t	g_tcon;
+	uint32_t	g_int_cstat;
+	uint32_t	g_int_enb;
+	uint32_t	g_wstat;
+	uint8_t		reserved7[0xb0];
+	uint32_t	l0_tcntb;
+	uint32_t	l0_tcnto;
+	uint32_t	l0_icntb;
+	uint32_t	l0_icnto;
+	uint32_t	l0_frcntb;
+	uint32_t	l0_frcnto;
+	uint8_t		reserved8[0x8];
+	uint32_t	l0_tcon;
+	uint8_t		reserved9[0xc];
+	uint32_t	l0_int_cstat;
+	uint32_t	l0_int_enb;
+	uint8_t		reserved10[0x8];
+	uint32_t	l0_wstat;
+	uint8_t		reserved11[0xbc];
+	uint32_t	l1_tcntb;
+	uint32_t	l1_tcnto;
+	uint32_t	l1_icntb;
+	uint32_t	l1_icnto;
+	uint32_t	l1_frcntb;
+	uint32_t	l1_frcnto;
+	uint8_t		reserved12[0x8];
+	uint32_t	l1_tcon;
+	uint8_t		reserved13[0xc];
+	uint32_t	l1_int_cstat;
+	uint32_t	l1_int_enb;
+	uint8_t		reserved14[0x8];
+	uint32_t	l1_wstat;
+};
+check_member(exynos_mct, l1_wstat, 0x440);
+
+static struct exynos_mct * const exynos_mct =
+		(void *)EXYNOS7_MCT_BASE;
+
+
+void mct_start(void);
+uint64_t mct_raw_value(void);
+
+#endif /* _CPU_SAMSUNG_EXYNOS7_MCT_H_ */
diff --git a/src/soc/samsung/exynos7/mct.c b/src/soc/samsung/exynos7/mct.c
new file mode 100644
index 0000000..7a16a10
--- /dev/null
+++ b/src/soc/samsung/exynos7/mct.c
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ *
+ * 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 <stdint.h>
+#include <arch/io.h>
+#include <soc/mct.h>
+
+uint64_t mct_raw_value(void)
+{
+	uint64_t upper = readl(&exynos_mct->g_cnt_u);
+	uint64_t lower = readl(&exynos_mct->g_cnt_l);
+
+	return (upper << 32) | lower;
+}
+
+void mct_start(void)
+{
+	writel(readl(&exynos_mct->g_tcon) | (0x1 << 8),
+	       &exynos_mct->g_tcon);
+}
diff --git a/src/soc/samsung/exynos7/monotonic_timer.c b/src/soc/samsung/exynos7/monotonic_timer.c
new file mode 100644
index 0000000..c8e94fc
--- /dev/null
+++ b/src/soc/samsung/exynos7/monotonic_timer.c
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ *
+ * 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 <stdint.h>
+#include <timer.h>
+
+#include <soc/clock.h>
+#include <soc/mct.h>
+
+static const uint32_t clocks_per_usec = MCT_HZ/1000000;
+
+void timer_monotonic_get(struct mono_time *mt)
+{
+	/* We don't have to call mct_start() here
+	 * because it was already called int he bootblock
+	 */
+
+	mono_time_set_usecs(mt, mct_raw_value() / clocks_per_usec);
+}
diff --git a/src/soc/samsung/exynos7/timer.c b/src/soc/samsung/exynos7/timer.c
new file mode 100644
index 0000000..d8add89
--- /dev/null
+++ b/src/soc/samsung/exynos7/timer.c
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ *
+ * 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 <console/console.h>
+#include <timer.h>
+#include <delay.h>
+#include <thread.h>
+#include <soc/clock.h>
+
+void init_timer(void)
+{
+	/* Nothing to do because we manually
+	 * call mct_start() in the bootblock
+	 */
+}
+
+/* delay x useconds */
+void udelay(unsigned usec)
+{
+	struct mono_time current, end;
+
+	if (!thread_yield_microseconds(usec))
+		return;
+
+	timer_monotonic_get(&current);
+	end = current;
+	mono_time_add_usecs(&end, usec);
+
+	if (mono_time_after(&current, &end)) {
+		printk(BIOS_EMERG, "udelay: 0x%08x is impossibly large\n",
+		       usec);
+		/* There's not much we can do if usec is too big. Use a long,
+		 * paranoid delay value and hope for the best... */
+		end = current;
+		mono_time_add_usecs(&end, USECS_PER_SEC);
+	}
+
+	while (mono_time_before(&current, &end))
+		timer_monotonic_get(&current);
+}



More information about the coreboot-gerrit mailing list