From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Goldschmidt Date: Tue, 22 Oct 2019 20:32:48 +0200 Subject: [U-Boot] [PATCH v5 11/19] cache: Add Arteris Ncore cache coherent unit driver In-Reply-To: <1570787542-40896-12-git-send-email-ley.foon.tan@intel.com> References: <1570787542-40896-1-git-send-email-ley.foon.tan@intel.com> <1570787542-40896-12-git-send-email-ley.foon.tan@intel.com> Message-ID: <545661f3-39ee-6842-5892-40f8a1316738@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 Reviewed-by: Simon Goldschmidt > > --- > 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 > + * > + */ > +#include > +#include > + > +#include > + > +/* 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, > +}; >