[U-Boot] [PATCH v5 11/19] cache: Add Arteris Ncore cache coherent unit driver
Simon Goldschmidt
simon.k.r.goldschmidt at gmail.com
Tue Oct 22 18:32:48 UTC 2019
Am 11.10.2019 um 11:52 schrieb Ley Foon Tan:
> Add Cache Coherency Unit (CCU) driver.
> CCU is to ensures consistency of shared data between multi masters
> in the system.
>
> Driver initializes CCU's directories and coherency agent
> interfaces in CCU IP.
>
> Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt at gmail.com>
>
> ---
> v5:
> - Move CCU driver to DM.
> ---
> drivers/cache/Kconfig | 8 ++
> drivers/cache/Makefile | 1 +
> drivers/cache/cache-ncore.c | 164 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 173 insertions(+)
> create mode 100644 drivers/cache/cache-ncore.c
>
> diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
> index 629039e7a8..1e452ad6d9 100644
> --- a/drivers/cache/Kconfig
> +++ b/drivers/cache/Kconfig
> @@ -31,4 +31,12 @@ config V5L2_CACHE
> It will configure tag and data ram timing control from the
> device tree and enable L2 cache.
>
> +config NCORE_CACHE
> + bool "Arteris Ncore cache coherent unit driver"
> + select CACHE
> + help
> + This driver is for the Arteris Ncore cache coherent unit (CCU)
> + controller. The driver initializes cache directories and coherent
> + agent interfaces.
> +
> endmenu
> diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile
> index 4a6458c602..7291fc0b29 100644
> --- a/drivers/cache/Makefile
> +++ b/drivers/cache/Makefile
> @@ -2,4 +2,5 @@
> obj-$(CONFIG_CACHE) += cache-uclass.o
> obj-$(CONFIG_SANDBOX) += sandbox_cache.o
> obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o
> +obj-$(CONFIG_NCORE_CACHE) += cache-ncore.o
> obj-$(CONFIG_V5L2_CACHE) += cache-v5l2.o
> diff --git a/drivers/cache/cache-ncore.c b/drivers/cache/cache-ncore.c
> new file mode 100644
> index 0000000000..e3aca36071
> --- /dev/null
> +++ b/drivers/cache/cache-ncore.c
> @@ -0,0 +1,164 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 Intel Corporation <www.intel.com>
> + *
> + */
> +#include <dm.h>
> +#include <wait_bit.h>
> +
> +#include <asm/io.h>
> +
> +/* Directory */
> +#define DIRUSFER 0x80010
> +#define DIRUCASER0 0x80040
> +#define DIRUSFMCR 0x80080
> +#define DIRUSFMAR 0x80084
> +
> +#define DIRUSFMCR_SFID_SHIFT 16
> +
> +/* Coherent cache agent interface */
> +#define CAIUIDR 0x00ffc
> +
> +#define CAIUIDR_CA_GET(v) (((v) & 0x00008000) >> 15)
> +#define CAIUIDR_TYPE_GET(v) (((v) & 0x000f0000) >> 16)
> +#define CAIUIDR_TYPE_ACE_CAI_DVM_SUPPORT 0
> +#define CAIUIDR_TYPE_ACELITE_CAI_DVM_SUPPORT 1
> +
> +/* Coherent subsystem */
> +#define CSADSER0 0xff040
> +#define CSUIDR 0xffff8
> +#define CSIDR 0xffffc
> +
> +#define CSUIDR_NUMCAIUS_GET(v) (((v) & 0x0000007f) >> 0)
> +#define CSUIDR_NUMDIRUS_GET(v) (((v) & 0x003f0000) >> 16)
> +#define CSUIDR_NUMCMIUS_GET(v) (((v) & 0x3f000000) >> 24)
> +
> +#define CSIDR_NUMSFS_GET(v) (((v) & 0x007c0000) >> 18)
> +
> +#define DIR_REG_SZ 0x1000
> +#define CAIU_REG_SZ 0x1000
> +
> +#define CCU_DIR_REG_ADDR(base, reg, dir) \
> + ((base) + (reg) + ((dir) * DIR_REG_SZ))
> +
> +/* OCRAM firewall register */
> +#define OCRAM_FW_01 0x100204
> +#define OCRAM_SECURE_REGIONS 4
> +
> +#define OCRAM_PRIVILEGED_MASK BIT(29)
> +#define OCRAM_SECURE_MASK BIT(30)
> +
> +static void ncore_ccu_init_dirs(void __iomem *base)
> +{
> + ulong i, f;
> + int ret;
> + u32 num_of_dirs;
> + u32 num_of_snoop_filters;
> + u32 reg;
> +
> + num_of_dirs = CSUIDR_NUMDIRUS_GET(readl(base + CSUIDR));
> + num_of_snoop_filters =
> + CSIDR_NUMSFS_GET(readl(base + CSIDR)) + 1;
> +
> + /* Initialize each snoop filter in each directory */
> + for (f = 0; f < num_of_snoop_filters; f++) {
> + reg = f << DIRUSFMCR_SFID_SHIFT;
> + for (i = 0; i < num_of_dirs; i++) {
> + /* Initialize all entries */
> + writel(reg, CCU_DIR_REG_ADDR(base, DIRUSFMCR, i));
> +
> + /* Poll snoop filter maintenance operation active
> + * bit become 0.
> + */
> + ret = wait_for_bit_le32((const void *)
> + CCU_DIR_REG_ADDR(base,
> + DIRUSFMAR, i),
> + BIT(0), false, 1000, false);
> + if (ret) {
> + puts("CCU: Directory initialization failed!\n");
> + hang();
> + }
> +
> + /* Enable snoop filter, a bit per snoop filter */
> + setbits_le32((ulong)CCU_DIR_REG_ADDR(base, DIRUSFER, i),
> + BIT(f));
> + }
> + }
> +}
> +
> +static void ncore_ccu_init_coh_agent(void __iomem *base)
> +{
> + u32 num_of_coh_agent_intf;
> + u32 num_of_dirs;
> + u32 reg;
> + u32 type;
> + u32 i, dir;
> +
> + num_of_coh_agent_intf =
> + CSUIDR_NUMCAIUS_GET(readl(base + CSUIDR));
> + num_of_dirs = CSUIDR_NUMDIRUS_GET(readl(base + CSUIDR));
> +
> + for (i = 0; i < num_of_coh_agent_intf; i++) {
> + reg = readl(base + CAIUIDR + (i * CAIU_REG_SZ));
> + if (CAIUIDR_CA_GET(reg)) {
> + /* Caching agent bit is enabled, enable caching agent
> + * snoop in each directory
> + */
> + for (dir = 0; dir < num_of_dirs; dir++) {
> + setbits_le32((ulong)
> + CCU_DIR_REG_ADDR(base, DIRUCASER0,
> + dir),
> + BIT(i));
> + }
> + }
> +
> + type = CAIUIDR_TYPE_GET(reg);
> + if (type == CAIUIDR_TYPE_ACE_CAI_DVM_SUPPORT ||
> + type == CAIUIDR_TYPE_ACELITE_CAI_DVM_SUPPORT) {
> + /* DVM support is enabled, enable ACE DVM snoop*/
> + setbits_le32((ulong)(base + CSADSER0),
> + BIT(i));
> + }
> + }
> +}
> +
> +static void ocram_bypass_firewall(void __iomem *base)
> +{
> + int i;
> +
> + for (i = 0; i < OCRAM_SECURE_REGIONS; i++) {
> + clrbits_le32(base + OCRAM_FW_01 + (i * sizeof(u32)),
> + OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
> + }
> +}
> +
> +static int ncore_ccu_probe(struct udevice *dev)
> +{
> + void __iomem *base;
> + fdt_addr_t addr;
> +
> + addr = dev_read_addr(dev);
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
> +
> + base = (void __iomem *)addr;
> +
> + ncore_ccu_init_dirs(base);
> + ncore_ccu_init_coh_agent(base);
> + ocram_bypass_firewall(base);
> +
> + return 0;
> +}
> +
> +static const struct udevice_id ncore_ccu_ids[] = {
> + { .compatible = "arteris,ncore-ccu" },
> + {}
> +};
> +
> +U_BOOT_DRIVER(ncore_ccu) = {
> + .name = "ncore_ccu",
> + .id = UCLASS_CACHE,
> + .of_match = ncore_ccu_ids,
> + .probe = ncore_ccu_probe,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
>
More information about the U-Boot
mailing list