123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Copyright (C) 2019 Intel Corporation <www.intel.com>
- *
- */
- #include <dm.h>
- #include <hang.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,
- };
|