]> Git Repo - J-u-boot.git/blob - drivers/cache/cache-ncore.c
Merge branch 'next'
[J-u-boot.git] / drivers / cache / cache-ncore.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019-2022 Intel Corporation <www.intel.com>
4  *
5  */
6 #include <dm.h>
7 #include <hang.h>
8 #include <wait_bit.h>
9
10 #include <asm/io.h>
11 #include <linux/bitops.h>
12
13 /* Directory */
14 #define DIRUSFER                0x80010
15 #define DIRUCASER0              0x80040
16 #define DIRUSFMCR               0x80080
17 #define DIRUSFMAR               0x80084
18
19 #define DIRUSFMCR_SFID_SHIFT    16
20
21 /* Coherent cache agent interface */
22 #define CAIUIDR                 0x00ffc
23
24 #define CAIUIDR_CA_GET(v)       (((v) & 0x00008000) >> 15)
25 #define CAIUIDR_TYPE_GET(v)     (((v) & 0x000f0000) >> 16)
26 #define CAIUIDR_TYPE_ACE_CAI_DVM_SUPPORT        0
27 #define CAIUIDR_TYPE_ACELITE_CAI_DVM_SUPPORT    1
28
29 /* Coherent subsystem */
30 #define CSADSER0                0xff040
31 #define CSUIDR                  0xffff8
32 #define CSIDR                   0xffffc
33
34 #define CSUIDR_NUMCAIUS_GET(v)  (((v) & 0x0000007f) >> 0)
35 #define CSUIDR_NUMDIRUS_GET(v)  (((v) & 0x003f0000) >> 16)
36 #define CSUIDR_NUMCMIUS_GET(v)  (((v) & 0x3f000000) >> 24)
37
38 #define CSIDR_NUMSFS_GET(v)     (((v) & 0x007c0000) >> 18)
39
40 #define DIR_REG_SZ              0x1000
41 #define CAIU_REG_SZ             0x1000
42
43 #define CCU_DIR_REG_ADDR(base, reg, dir)        \
44                 ((base) + (reg) + ((dir) * DIR_REG_SZ))
45
46 /* OCRAM firewall register */
47 #define OCRAM_FW_01                     0x100204
48 #define OCRAM_SECURE_REGIONS            4
49
50 #define OCRAM_PRIVILEGED_MASK           BIT(29)
51 #define OCRAM_SECURE_MASK               BIT(30)
52
53 static void ncore_ccu_init_dirs(void __iomem *base)
54 {
55         ulong i, f;
56         int ret;
57         u32 num_of_dirs;
58         u32 num_of_snoop_filters;
59         u32 reg;
60
61         num_of_dirs = CSUIDR_NUMDIRUS_GET(readl(base + CSUIDR));
62         num_of_snoop_filters =
63                 CSIDR_NUMSFS_GET(readl(base + CSIDR)) + 1;
64
65         /* Initialize each snoop filter in each directory */
66         for (f = 0; f < num_of_snoop_filters; f++) {
67                 reg = f << DIRUSFMCR_SFID_SHIFT;
68                 for (i = 0; i < num_of_dirs; i++) {
69                         /* Initialize all entries */
70                         writel(reg, CCU_DIR_REG_ADDR(base, DIRUSFMCR, i));
71
72                         /* Poll snoop filter maintenance operation active
73                          * bit become 0.
74                          */
75                         ret = wait_for_bit_le32((const void *)
76                                                 CCU_DIR_REG_ADDR(base,
77                                                                  DIRUSFMAR, i),
78                                                 BIT(0), false, 1000, false);
79                         if (ret) {
80                                 puts("CCU: Directory initialization failed!\n");
81                                 hang();
82                         }
83
84                         /* Disable snoop filter, a bit per snoop filter */
85                         clrbits_le32((ulong)CCU_DIR_REG_ADDR(base, DIRUSFER, i),
86                                      BIT(f));
87                 }
88         }
89 }
90
91 static void ncore_ccu_init_coh_agent(void __iomem *base)
92 {
93         u32 num_of_coh_agent_intf;
94         u32 num_of_dirs;
95         u32 reg;
96         u32 type;
97         u32 i, dir;
98
99         num_of_coh_agent_intf =
100                 CSUIDR_NUMCAIUS_GET(readl(base + CSUIDR));
101         num_of_dirs = CSUIDR_NUMDIRUS_GET(readl(base + CSUIDR));
102
103         for (i = 0; i < num_of_coh_agent_intf; i++) {
104                 reg = readl(base + CAIUIDR + (i * CAIU_REG_SZ));
105                 if (CAIUIDR_CA_GET(reg)) {
106                         /* Caching agent bit is enabled, enable caching agent
107                          * snoop in each directory
108                          */
109                         for (dir = 0; dir < num_of_dirs; dir++) {
110                                 setbits_le32((ulong)
111                                              CCU_DIR_REG_ADDR(base, DIRUCASER0,
112                                                               dir),
113                                              BIT(i));
114                         }
115                 }
116
117                 type = CAIUIDR_TYPE_GET(reg);
118                 if (type == CAIUIDR_TYPE_ACE_CAI_DVM_SUPPORT ||
119                     type == CAIUIDR_TYPE_ACELITE_CAI_DVM_SUPPORT) {
120                         /* DVM support is enabled, enable ACE DVM snoop*/
121                         setbits_le32((ulong)(base + CSADSER0),
122                                      BIT(i));
123                 }
124         }
125 }
126
127 static void ocram_bypass_firewall(void __iomem *base)
128 {
129         int i;
130
131         for (i = 0; i < OCRAM_SECURE_REGIONS; i++) {
132                 clrbits_le32(base + OCRAM_FW_01 + (i * sizeof(u32)),
133                              OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
134         }
135 }
136
137 static int ncore_ccu_probe(struct udevice *dev)
138 {
139         void __iomem *base;
140         fdt_addr_t addr;
141
142         addr = dev_read_addr(dev);
143         if (addr == FDT_ADDR_T_NONE)
144                 return -EINVAL;
145
146         base = (void __iomem *)addr;
147
148         ncore_ccu_init_dirs(base);
149         ncore_ccu_init_coh_agent(base);
150         ocram_bypass_firewall(base);
151
152         return 0;
153 }
154
155 static const struct udevice_id ncore_ccu_ids[] = {
156         { .compatible = "arteris,ncore-ccu" },
157         {}
158 };
159
160 U_BOOT_DRIVER(ncore_ccu) = {
161         .name   = "ncore_ccu",
162         .id     = UCLASS_CACHE,
163         .of_match = ncore_ccu_ids,
164         .probe  = ncore_ccu_probe,
165         .flags  = DM_FLAG_PRE_RELOC,
166 };
This page took 0.0336 seconds and 4 git commands to generate.