aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv/lib
diff options
context:
space:
mode:
authorBin Meng <bin.meng@windriver.com>2020-07-19 23:17:07 -0700
committerAndes <uboot@andestech.com>2020-07-24 14:55:04 +0800
commita0018fc8209c0bf7188592527fc0a7d459b9c144 (patch)
tree2b5931250ac14ef6f7d2004b42c1a86641cd2884 /arch/riscv/lib
parent5d3a21df6694ebd66d5c34c9d62a26edc7456fc7 (diff)
downloadu-boot-a0018fc8209c0bf7188592527fc0a7d459b9c144.zip
u-boot-a0018fc8209c0bf7188592527fc0a7d459b9c144.tar.gz
u-boot-a0018fc8209c0bf7188592527fc0a7d459b9c144.tar.bz2
riscv: Make SiFive HiFive Unleashed board boot again
Commit 40686c394e53 ("riscv: Clean up IPI initialization code") caused U-Boot failed to boot on SiFive HiFive Unleashed board. The codes inside arch_cpu_init_dm() may call U-Boot timer APIs before the call to riscv_init_ipi(). At that time the timer register base (e.g.: the SiFive CLINT device in this case) is unknown yet. It might be the name riscv_init_ipi() that misleads people to only consider it is related to IPI, but in fact the timer capability is provided by the same SiFive CLINT device that provides the IPI. Timer capability is needed for both UP and SMP. Considering that the original refactor does have benefits, that it makes the IPI code more similar to U-Boot initialization idioms. It also removes some quite ugly macros. Let's do the minimal revert instead of a complete revert, plus a fixes to arch_cpu_init_dm() to consider the SPL case. Fixes: 40686c394e53 ("riscv: Clean up IPI initialization code") Signed-off-by: Bin Meng <bin.meng@windriver.com> Reviewed-by: Sean Anderson <seanga2@gmail.com> Tested-by: Leo Liang <ycliang@andestech.com>
Diffstat (limited to 'arch/riscv/lib')
-rw-r--r--arch/riscv/lib/sifive_clint.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
index 78fc6c8..b9a2c64 100644
--- a/arch/riscv/lib/sifive_clint.c
+++ b/arch/riscv/lib/sifive_clint.c
@@ -26,6 +26,9 @@ DECLARE_GLOBAL_DATA_PTR;
int riscv_get_time(u64 *time)
{
+ /* ensure timer register base has a sane value */
+ riscv_init_ipi();
+
*time = readq((void __iomem *)MTIME_REG(gd->arch.clint));
return 0;
@@ -33,6 +36,9 @@ int riscv_get_time(u64 *time)
int riscv_set_timecmp(int hart, u64 cmp)
{
+ /* ensure timer register base has a sane value */
+ riscv_init_ipi();
+
writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart));
return 0;
@@ -40,11 +46,13 @@ int riscv_set_timecmp(int hart, u64 cmp)
int riscv_init_ipi(void)
{
- long *ret = syscon_get_first_range(RISCV_SYSCON_CLINT);
+ if (!gd->arch.clint) {
+ long *ret = syscon_get_first_range(RISCV_SYSCON_CLINT);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- gd->arch.clint = ret;
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+ gd->arch.clint = ret;
+ }
return 0;
}