From f8c9660bfe17100a27ca4cf28f957a25cb420255 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 15 Sep 2020 16:05:06 +0800 Subject: ram: sifive: Check return value on clk_enable() The return value should be checked otherwise it's useless to assign the return value to 'ret'. Signed-off-by: Bin Meng --- drivers/ram/sifive/fu540_ddr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/ram/sifive/fu540_ddr.c b/drivers/ram/sifive/fu540_ddr.c index 5ff88692a81..f5b2873b33c 100644 --- a/drivers/ram/sifive/fu540_ddr.c +++ b/drivers/ram/sifive/fu540_ddr.c @@ -369,6 +369,11 @@ static int fu540_ddr_probe(struct udevice *dev) } ret = clk_enable(&priv->ddr_clk); + if (ret < 0) { + debug("Could not enable DDR clock\n"); + return ret; + } + priv->ctl = regmap_get_range(map, 0); priv->phy = regmap_get_range(map, 1); priv->physical_filter_ctrl = regmap_get_range(map, 2); -- cgit v1.3.1 From 9981a8009e17fd51b74a4a58ba436998ebbf81ed Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 15 Sep 2020 16:05:07 +0800 Subject: ram: sifive: Remove regmap dependency The usage of regmap API in the SiFive RAM driver is not correct. The reg address should be obtained via dev_read_addr_index() API. Signed-off-by: Bin Meng --- drivers/ram/sifive/fu540_ddr.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ram/sifive/fu540_ddr.c b/drivers/ram/sifive/fu540_ddr.c index f5b2873b33c..60d4945f848 100644 --- a/drivers/ram/sifive/fu540_ddr.c +++ b/drivers/ram/sifive/fu540_ddr.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -339,17 +338,12 @@ static int fu540_ddr_probe(struct udevice *dev) priv->info.size = gd->ram_size; #if defined(CONFIG_SPL_BUILD) - struct regmap *map; int ret; u32 clock = 0; debug("FU540 DDR probe\n"); priv->dev = dev; - ret = regmap_init_mem(dev_ofnode(dev), &map); - if (ret) - return ret; - ret = clk_get_by_index(dev, 0, &priv->ddr_clk); if (ret) { debug("clk get failed %d\n", ret); @@ -374,9 +368,9 @@ static int fu540_ddr_probe(struct udevice *dev) return ret; } - priv->ctl = regmap_get_range(map, 0); - priv->phy = regmap_get_range(map, 1); - priv->physical_filter_ctrl = regmap_get_range(map, 2); + priv->ctl = (struct fu540_ddrctl *)dev_read_addr_index(dev, 0); + priv->phy = (struct fu540_ddrphy *)dev_read_addr_index(dev, 1); + priv->physical_filter_ctrl = (u32 *)dev_read_addr_index(dev, 2); return fu540_ddr_setup(dev); #endif -- cgit v1.3.1 From c33efafaf949ef11fc525cd5be018ea48c40898c Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 28 Sep 2020 10:52:21 -0400 Subject: riscv: Rework riscv timer driver to only support S-mode The riscv-timer driver currently serves as a shim for several riscv timer drivers. This is not too desirable because it bypasses the usual timer selection via the driver model. There is no easy way to specify an alternate timing driver, or have the tick rate depend on the cpu's configured frequency. The timer drivers also do not have device structs, and so have to rely on storing parameters in gd_t. Lastly, there is no initialization call, so driver init is done in the same function which reads the time. This can result in confusing error messages. To a user, it looks like the driver failed when trying to read the time, whereas it may have failed while initializing. This patch removes the shim functionality from the riscv-timer driver, and has it instead implement the former rdtime.c timer driver. This is because existing u-boot users who pass in a device tree (e.g. qemu) do not create a timer device for S-mode u-boot. The existing behavior of creating the riscv-timer device in the riscv cpu driver must be kept. The actual reading of the CSRs has been redone in the style of Linux's get_cycles64. Signed-off-by: Sean Anderson Reviewed-by: Bin Meng Reviewed-by: Rick Chen --- arch/riscv/Kconfig | 8 -------- arch/riscv/cpu/ax25/Kconfig | 2 +- arch/riscv/cpu/fu540/Kconfig | 2 +- arch/riscv/cpu/generic/Kconfig | 2 +- arch/riscv/lib/Makefile | 1 - arch/riscv/lib/rdtime.c | 38 -------------------------------------- drivers/timer/Kconfig | 4 ++-- drivers/timer/riscv_timer.c | 39 ++++++++++++++++++++------------------- 8 files changed, 25 insertions(+), 71 deletions(-) delete mode 100644 arch/riscv/lib/rdtime.c (limited to 'drivers') diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 009a545fcf3..21e6690f4d2 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -185,14 +185,6 @@ config ANDES_PLMT The Andes PLMT block holds memory-mapped mtime register associated with timer tick. -config RISCV_RDTIME - bool - default y if RISCV_SMODE || SPL_RISCV_SMODE - help - The provides the riscv_get_time() API that is implemented using the - standard rdtime instruction. This is the case for S-mode U-Boot, and - is useful for processors that support rdtime in M-mode too. - config SYS_MALLOC_F_LEN default 0x1000 diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig index 8d8d71dcbf9..5cb5bb51eb1 100644 --- a/arch/riscv/cpu/ax25/Kconfig +++ b/arch/riscv/cpu/ax25/Kconfig @@ -3,7 +3,7 @@ config RISCV_NDS select ARCH_EARLY_INIT_R imply CPU imply CPU_RISCV - imply RISCV_TIMER + imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE) imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE) imply SPL_CPU_SUPPORT diff --git a/arch/riscv/cpu/fu540/Kconfig b/arch/riscv/cpu/fu540/Kconfig index 53e19635c83..ac3f183342f 100644 --- a/arch/riscv/cpu/fu540/Kconfig +++ b/arch/riscv/cpu/fu540/Kconfig @@ -10,7 +10,7 @@ config SIFIVE_FU540 select SPL_RAM if SPL imply CPU imply CPU_RISCV - imply RISCV_TIMER + imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE) imply CMD_CPU imply SPL_CPU_SUPPORT diff --git a/arch/riscv/cpu/generic/Kconfig b/arch/riscv/cpu/generic/Kconfig index b2cb155d6da..f4c2e2643c9 100644 --- a/arch/riscv/cpu/generic/Kconfig +++ b/arch/riscv/cpu/generic/Kconfig @@ -7,7 +7,7 @@ config GENERIC_RISCV select ARCH_EARLY_INIT_R imply CPU imply CPU_RISCV - imply RISCV_TIMER + imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE) imply CMD_CPU imply SPL_CPU_SUPPORT diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 6c503ff2b2b..10ac5b06d3c 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o obj-$(CONFIG_ANDES_PLIC) += andes_plic.o obj-$(CONFIG_ANDES_PLMT) += andes_plmt.o else -obj-$(CONFIG_RISCV_RDTIME) += rdtime.o obj-$(CONFIG_SBI) += sbi.o obj-$(CONFIG_SBI_IPI) += sbi_ipi.o endif diff --git a/arch/riscv/lib/rdtime.c b/arch/riscv/lib/rdtime.c deleted file mode 100644 index e128d7fce69..00000000000 --- a/arch/riscv/lib/rdtime.c +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018, Anup Patel - * Copyright (C) 2018, Bin Meng - * - * The riscv_get_time() API implementation that is using the - * standard rdtime instruction. - */ - -#include - -/* Implement the API required by RISC-V timer driver */ -int riscv_get_time(u64 *time) -{ -#ifdef CONFIG_64BIT - u64 n; - - __asm__ __volatile__ ( - "rdtime %0" - : "=r" (n)); - - *time = n; -#else - u32 lo, hi, tmp; - - __asm__ __volatile__ ( - "1:\n" - "rdtimeh %0\n" - "rdtime %1\n" - "rdtimeh %2\n" - "bne %0, %2, 1b" - : "=&r" (hi), "=&r" (lo), "=&r" (tmp)); - - *time = ((u64)hi << 32) | lo; -#endif - - return 0; -} diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 637024445c1..d40d3130113 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -146,8 +146,8 @@ config RISCV_TIMER bool "RISC-V timer support" depends on TIMER && RISCV help - Select this to enable support for the timer as defined - by the RISC-V privileged architecture spec. + Select this to enable support for a generic RISC-V S-Mode timer + driver. config ROCKCHIP_TIMER bool "Rockchip timer support" diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c index 9f9f070e0b3..449fcfcfd59 100644 --- a/drivers/timer/riscv_timer.c +++ b/drivers/timer/riscv_timer.c @@ -1,36 +1,37 @@ // SPDX-License-Identifier: GPL-2.0+ /* + * Copyright (C) 2020, Sean Anderson * Copyright (C) 2018, Bin Meng + * Copyright (C) 2018, Anup Patel + * Copyright (C) 2012 Regents of the University of California * - * RISC-V privileged architecture defined generic timer driver + * RISC-V architecturally-defined generic timer driver * - * This driver relies on RISC-V platform codes to provide the essential API - * riscv_get_time() which is supposed to return the timer counter as defined - * by the RISC-V privileged architecture spec. - * - * This driver can be used in both M-mode and S-mode U-Boot. + * This driver provides generic timer support for S-mode U-Boot. */ #include #include #include #include -#include - -/** - * riscv_get_time() - get the timer counter - * - * Platform codes should provide this API in order to make this driver function. - * - * @time: the 64-bit timer count as defined by the RISC-V privileged - * architecture spec. - * @return: 0 on success, -ve on error. - */ -extern int riscv_get_time(u64 *time); +#include static int riscv_timer_get_count(struct udevice *dev, u64 *count) { - return riscv_get_time(count); + if (IS_ENABLED(CONFIG_64BIT)) { + *count = csr_read(CSR_TIME); + } else { + u32 hi, lo; + + do { + hi = csr_read(CSR_TIMEH); + lo = csr_read(CSR_TIME); + } while (hi != csr_read(CSR_TIMEH)); + + *count = ((u64)hi << 32) | lo; + } + + return 0; } static int riscv_timer_probe(struct udevice *dev) -- cgit v1.3.1 From 3576121687965ffe580fc44f5dd1d8e9ab434c5b Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 28 Sep 2020 10:52:22 -0400 Subject: timer: Add helper for drivers using timebase fallback This function is designed to be used when a timer used to be initialized by the cpu (e.g. RISC-V timers), but now is initialized by dm_timer_init. In such a case, the timer may prefer to use the clocks and clock-frequency properties, but should be able to fall back on using the cpu's timebase-frequency. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass Reviewed-by: Bin Meng Reviewed-by: Rick Chen --- drivers/timer/timer-uclass.c | 31 +++++++++++++++++++++++++++++++ include/timer.h | 15 +++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'drivers') diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c index 14dde950a18..e9802c8b43e 100644 --- a/drivers/timer/timer-uclass.c +++ b/drivers/timer/timer-uclass.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -79,6 +80,36 @@ static int timer_post_probe(struct udevice *dev) return 0; } +/* + * TODO: should be CONFIG_IS_ENABLED(CPU), but the SPL config has _SUPPORT on + * the end... + */ +#if defined(CONFIG_CPU) || defined(CONFIG_SPL_CPU_SUPPORT) +int timer_timebase_fallback(struct udevice *dev) +{ + struct udevice *cpu; + struct cpu_platdata *cpu_plat; + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + /* Did we get our clock rate from the device tree? */ + if (uc_priv->clock_rate) + return 0; + + /* Fall back to timebase-frequency */ + dev_dbg(dev, "missing clocks or clock-frequency property; falling back on timebase-frequency\n"); + cpu = cpu_get_current_dev(); + if (!cpu) + return -ENODEV; + + cpu_plat = dev_get_parent_platdata(cpu); + if (!cpu_plat) + return -ENODEV; + + uc_priv->clock_rate = cpu_plat->timebase_freq; + return 0; +} +#endif + u64 timer_conv_64(u32 count) { /* increment tbh if tbl has rolled over */ diff --git a/include/timer.h b/include/timer.h index a49b500ce35..8b9fa51c53d 100644 --- a/include/timer.h +++ b/include/timer.h @@ -15,6 +15,21 @@ */ int dm_timer_init(void); +/** + * timer_timebase_fallback() - Helper for timers using timebase fallback + * @dev: A timer partially-probed timer device + * + * This is a helper function designed for timers which need to fall back on the + * cpu's timebase. This function is designed to be called during the driver's + * probe(). If there is a clocks or clock-frequency property in the timer's + * binding, then it will be used. Otherwise, the timebase of the current cpu + * will be used. This is initialized by the cpu driver, and usually gotten from + * ``/cpus/timebase-frequency`` or ``/cpus/cpu@X/timebase-frequency``. + * + * Return: 0 if OK, or negative error code on failure + */ +int timer_timebase_fallback(struct udevice *dev); + /* * timer_conv_64 - convert 32-bit counter value to 64-bit * -- cgit v1.3.1 From 7616e3687e447b5a838f472afb5275fe6a841f5b Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 28 Sep 2020 10:52:23 -0400 Subject: timer: Add a test for timer_timebase_fallback To test this function, sandbox CPU must set cpu_platdata.timebase_freq on bind. It also needs to expose a method to set the current cpu. I also make some most members of cpu_sandbox_ops static. On the timer side, the device tree property sandbox,timebase-frequency-fallback controls whether sandbox_timer_probe falls back to time_timebase_fallback or to SANDBOX_TIMER_RATE. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 9 ++++++++- arch/sandbox/include/asm/cpu.h | 11 +++++++++++ drivers/cpu/cpu_sandbox.c | 39 ++++++++++++++++++++++++++++++++------- drivers/timer/sandbox_timer.c | 4 +++- test/dm/timer.c | 27 ++++++++++++++++++++++++++- 5 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 arch/sandbox/include/asm/cpu.h (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 9f45c48e4e0..2f559265a50 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -533,7 +533,9 @@ }; cpus { + timebase-frequency = <2000000>; cpu-test1 { + timebase-frequency = <3000000>; compatible = "sandbox,cpu_sandbox"; u-boot,dm-pre-reloc; }; @@ -839,11 +841,16 @@ 0x58 8>; }; - timer { + timer@0 { compatible = "sandbox,timer"; clock-frequency = <1000000>; }; + timer@1 { + compatible = "sandbox,timer"; + sandbox,timebase-frequency-fallback; + }; + tpm2 { compatible = "sandbox,tpm2"; }; diff --git a/arch/sandbox/include/asm/cpu.h b/arch/sandbox/include/asm/cpu.h new file mode 100644 index 00000000000..c97ac7ba95b --- /dev/null +++ b/arch/sandbox/include/asm/cpu.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Sean Anderson + */ + +#ifndef __SANDBOX_CPU_H +#define __SANDBOX_CPU_H + +void cpu_sandbox_set_current(const char *name); + +#endif /* __SANDBOX_CPU_H */ diff --git a/drivers/cpu/cpu_sandbox.c b/drivers/cpu/cpu_sandbox.c index caa26e50f28..4ba0d1b99ef 100644 --- a/drivers/cpu/cpu_sandbox.c +++ b/drivers/cpu/cpu_sandbox.c @@ -8,14 +8,15 @@ #include #include -int cpu_sandbox_get_desc(const struct udevice *dev, char *buf, int size) +static int cpu_sandbox_get_desc(const struct udevice *dev, char *buf, int size) { snprintf(buf, size, "LEG Inc. SuperMegaUltraTurbo CPU No. 1"); return 0; } -int cpu_sandbox_get_info(const struct udevice *dev, struct cpu_info *info) +static int cpu_sandbox_get_info(const struct udevice *dev, + struct cpu_info *info) { info->cpu_freq = 42 * 42 * 42 * 42 * 42; info->features = 0x42424242; @@ -24,21 +25,29 @@ int cpu_sandbox_get_info(const struct udevice *dev, struct cpu_info *info) return 0; } -int cpu_sandbox_get_count(const struct udevice *dev) +static int cpu_sandbox_get_count(const struct udevice *dev) { return 42; } -int cpu_sandbox_get_vendor(const struct udevice *dev, char *buf, int size) +static int cpu_sandbox_get_vendor(const struct udevice *dev, char *buf, + int size) { snprintf(buf, size, "Languid Example Garbage Inc."); return 0; } -int cpu_sandbox_is_current(struct udevice *dev) +static const char *cpu_current = "cpu-test1"; + +void cpu_sandbox_set_current(const char *name) { - if (!strcmp(dev->name, "cpu-test1")) + cpu_current = name; +} + +static int cpu_sandbox_is_current(struct udevice *dev) +{ + if (!strcmp(dev->name, cpu_current)) return 1; return 0; @@ -52,7 +61,22 @@ static const struct cpu_ops cpu_sandbox_ops = { .is_current = cpu_sandbox_is_current, }; -int cpu_sandbox_probe(struct udevice *dev) +static int cpu_sandbox_bind(struct udevice *dev) +{ + int ret; + struct cpu_platdata *plat = dev_get_parent_platdata(dev); + + /* first examine the property in current cpu node */ + ret = dev_read_u32(dev, "timebase-frequency", &plat->timebase_freq); + /* if not found, then look at the parent /cpus node */ + if (ret) + ret = dev_read_u32(dev->parent, "timebase-frequency", + &plat->timebase_freq); + + return ret; +} + +static int cpu_sandbox_probe(struct udevice *dev) { return 0; } @@ -67,5 +91,6 @@ U_BOOT_DRIVER(cpu_sandbox) = { .id = UCLASS_CPU, .ops = &cpu_sandbox_ops, .of_match = cpu_sandbox_ids, + .bind = cpu_sandbox_bind, .probe = cpu_sandbox_probe, }; diff --git a/drivers/timer/sandbox_timer.c b/drivers/timer/sandbox_timer.c index 5228486082c..6a503c2f153 100644 --- a/drivers/timer/sandbox_timer.c +++ b/drivers/timer/sandbox_timer.c @@ -40,7 +40,9 @@ static int sandbox_timer_probe(struct udevice *dev) { struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); - if (!uc_priv->clock_rate) + if (dev_read_bool(dev, "sandbox,timebase-frequency-fallback")) + return timer_timebase_fallback(dev); + else if (!uc_priv->clock_rate) uc_priv->clock_rate = SANDBOX_TIMER_RATE; return 0; diff --git a/test/dm/timer.c b/test/dm/timer.c index 95dab976654..70043b9eeed 100644 --- a/test/dm/timer.c +++ b/test/dm/timer.c @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include /* * Basic test of the timer uclass. @@ -17,9 +19,32 @@ static int dm_test_timer_base(struct unit_test_state *uts) { struct udevice *dev; - ut_assertok(uclass_get_device(UCLASS_TIMER, 0, &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_TIMER, "timer@0", &dev)); ut_asserteq(1000000, timer_get_rate(dev)); return 0; } DM_TEST(dm_test_timer_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* + * Test of timebase fallback + */ +static int dm_test_timer_timebase_fallback(struct unit_test_state *uts) +{ + struct udevice *dev; + + cpu_sandbox_set_current("cpu-test1"); + ut_assertok(uclass_get_device_by_name(UCLASS_TIMER, "timer@1", &dev)); + ut_asserteq(3000000, timer_get_rate(dev)); + ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); + + cpu_sandbox_set_current("cpu-test2"); + ut_assertok(uclass_get_device_by_name(UCLASS_TIMER, "timer@1", &dev)); + ut_asserteq(2000000, timer_get_rate(dev)); + + cpu_sandbox_set_current("cpu-test1"); + + return 0; +} +DM_TEST(dm_test_timer_timebase_fallback, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -- cgit v1.3.1 From a952c3a4546ba1d6c5a487cae2e73760ecfd0c60 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 28 Sep 2020 10:52:27 -0400 Subject: riscv: clk: Add CLINT clock to kendryte clock driver Another "virtual" clock (in the sense that it isn't configurable). This could possibly be done as a clock in the device tree, but I think this is a bit cleaner. Signed-off-by: Sean Anderson --- drivers/clk/kendryte/clk.c | 4 ++++ include/dt-bindings/clock/k210-sysctl.h | 1 + 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c index 981b3b7699b..bb196961afd 100644 --- a/drivers/clk/kendryte/clk.c +++ b/drivers/clk/kendryte/clk.c @@ -646,6 +646,10 @@ static int k210_clk_probe(struct udevice *dev) REGISTER_GATE(K210_CLK_RTC, "rtc", in0); #undef REGISTER_GATE + /* The MTIME register in CLINT runs at one 50th the CPU clock speed */ + clk_dm(K210_CLK_CLINT, + clk_register_fixed_factor(NULL, "clint", "cpu", 0, 1, 50)); + return 0; } diff --git a/include/dt-bindings/clock/k210-sysctl.h b/include/dt-bindings/clock/k210-sysctl.h index 0e3ed3fb9fa..fe852bbd92a 100644 --- a/include/dt-bindings/clock/k210-sysctl.h +++ b/include/dt-bindings/clock/k210-sysctl.h @@ -55,5 +55,6 @@ #define K210_CLK_OTP 43 #define K210_CLK_RTC 44 #define K210_CLK_ACLK 45 +#define K210_CLK_CLINT 46 #endif /* CLOCK_K210_SYSCTL_H */ -- cgit v1.3.1