Emil Renner Berthing wrote: > Joshua Yeong wrote: > > Add StarFive Starlink cache management driver for > > JH8100 SoC. This driver enables RISC-V non-standard cache operation on > > JH8100 that does not support Zicbom extension instructions. > > > > Signed-off-by: Joshua Yeong <joshua.yeong@xxxxxxxxxxxxxxxx> > > --- > > drivers/cache/Kconfig | 9 ++ > > drivers/cache/Makefile | 5 +- > > drivers/cache/starfive_starlink_cache.c | 135 > > ++++++++++++++++++++++++ > > 3 files changed, 147 insertions(+), 2 deletions(-) create mode > > 100644 drivers/cache/starfive_starlink_cache.c > > > > diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index > > 9345ce4976d7..9181cd391f53 100644 > > --- a/drivers/cache/Kconfig > > +++ b/drivers/cache/Kconfig > > @@ -14,4 +14,13 @@ config SIFIVE_CCACHE > > help > > Support for the composable cache controller on SiFive platforms. > > > > +config STARFIVE_STARLINK_CACHE > > + bool "StarFive StarLink Cache controller" > > + depends on RISCV > > + depends on ARCH_STARFIVE > > + select RISCV_DMA_NONCOHERENT > > + select RISCV_NONSTANDARD_CACHE_OPS > > + help > > + Support for the StarLink cache controller on StarFive platforms. > > This is a bit misleading. The JH71x0s don't have this. It's only on the JH8100 so > far, and hopefully later SoCs will just implement RISC-V standards for this. > So maybe something like > > "Support for the StarLink cache controller on the StarFive JH8100 SoC." > Hi Emil, The StarLink-500 cache controller is not designed exclusively for JH8100 SoC. While it is true that it currently exists on the StarFive platform, CPU/SoC that does not come with Zicbom extensions supported would need to rely on this cache drive to do cache management operations. I think we don’t need to mentioned 'JH8100 SoC' here. > > + > > endmenu > > diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile index > > 7657cff3bd6c..55c5e851034d 100644 > > --- a/drivers/cache/Makefile > > +++ b/drivers/cache/Makefile > > @@ -1,4 +1,5 @@ > > # SPDX-License-Identifier: GPL-2.0 > > > > -obj-$(CONFIG_AX45MP_L2_CACHE) += ax45mp_cache.o > > -obj-$(CONFIG_SIFIVE_CCACHE) += sifive_ccache.o > > +obj-$(CONFIG_AX45MP_L2_CACHE) += ax45mp_cache.o > > +obj-$(CONFIG_SIFIVE_CCACHE) += sifive_ccache.o > > +obj-$(CONFIG_STARFIVE_STARLINK_CACHE) += starfive_starlink_cache.o > > diff --git a/drivers/cache/starfive_starlink_cache.c > > b/drivers/cache/starfive_starlink_cache.c > > new file mode 100644 > > index 000000000000..2f1fa6a923ee > > --- /dev/null > > +++ b/drivers/cache/starfive_starlink_cache.c > > @@ -0,0 +1,135 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Cache Management Operations for StarFive's Starlink cache > > +controller > > + * > > + * Copyright (C) 2024 Shanghai StarFive Technology Co., Ltd. > > + * > > + * Author: Joshua Yeong <joshua.yeong@xxxxxxxxxxxxxxxx> */ > > + > > +#include <linux/bitfield.h> > > +#include <linux/cacheflush.h> > > +#include <linux/iopoll.h> > > +#include <linux/of_address.h> > > + > > +#include <asm/dma-noncoherent.h> > > + > > +#define STARLINK_CACHE_FLUSH_START_ADDR 0x0 > > +#define STARLINK_CACHE_FLUSH_END_ADDR 0x8 > > +#define STARLINK_CACHE_FLUSH_CTL 0x10 > > +#define STARLINK_CACHE_ALIGN 0x40 > > + > > +#define STARLINK_CACHE_ADDRESS_RANGE_MASK > GENMASK(39, 0) > > +#define STARLINK_CACHE_FLUSH_CTL_MODE_MASK > GENMASK(2, 1) > > +#define STARLINK_CACHE_FLUSH_CTL_ENABLE_MASK BIT(0) > > + > > +#define STARLINK_CACHE_FLUSH_CTL_CLEAN_INVALIDATE 0 > > +#define STARLINK_CACHE_FLUSH_CTL_MAKE_INVALIDATE 1 > > +#define STARLINK_CACHE_FLUSH_CTL_CLEAN_SHARED 2 > > +#define STARLINK_CACHE_FLUSH_POLL_DELAY_US 1 > > +#define STARLINK_CACHE_FLUSH_TIMEOUT_US > 5000000 > > + > > +struct starlink_cache_priv { > > + void __iomem *base_addr; > > +}; > > + > > +static struct starlink_cache_priv starlink_cache_priv; > > This could just be > > static void __iomem *starlink_cache_base; > > > + > > +static void starlink_cache_flush_complete(void) > > +{ > > + volatile void __iomem *ctl = starlink_cache_priv.base_addr + > > + STARLINK_CACHE_FLUSH_CTL; > > + u64 v; > > + int ret; > > + > > + ret = readq_poll_timeout_atomic(ctl, v, !(v & > STARLINK_CACHE_FLUSH_CTL_ENABLE_MASK), > > + > STARLINK_CACHE_FLUSH_POLL_DELAY_US, > > + > STARLINK_CACHE_FLUSH_TIMEOUT_US); > > + if (ret) > > + WARN(1, "StarFive Starlink cache flush operation > timeout\n"); } > > + > > +static void starlink_cache_dma_cache_wback(phys_addr_t paddr, > > +unsigned long size) { > > + writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, > paddr), > > + starlink_cache_priv.base_addr + > STARLINK_CACHE_FLUSH_START_ADDR); > > + writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, > paddr + size), > > + starlink_cache_priv.base_addr + > > +STARLINK_CACHE_FLUSH_END_ADDR); > > + > > + mb(); > > + writeq(FIELD_PREP(STARLINK_CACHE_FLUSH_CTL_MODE_MASK, > > + STARLINK_CACHE_FLUSH_CTL_CLEAN_SHARED), > > + starlink_cache_priv.base_addr + STARLINK_CACHE_FLUSH_CTL); > > + > > + starlink_cache_flush_complete(); > > +} > > + > > +static void starlink_cache_dma_cache_invalidate(phys_addr_t paddr, > > +unsigned long size) { > > + writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, > paddr), > > + starlink_cache_priv.base_addr + > STARLINK_CACHE_FLUSH_START_ADDR); > > + writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, > paddr + size), > > + starlink_cache_priv.base_addr + > > +STARLINK_CACHE_FLUSH_END_ADDR); > > + > > + mb(); > > + writeq(FIELD_PREP(STARLINK_CACHE_FLUSH_CTL_MODE_MASK, > > + STARLINK_CACHE_FLUSH_CTL_MAKE_INVALIDATE), > > + starlink_cache_priv.base_addr + STARLINK_CACHE_FLUSH_CTL); > > + > > + starlink_cache_flush_complete(); > > +} > > + > > +static void starlink_cache_dma_cache_wback_inv(phys_addr_t paddr, > > +unsigned long size) { > > + writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, > paddr), > > + starlink_cache_priv.base_addr + > STARLINK_CACHE_FLUSH_START_ADDR); > > + writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, > paddr + size), > > + starlink_cache_priv.base_addr + > > +STARLINK_CACHE_FLUSH_END_ADDR); > > + > > + mb(); > > + writeq(FIELD_PREP(STARLINK_CACHE_FLUSH_CTL_MODE_MASK, > > + STARLINK_CACHE_FLUSH_CTL_CLEAN_INVALIDATE), > > + starlink_cache_priv.base_addr + STARLINK_CACHE_FLUSH_CTL); > > + > > + starlink_cache_flush_complete(); > > +} > > + > > +static const struct riscv_nonstd_cache_ops starlink_cache_ops = { > > + .wback = &starlink_cache_dma_cache_wback, > > + .inv = &starlink_cache_dma_cache_invalidate, > > + .wback_inv = &starlink_cache_dma_cache_wback_inv, > > +}; > > + > > +static const struct of_device_id starlink_cache_ids[] = { > > + { .compatible = "starfive,jh8100-starlink-cache" }, > > + { /* sentinel */ } > > +}; > > + > > +static int __init starlink_cache_init(void) { > > + struct device_node *np; > > + u32 block_size = 0; > > You return early if of_property_read_u32() fails, so this doesn't need to be > initialized. > > > + int ret; > > + > > + np = of_find_matching_node(NULL, starlink_cache_ids); > > + if (!of_device_is_available(np)) > > + return -ENODEV; > > + > > + ret = of_property_read_u32(np, "cache-block-size", &block_size); > > + if (ret) > > + return ret; > > + > > + if (block_size % STARLINK_CACHE_ALIGN) > > + return -EINVAL; > > + > > + starlink_cache_priv.base_addr = of_iomap(np, 0); > > + if (!starlink_cache_priv.base_addr) > > + return -ENOMEM; > > + > > + riscv_cbom_block_size = block_size; > > + riscv_noncoherent_supported(); > > + riscv_noncoherent_register_cache_ops(&starlink_cache_ops); > > + > > + return 0; > > +} > > +early_initcall(starlink_cache_init); > > The sifive driver gets away with arch_initcall() here. Any particular reason you > need this earlier? I will change it to arch_initcall(). Appreciate for the comments. Thank you. Regards, Joshua > > > -- > > 2.25.1 > > > > > > _______________________________________________ > > linux-riscv mailing list > > linux-riscv@xxxxxxxxxxxxxxxxxxx > > http://lists.infradead.org/mailman/listinfo/linux-riscv