
On 9/15/20 4:09 AM, Bin Meng wrote:
Hi Sean,
On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson seanga2@gmail.com wrote:
This converts the clint driver from the riscv-specific interface to be a DM-based UCLASS_TIMER driver. In addition, the SiFive DDR driver previously implicitly depended on the CLINT to select REGMAP.
Unlike Andes's PLMT/PLIC (which AFAIK never have anything pass it a dtb), the SiFive CLINT is part of the device tree passed in by qemu. This device tree doesn't have a clocks or clock-frequency property on clint, so we need to fall back on the timebase-frequency property. Perhaps in the future we can get a clock-frequency property added to the qemu dtb.
Unlike with the Andes PLMT, the Sifive CLINT is also an IPI controller. RISCV_SYSCON_CLINT is retained for this purpose.
Signed-off-by: Sean Anderson seanga2@gmail.com Reviewed-by: Pragnesh Patel pragnesh.patel@openfive.com
This patch builds but has only been tested on the K210 and QEMU. It has NOT been tested on a HiFive.
Changes in v4:
- Use timer_timebase_fallback
Changes in v3:
- Don't initialize the IPI in spl_invoke_opensbi. Further testing has revealed it to be unnecessary.
arch/riscv/Kconfig | 4 --- arch/riscv/lib/sifive_clint.c | 66 +++++++++++++++++++---------------- drivers/ram/sifive/Kconfig | 2 ++ 3 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index d9155b9bab..aaa3b833a5 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -155,10 +155,6 @@ config 64BIT config SIFIVE_CLINT bool depends on RISCV_MMODE || SPL_RISCV_MMODE
select REGMAP
select SYSCON
select SPL_REGMAP if SPL
select SPL_SYSCON if SPL help The SiFive CLINT block holds memory-mapped control and status registers associated with software and timer interrupts.
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c index b9a2c649cc..c9704c596f 100644 --- a/arch/riscv/lib/sifive_clint.c +++ b/arch/riscv/lib/sifive_clint.c @@ -8,9 +8,9 @@ */
#include <common.h> +#include <clk.h> #include <dm.h> -#include <regmap.h> -#include <syscon.h> +#include <timer.h> #include <asm/io.h> #include <asm/syscon.h> #include <linux/err.h> @@ -24,35 +24,19 @@
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;
-}
-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;
-}
int riscv_init_ipi(void) {
if (!gd->arch.clint) {
long *ret = syscon_get_first_range(RISCV_SYSCON_CLINT);
int ret;
struct udevice *dev;
if (IS_ERR(ret))
return PTR_ERR(ret);
gd->arch.clint = ret;
}
ret = uclass_get_device_by_driver(UCLASS_TIMER,
DM_GET_DRIVER(sifive_clint), &dev);
if (ret)
return ret;
gd->arch.clint = dev_read_addr_ptr(dev);
if (!gd->arch.clint)
return -EINVAL; return 0;
} @@ -78,14 +62,36 @@ int riscv_get_ipi(int hart, int *pending) return 0; }
+static int sifive_clint_get_count(struct udevice *dev, u64 *count) +{
*count = readq((void __iomem *)MTIME_REG(dev->priv));
return 0;
+}
+static const struct timer_ops sifive_clint_ops = {
.get_count = sifive_clint_get_count,
+};
+static int sifive_clint_probe(struct udevice *dev) +{
dev->priv = dev_read_addr_ptr(dev);
if (!dev->priv)
return -EINVAL;
return timer_timebase_fallback(dev);
+}
static const struct udevice_id sifive_clint_ids[] = {
{ .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT },
{ .compatible = "riscv,clint0" }, { }
};
U_BOOT_DRIVER(sifive_clint) = { .name = "sifive_clint",
.id = UCLASS_SYSCON,
.id = UCLASS_TIMER, .of_match = sifive_clint_ids,
.probe = sifive_clint_probe,
.ops = &sifive_clint_ops, .flags = DM_FLAG_PRE_RELOC,
}; diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig index 6aca22ab2a..31ad0a7e45 100644 --- a/drivers/ram/sifive/Kconfig +++ b/drivers/ram/sifive/Kconfig @@ -9,5 +9,7 @@ config SIFIVE_FU540_DDR bool "SiFive FU540 DDR driver" depends on RAM_SIFIVE default y if TARGET_SIFIVE_FU540
select REGMAP
select SPL_REGMAP if SPL
This should be dropped. Please see the patch below: http://patchwork.ozlabs.org/project/uboot/patch/1600157107-57175-2-git-send-...
Ok, I can drop this and add a dependency.
help This enables DDR support for the platforms based on SiFive FU540 SoC.
--
Regards, Bin