1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
7 #include <linux/bitfield.h>
8 #include <linux/bitmap.h>
9 #include <linux/bitops.h>
10 #include <linux/cleanup.h>
11 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/nvmem-consumer.h>
18 #include <linux/regmap.h>
19 #include <linux/sizes.h>
20 #include <linux/slab.h>
21 #include <linux/soc/qcom/llcc-qcom.h>
23 #define ACTIVATE BIT(0)
24 #define DEACTIVATE BIT(1)
25 #define ACT_CLEAR BIT(0)
26 #define ACT_COMPLETE BIT(4)
27 #define ACT_CTRL_OPCODE_ACTIVATE BIT(0)
28 #define ACT_CTRL_OPCODE_DEACTIVATE BIT(1)
29 #define ACT_CTRL_ACT_TRIG BIT(0)
30 #define ACT_CTRL_OPCODE_SHIFT 1
31 #define ATTR1_PROBE_TARGET_WAYS_SHIFT 2
32 #define ATTR1_FIXED_SIZE_SHIFT 3
33 #define ATTR1_PRIORITY_SHIFT 4
34 #define ATTR1_MAX_CAP_SHIFT 16
35 #define ATTR0_RES_WAYS_MASK GENMASK(15, 0)
36 #define ATTR0_BONUS_WAYS_MASK GENMASK(31, 16)
37 #define ATTR0_BONUS_WAYS_SHIFT 16
38 #define LLCC_STATUS_READ_DELAY 100
40 #define CACHE_LINE_SIZE_SHIFT 6
42 #define LLCC_LB_CNT_MASK GENMASK(31, 28)
43 #define LLCC_LB_CNT_SHIFT 28
45 #define MAX_CAP_TO_BYTES(n) (n * SZ_1K)
46 #define LLCC_TRP_ACT_CTRLn(n) (n * SZ_4K)
47 #define LLCC_TRP_ACT_CLEARn(n) (8 + n * SZ_4K)
48 #define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K)
49 #define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n)
50 #define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n)
51 #define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_4 * n)
53 #define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00
54 #define LLCC_TRP_PCB_ACT 0x21f04
55 #define LLCC_TRP_ALGO_CFG1 0x21f0c
56 #define LLCC_TRP_ALGO_CFG2 0x21f10
57 #define LLCC_TRP_ALGO_CFG3 0x21f14
58 #define LLCC_TRP_ALGO_CFG4 0x21f18
59 #define LLCC_TRP_ALGO_CFG5 0x21f1c
60 #define LLCC_TRP_WRSC_EN 0x21f20
61 #define LLCC_TRP_ALGO_CFG6 0x21f24
62 #define LLCC_TRP_ALGO_CFG7 0x21f28
63 #define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c
64 #define LLCC_TRP_ALGO_CFG8 0x21f30
66 #define LLCC_VERSION_2_0_0_0 0x02000000
67 #define LLCC_VERSION_2_1_0_0 0x02010000
68 #define LLCC_VERSION_4_1_0_0 0x04010000
71 * struct llcc_slice_config - Data associated with the llcc slice
72 * @usecase_id: Unique id for the client's use case
73 * @slice_id: llcc slice id for each client
74 * @max_cap: The maximum capacity of the cache slice provided in KB
75 * @priority: Priority of the client used to select victim line for replacement
76 * @fixed_size: Boolean indicating if the slice has a fixed capacity
77 * @bonus_ways: Bonus ways are additional ways to be used for any slice,
78 * if client ends up using more than reserved cache ways. Bonus
79 * ways are allocated only if they are not reserved for some
81 * @res_ways: Reserved ways for the cache slice, the reserved ways cannot
82 * be used by any other client than the one its assigned to.
83 * @cache_mode: Each slice operates as a cache, this controls the mode of the
84 * slice: normal or TCM(Tightly Coupled Memory)
85 * @probe_target_ways: Determines what ways to probe for access hit. When
86 * configured to 1 only bonus and reserved ways are probed.
87 * When configured to 0 all ways in llcc are probed.
88 * @dis_cap_alloc: Disable capacity based allocation for a client
89 * @retain_on_pc: If this bit is set and client has maintained active vote
90 * then the ways assigned to this client are not flushed on power
92 * @activate_on_init: Activate the slice immediately after it is programmed
93 * @write_scid_en: Bit enables write cache support for a given scid.
94 * @write_scid_cacheable_en: Enables write cache cacheable support for a
95 * given scid (not supported on v2 or older hardware).
96 * @stale_en: Bit enables stale.
97 * @stale_cap_en: Bit enables stale only if current scid is over-cap.
98 * @mru_uncap_en: Roll-over on reserved cache ways if current scid is
100 * @mru_rollover: Roll-over on reserved cache ways.
101 * @alloc_oneway_en: Allways allocate one way on over-cap even if there's no
102 * same-scid lines for replacement.
103 * @ovcap_en: Once current scid is over-capacity, allocate other over-cap SCID.
104 * @ovcap_prio: Once current scid is over-capacity, allocate other low priority
105 * over-cap scid. Depends on corresponding bit being set in
107 * @vict_prio: When current scid is under-capacity, allocate over other
108 * lower-than victim priority-line threshold scid.
110 struct llcc_slice_config {
119 u32 probe_target_ways;
122 bool activate_on_init;
124 bool write_scid_cacheable_en;
129 bool alloc_oneway_en;
135 struct qcom_llcc_config {
136 const struct llcc_slice_config *sct_data;
137 const u32 *reg_offset;
138 const struct llcc_edac_reg_offset *edac_reg_offset;
139 u32 max_cap_shift; /* instead of ATTR1_MAX_CAP_SHIFT */
147 struct qcom_sct_config {
148 const struct qcom_llcc_config *llcc_config;
152 enum llcc_reg_offset {
157 static const struct llcc_slice_config sa8775p_data[] = {
159 .usecase_id = LLCC_CPUSS,
165 .retain_on_pc = true,
166 .activate_on_init = true,
168 .usecase_id = LLCC_VIDSC0,
175 .retain_on_pc = true,
177 .usecase_id = LLCC_CPUSS1,
184 .retain_on_pc = true,
186 .usecase_id = LLCC_CPUHWT,
193 .retain_on_pc = true,
195 .usecase_id = LLCC_AUDIO,
203 .usecase_id = LLCC_CMPT,
210 .retain_on_pc = true,
212 .usecase_id = LLCC_GPUHTW,
219 .retain_on_pc = true,
221 .usecase_id = LLCC_GPU,
228 .retain_on_pc = true,
229 .write_scid_en = true,
231 .usecase_id = LLCC_MMUHWT,
238 .activate_on_init = true,
240 .usecase_id = LLCC_CMPTDMA,
247 .retain_on_pc = true,
249 .usecase_id = LLCC_DISP,
256 .retain_on_pc = true,
258 .usecase_id = LLCC_VIDFW,
264 .retain_on_pc = true,
266 .usecase_id = LLCC_AUDHW,
274 .usecase_id = LLCC_CVP,
281 .retain_on_pc = true,
283 .usecase_id = LLCC_APTCM,
290 .retain_on_pc = true,
292 .usecase_id = LLCC_WRCACHE,
299 .activate_on_init = true,
303 static const struct llcc_slice_config sar1130p_data[] = {
305 .usecase_id = LLCC_CPUSS,
309 .bonus_ways = 0x1fff,
312 .retain_on_pc = true,
313 .activate_on_init = true,
315 .usecase_id = LLCC_VIDSC0,
320 .bonus_ways = 0x1fff,
323 .retain_on_pc = true,
325 .usecase_id = LLCC_AUDIO,
330 .bonus_ways = 0x1fff,
333 .retain_on_pc = true,
335 .usecase_id = LLCC_CMPT,
340 .bonus_ways = 0x1fff,
343 .retain_on_pc = true,
345 .usecase_id = LLCC_GPUHTW,
350 .bonus_ways = 0x1fff,
353 .retain_on_pc = true,
355 .usecase_id = LLCC_GPU,
360 .bonus_ways = 0x1fff,
363 .retain_on_pc = true,
364 .write_scid_en = true,
366 .usecase_id = LLCC_MMUHWT,
371 .bonus_ways = 0x1fff,
375 .usecase_id = LLCC_DISP,
380 .bonus_ways = 0x1fff,
383 .retain_on_pc = true,
385 .usecase_id = LLCC_CVP,
390 .bonus_ways = 0x1fff,
393 .retain_on_pc = true,
395 .usecase_id = LLCC_APTCM,
403 .dis_cap_alloc = true,
404 .retain_on_pc = true,
406 .usecase_id = LLCC_WRCACHE,
411 .bonus_ways = 0x1fff,
414 .activate_on_init = true,
416 .usecase_id = LLCC_AENPU,
421 .bonus_ways = 0x1fff,
424 .retain_on_pc = true,
426 .usecase_id = LLCC_DISP_LEFT,
434 .retain_on_pc = true,
436 .usecase_id = LLCC_DISP_RIGHT,
444 .retain_on_pc = true,
446 .usecase_id = LLCC_EVCS_LEFT,
454 .retain_on_pc = true,
456 .usecase_id = LLCC_EVCS_RIGHT,
464 .retain_on_pc = true,
468 static const struct llcc_slice_config sar2130p_data[] = {
470 .usecase_id = LLCC_CPUSS,
475 .bonus_ways = 0x3fffffff,
478 .retain_on_pc = true,
479 .activate_on_init = true,
481 .usecase_id = LLCC_VIDSC0,
486 .bonus_ways = 0x3fffffff,
489 .retain_on_pc = true,
491 .usecase_id = LLCC_AUDIO,
496 .bonus_ways = 0x3fffffff,
499 .retain_on_pc = true,
501 .usecase_id = LLCC_CMPT,
506 .bonus_ways = 0x3fffffff,
509 .retain_on_pc = true,
511 .usecase_id = LLCC_GPUHTW,
516 .bonus_ways = 0x3fffffff,
519 .retain_on_pc = true,
521 .usecase_id = LLCC_GPU,
526 .bonus_ways = 0x3fffffff,
529 .retain_on_pc = true,
530 .write_scid_en = true,
532 .usecase_id = LLCC_MMUHWT,
537 .bonus_ways = 0x3fffffff,
540 .activate_on_init = true,
542 .usecase_id = LLCC_DISP,
547 .bonus_ways = 0x3fffffff,
550 .retain_on_pc = true,
552 .usecase_id = LLCC_APTCM,
560 .dis_cap_alloc = true,
561 .retain_on_pc = true,
563 .usecase_id = LLCC_WRCACHE,
568 .bonus_ways = 0x3fffffff,
571 .activate_on_init = true,
573 .usecase_id = LLCC_VIEYE,
578 .bonus_ways = 0x3fffffff,
581 .retain_on_pc = true,
583 .usecase_id = LLCC_VIDPTH,
588 .bonus_ways = 0x3fffffff,
591 .retain_on_pc = true,
593 .usecase_id = LLCC_GPUMV,
598 .bonus_ways = 0x3fffffff,
601 .retain_on_pc = true,
603 .usecase_id = LLCC_EVA_LEFT,
608 .bonus_ways = 0x3ffffffc,
611 .retain_on_pc = true,
613 .usecase_id = LLCC_EVA_RIGHT,
618 .bonus_ways = 0x3ffffffc,
621 .retain_on_pc = true,
623 .usecase_id = LLCC_EVAGAIN,
628 .bonus_ways = 0x3fffffff,
631 .retain_on_pc = true,
633 .usecase_id = LLCC_AENPU,
638 .bonus_ways = 0x3fffffff,
641 .retain_on_pc = true,
643 .usecase_id = LLCC_VIPTH,
648 .bonus_ways = 0x3fffffff,
651 .retain_on_pc = true,
653 .usecase_id = LLCC_DISP_LEFT,
661 .retain_on_pc = true,
663 .usecase_id = LLCC_DISP_RIGHT,
671 .retain_on_pc = true,
673 .usecase_id = LLCC_EVCS_LEFT,
681 .retain_on_pc = true,
683 .usecase_id = LLCC_EVCS_RIGHT,
691 .retain_on_pc = true,
693 .usecase_id = LLCC_SPAD,
701 .retain_on_pc = true,
705 static const struct llcc_slice_config sc7180_data[] = {
707 .usecase_id = LLCC_CPUSS,
713 .retain_on_pc = true,
714 .activate_on_init = true,
716 .usecase_id = LLCC_MDM,
722 .retain_on_pc = true,
724 .usecase_id = LLCC_GPUHTW,
730 .retain_on_pc = true,
732 .usecase_id = LLCC_GPU,
738 .retain_on_pc = true,
742 static const struct llcc_slice_config sc7280_data[] = {
744 .usecase_id = LLCC_CPUSS,
750 .retain_on_pc = true,
751 .activate_on_init = true,
753 .usecase_id = LLCC_MDMHPGRW,
760 .retain_on_pc = true,
762 .usecase_id = LLCC_CMPT,
769 .retain_on_pc = true,
771 .usecase_id = LLCC_GPUHTW,
778 .retain_on_pc = true,
780 .usecase_id = LLCC_GPU,
786 .retain_on_pc = true,
788 .usecase_id = LLCC_MMUHWT,
795 .activate_on_init = true,
797 .usecase_id = LLCC_MDMPNG,
804 .retain_on_pc = true,
806 .usecase_id = LLCC_WLHW,
813 .retain_on_pc = true,
815 .usecase_id = LLCC_MODPE,
822 .retain_on_pc = true,
826 static const struct llcc_slice_config sc8180x_data[] = {
828 .usecase_id = LLCC_CPUSS,
835 .retain_on_pc = true,
836 .activate_on_init = true,
838 .usecase_id = LLCC_VIDSC0,
845 .retain_on_pc = true,
847 .usecase_id = LLCC_VIDSC1,
854 .retain_on_pc = true,
856 .usecase_id = LLCC_AUDIO,
863 .retain_on_pc = true,
865 .usecase_id = LLCC_MDMHPGRW,
873 .retain_on_pc = true,
875 .usecase_id = LLCC_MDM,
882 .retain_on_pc = true,
884 .usecase_id = LLCC_MODHW,
891 .retain_on_pc = true,
893 .usecase_id = LLCC_CMPT,
900 .retain_on_pc = true,
902 .usecase_id = LLCC_GPUHTW,
909 .retain_on_pc = true,
911 .usecase_id = LLCC_GPU,
918 .retain_on_pc = true,
920 .usecase_id = LLCC_MMUHWT,
927 .activate_on_init = true,
929 .usecase_id = LLCC_CMPTDMA,
936 .retain_on_pc = true,
938 .usecase_id = LLCC_DISP,
945 .retain_on_pc = true,
947 .usecase_id = LLCC_VIDFW,
954 .retain_on_pc = true,
956 .usecase_id = LLCC_MDMHPFX,
963 .retain_on_pc = true,
965 .usecase_id = LLCC_MDMPNG,
972 .retain_on_pc = true,
974 .usecase_id = LLCC_AUDHW,
981 .retain_on_pc = true,
983 .usecase_id = LLCC_NPU,
990 .retain_on_pc = true,
992 .usecase_id = LLCC_WLHW,
999 .retain_on_pc = true,
1001 .usecase_id = LLCC_MODPE,
1008 .retain_on_pc = true,
1010 .usecase_id = LLCC_APTCM,
1017 .retain_on_pc = true,
1019 .usecase_id = LLCC_WRCACHE,
1024 .bonus_ways = 0xfff,
1029 static const struct llcc_slice_config sc8280xp_data[] = {
1031 .usecase_id = LLCC_CPUSS,
1036 .bonus_ways = 0xfff,
1038 .retain_on_pc = true,
1039 .activate_on_init = true,
1041 .usecase_id = LLCC_VIDSC0,
1046 .bonus_ways = 0xfff,
1048 .retain_on_pc = true,
1050 .usecase_id = LLCC_AUDIO,
1055 .bonus_ways = 0xfff,
1058 .usecase_id = LLCC_CMPT,
1063 .bonus_ways = 0xfff,
1066 .usecase_id = LLCC_GPUHTW,
1071 .bonus_ways = 0xfff,
1073 .retain_on_pc = true,
1075 .usecase_id = LLCC_GPU,
1080 .bonus_ways = 0xfff,
1082 .retain_on_pc = true,
1083 .write_scid_en = true,
1085 .usecase_id = LLCC_MMUHWT,
1090 .bonus_ways = 0xfff,
1092 .activate_on_init = true,
1094 .usecase_id = LLCC_DISP,
1099 .bonus_ways = 0xfff,
1101 .retain_on_pc = true,
1103 .usecase_id = LLCC_AUDHW,
1108 .bonus_ways = 0xfff,
1110 .retain_on_pc = true,
1112 .usecase_id = LLCC_ECC,
1117 .bonus_ways = 0xfff,
1119 .retain_on_pc = true,
1121 .usecase_id = LLCC_CVP,
1126 .bonus_ways = 0xfff,
1128 .retain_on_pc = true,
1130 .usecase_id = LLCC_APTCM,
1137 .retain_on_pc = true,
1139 .usecase_id = LLCC_WRCACHE,
1144 .bonus_ways = 0xfff,
1146 .activate_on_init = true,
1148 .usecase_id = LLCC_CVPFW,
1152 .bonus_ways = 0xfff,
1154 .retain_on_pc = true,
1156 .usecase_id = LLCC_CPUSS1,
1161 .bonus_ways = 0xfff,
1163 .retain_on_pc = true,
1165 .usecase_id = LLCC_CPUHWT,
1170 .bonus_ways = 0xfff,
1172 .activate_on_init = true,
1176 static const struct llcc_slice_config sdm845_data[] = {{
1177 .usecase_id = LLCC_CPUSS,
1181 .bonus_ways = 0xffc,
1184 .dis_cap_alloc = true,
1185 .retain_on_pc = true,
1186 .activate_on_init = true,
1188 .usecase_id = LLCC_VIDSC0,
1195 .dis_cap_alloc = true,
1196 .retain_on_pc = true,
1198 .usecase_id = LLCC_VIDSC1,
1205 .dis_cap_alloc = true,
1206 .retain_on_pc = true,
1208 .usecase_id = LLCC_ROTATOR,
1215 .dis_cap_alloc = true,
1216 .retain_on_pc = true,
1218 .usecase_id = LLCC_VOICE,
1222 .bonus_ways = 0xffc,
1225 .dis_cap_alloc = true,
1226 .retain_on_pc = true,
1228 .usecase_id = LLCC_AUDIO,
1232 .bonus_ways = 0xffc,
1235 .dis_cap_alloc = true,
1236 .retain_on_pc = true,
1238 .usecase_id = LLCC_MDMHPGRW,
1245 .dis_cap_alloc = true,
1246 .retain_on_pc = true,
1248 .usecase_id = LLCC_MDM,
1252 .bonus_ways = 0xffc,
1255 .dis_cap_alloc = true,
1256 .retain_on_pc = true,
1258 .usecase_id = LLCC_CMPT,
1262 .bonus_ways = 0xffc,
1265 .dis_cap_alloc = true,
1266 .retain_on_pc = true,
1268 .usecase_id = LLCC_GPUHTW,
1275 .dis_cap_alloc = true,
1276 .retain_on_pc = true,
1278 .usecase_id = LLCC_GPU,
1282 .bonus_ways = 0xff0,
1285 .dis_cap_alloc = true,
1286 .retain_on_pc = true,
1288 .usecase_id = LLCC_MMUHWT,
1294 .dis_cap_alloc = true,
1295 .activate_on_init = true,
1297 .usecase_id = LLCC_CMPTDMA,
1301 .bonus_ways = 0xffc,
1304 .dis_cap_alloc = true,
1305 .retain_on_pc = true,
1307 .usecase_id = LLCC_DISP,
1311 .bonus_ways = 0xffc,
1314 .dis_cap_alloc = true,
1315 .retain_on_pc = true,
1317 .usecase_id = LLCC_VIDFW,
1321 .bonus_ways = 0xffc,
1324 .dis_cap_alloc = true,
1325 .retain_on_pc = true,
1327 .usecase_id = LLCC_MDMHPFX,
1334 .dis_cap_alloc = true,
1335 .retain_on_pc = true,
1337 .usecase_id = LLCC_MDMPNG,
1344 .dis_cap_alloc = true,
1345 .retain_on_pc = true,
1347 .usecase_id = LLCC_AUDHW,
1352 .bonus_ways = 0xffc,
1355 .dis_cap_alloc = true,
1356 .retain_on_pc = true,
1360 static const struct llcc_slice_config sm6350_data[] = {
1362 .usecase_id = LLCC_CPUSS,
1366 .bonus_ways = 0xfff,
1368 .activate_on_init = true,
1369 .write_scid_en = true,
1371 .usecase_id = LLCC_MDM,
1375 .bonus_ways = 0xfff,
1377 .activate_on_init = true,
1379 .usecase_id = LLCC_GPUHTW,
1383 .bonus_ways = 0xfff,
1385 .activate_on_init = true,
1387 .usecase_id = LLCC_GPU,
1391 .bonus_ways = 0xfff,
1393 .activate_on_init = true,
1395 .usecase_id = LLCC_MDMPNG,
1400 .bonus_ways = 0xfff,
1402 .activate_on_init = true,
1404 .usecase_id = LLCC_NPU,
1408 .bonus_ways = 0xfff,
1410 .activate_on_init = true,
1412 .usecase_id = LLCC_MODPE,
1417 .bonus_ways = 0xfff,
1419 .activate_on_init = true,
1423 static const struct llcc_slice_config sm7150_data[] = {
1425 .usecase_id = LLCC_CPUSS,
1431 .retain_on_pc = true,
1432 .activate_on_init = true,
1434 .usecase_id = LLCC_MDM,
1440 .retain_on_pc = true,
1442 .usecase_id = LLCC_GPUHTW,
1449 .retain_on_pc = true,
1451 .usecase_id = LLCC_GPU,
1458 .retain_on_pc = true,
1460 .usecase_id = LLCC_NPU,
1466 .retain_on_pc = true,
1470 static const struct llcc_slice_config sm8150_data[] = {
1472 .usecase_id = LLCC_CPUSS,
1477 .bonus_ways = 0xfff,
1479 .retain_on_pc = true,
1480 .activate_on_init = true,
1482 .usecase_id = LLCC_VIDSC0,
1487 .bonus_ways = 0xfff,
1489 .retain_on_pc = true,
1491 .usecase_id = LLCC_VIDSC1,
1496 .bonus_ways = 0xfff,
1498 .retain_on_pc = true,
1500 .usecase_id = LLCC_AUDIO,
1505 .bonus_ways = 0xfff,
1507 .retain_on_pc = true,
1509 .usecase_id = LLCC_MDMHPGRW,
1516 .retain_on_pc = true,
1518 .usecase_id = LLCC_MDM,
1523 .bonus_ways = 0xfff,
1525 .retain_on_pc = true,
1527 .usecase_id = LLCC_MODHW,
1532 .bonus_ways = 0xfff,
1534 .retain_on_pc = true,
1536 .usecase_id = LLCC_CMPT,
1541 .bonus_ways = 0xfff,
1543 .retain_on_pc = true,
1545 .usecase_id = LLCC_GPUHTW,
1550 .bonus_ways = 0xfff,
1552 .retain_on_pc = true,
1554 .usecase_id = LLCC_GPU,
1559 .bonus_ways = 0xfff,
1561 .retain_on_pc = true,
1563 .usecase_id = LLCC_MMUHWT,
1568 .bonus_ways = 0xfff,
1570 .activate_on_init = true,
1572 .usecase_id = LLCC_CMPTDMA,
1577 .bonus_ways = 0xfff,
1579 .retain_on_pc = true,
1581 .usecase_id = LLCC_DISP,
1586 .bonus_ways = 0xfff,
1588 .retain_on_pc = true,
1590 .usecase_id = LLCC_MDMHPFX,
1595 .bonus_ways = 0xfff,
1597 .retain_on_pc = true,
1599 .usecase_id = LLCC_MDMHPFX,
1606 .retain_on_pc = true,
1608 .usecase_id = LLCC_AUDHW,
1613 .bonus_ways = 0xfff,
1615 .retain_on_pc = true,
1617 .usecase_id = LLCC_NPU,
1622 .bonus_ways = 0xfff,
1624 .retain_on_pc = true,
1626 .usecase_id = LLCC_WLHW,
1631 .bonus_ways = 0xfff,
1633 .retain_on_pc = true,
1635 .usecase_id = LLCC_MODPE,
1642 .retain_on_pc = true,
1644 .usecase_id = LLCC_APTCM,
1651 .retain_on_pc = true,
1653 .usecase_id = LLCC_WRCACHE,
1658 .bonus_ways = 0xfff,
1663 static const struct llcc_slice_config sm8250_data[] = {
1665 .usecase_id = LLCC_CPUSS,
1670 .bonus_ways = 0xfff,
1672 .retain_on_pc = true,
1673 .activate_on_init = true,
1675 .usecase_id = LLCC_VIDSC0,
1680 .bonus_ways = 0xfff,
1682 .retain_on_pc = true,
1684 .usecase_id = LLCC_AUDIO,
1688 .bonus_ways = 0xfff,
1691 .usecase_id = LLCC_CMPT,
1695 .bonus_ways = 0xfff,
1698 .usecase_id = LLCC_GPUHTW,
1703 .bonus_ways = 0xfff,
1705 .retain_on_pc = true,
1707 .usecase_id = LLCC_GPU,
1711 .bonus_ways = 0xfff,
1713 .retain_on_pc = true,
1714 .write_scid_en = true,
1716 .usecase_id = LLCC_MMUHWT,
1721 .bonus_ways = 0xfff,
1723 .activate_on_init = true,
1725 .usecase_id = LLCC_CMPTDMA,
1729 .bonus_ways = 0xfff,
1731 .retain_on_pc = true,
1733 .usecase_id = LLCC_DISP,
1738 .bonus_ways = 0xfff,
1740 .retain_on_pc = true,
1742 .usecase_id = LLCC_VIDFW,
1746 .bonus_ways = 0xfff,
1748 .retain_on_pc = true,
1750 .usecase_id = LLCC_AUDHW,
1755 .bonus_ways = 0xfff,
1757 .retain_on_pc = true,
1759 .usecase_id = LLCC_NPU,
1764 .bonus_ways = 0xfff,
1766 .retain_on_pc = true,
1768 .usecase_id = LLCC_WLHW,
1772 .bonus_ways = 0xfff,
1774 .retain_on_pc = true,
1776 .usecase_id = LLCC_CVP,
1781 .bonus_ways = 0xfff,
1783 .retain_on_pc = true,
1785 .usecase_id = LLCC_APTCM,
1791 .retain_on_pc = true,
1793 .usecase_id = LLCC_WRCACHE,
1798 .bonus_ways = 0xfff,
1800 .activate_on_init = true,
1804 static const struct llcc_slice_config sm8350_data[] = {
1806 .usecase_id = LLCC_CPUSS,
1811 .bonus_ways = 0xfff,
1813 .activate_on_init = true,
1814 .write_scid_en = true,
1816 .usecase_id = LLCC_VIDSC0,
1821 .bonus_ways = 0xfff,
1823 .activate_on_init = true,
1825 .usecase_id = LLCC_AUDIO,
1830 .bonus_ways = 0xfff,
1833 .usecase_id = LLCC_MDMHPGRW,
1837 .bonus_ways = 0xfff,
1839 .activate_on_init = true,
1841 .usecase_id = LLCC_MODHW,
1846 .bonus_ways = 0xfff,
1848 .activate_on_init = true,
1850 .usecase_id = LLCC_CMPT,
1855 .bonus_ways = 0xfff,
1857 .activate_on_init = true,
1859 .usecase_id = LLCC_GPUHTW,
1864 .bonus_ways = 0xfff,
1866 .activate_on_init = true,
1868 .usecase_id = LLCC_GPU,
1872 .bonus_ways = 0xfff,
1874 .retain_on_pc = true,
1875 .activate_on_init = true,
1877 .usecase_id = LLCC_MMUHWT,
1882 .bonus_ways = 0xfff,
1884 .write_scid_en = true,
1886 .usecase_id = LLCC_DISP,
1891 .bonus_ways = 0xfff,
1893 .activate_on_init = true,
1895 .usecase_id = LLCC_MDMPNG,
1902 .activate_on_init = true,
1904 .usecase_id = LLCC_AUDHW,
1909 .bonus_ways = 0xfff,
1911 .activate_on_init = true,
1913 .usecase_id = LLCC_CVP,
1918 .bonus_ways = 0xfff,
1920 .activate_on_init = true,
1922 .usecase_id = LLCC_MODPE,
1929 .activate_on_init = true,
1931 .usecase_id = LLCC_APTCM,
1938 .activate_on_init = true,
1940 .usecase_id = LLCC_WRCACHE,
1945 .bonus_ways = 0xfff,
1947 .write_scid_en = true,
1949 .usecase_id = LLCC_CVPFW,
1953 .bonus_ways = 0xfff,
1955 .activate_on_init = true,
1957 .usecase_id = LLCC_CPUSS1,
1962 .bonus_ways = 0xfff,
1964 .activate_on_init = true,
1966 .usecase_id = LLCC_CPUHWT,
1971 .bonus_ways = 0xfff,
1973 .write_scid_en = true,
1977 static const struct llcc_slice_config sm8450_data[] = {
1979 .usecase_id = LLCC_CPUSS,
1983 .bonus_ways = 0xffff,
1985 .retain_on_pc = true,
1986 .activate_on_init = true,
1988 .usecase_id = LLCC_VIDSC0,
1993 .bonus_ways = 0xffff,
1995 .retain_on_pc = true,
1997 .usecase_id = LLCC_AUDIO,
2002 .bonus_ways = 0xffff,
2005 .usecase_id = LLCC_MDMHPGRW,
2009 .bonus_ways = 0xffff,
2011 .retain_on_pc = true,
2013 .usecase_id = LLCC_MODHW,
2018 .bonus_ways = 0xffff,
2020 .retain_on_pc = true,
2022 .usecase_id = LLCC_CMPT,
2027 .bonus_ways = 0xffff,
2029 .retain_on_pc = true,
2031 .usecase_id = LLCC_GPUHTW,
2036 .bonus_ways = 0xffff,
2038 .retain_on_pc = true,
2040 .usecase_id = LLCC_GPU,
2045 .bonus_ways = 0xffff,
2047 .retain_on_pc = true,
2048 .write_scid_en = true,
2050 .usecase_id = LLCC_MMUHWT,
2055 .bonus_ways = 0xffff,
2057 .activate_on_init = true,
2059 .usecase_id = LLCC_DISP,
2064 .bonus_ways = 0xffff,
2066 .retain_on_pc = true,
2068 .usecase_id = LLCC_MDMPNG,
2073 .bonus_ways = 0xf000,
2075 .retain_on_pc = true,
2077 .usecase_id = LLCC_AUDHW,
2082 .bonus_ways = 0xffff,
2085 .usecase_id = LLCC_CVP,
2090 .bonus_ways = 0xffff,
2092 .retain_on_pc = true,
2094 .usecase_id = LLCC_MODPE,
2099 .bonus_ways = 0xf000,
2101 .retain_on_pc = true,
2103 .usecase_id = LLCC_APTCM,
2110 .retain_on_pc = true,
2112 .usecase_id = LLCC_WRCACHE,
2117 .bonus_ways = 0xffff,
2119 .activate_on_init = true,
2121 .usecase_id = LLCC_CVPFW,
2126 .bonus_ways = 0xffff,
2128 .retain_on_pc = true,
2130 .usecase_id = LLCC_CPUSS1,
2135 .bonus_ways = 0xffff,
2137 .retain_on_pc = true,
2139 .usecase_id = LLCC_CAMEXP0,
2144 .bonus_ways = 0xffff,
2146 .retain_on_pc = true,
2148 .usecase_id = LLCC_CPUMTE,
2153 .bonus_ways = 0xfff,
2155 .activate_on_init = true,
2157 .usecase_id = LLCC_CPUHWT,
2162 .bonus_ways = 0xffff,
2164 .retain_on_pc = true,
2165 .activate_on_init = true,
2167 .usecase_id = LLCC_CAMEXP1,
2172 .bonus_ways = 0xffff,
2174 .retain_on_pc = true,
2176 .usecase_id = LLCC_AENPU,
2181 .bonus_ways = 0xffff,
2186 static const struct llcc_slice_config sm8550_data[] = {
2188 .usecase_id = LLCC_CPUSS,
2192 .bonus_ways = 0xffffff,
2194 .activate_on_init = true,
2195 .write_scid_en = true,
2197 .usecase_id = LLCC_VIDSC0,
2202 .bonus_ways = 0xffffff,
2205 .usecase_id = LLCC_AUDIO,
2210 .bonus_ways = 0xffffff,
2213 .usecase_id = LLCC_MDMHPGRW,
2217 .bonus_ways = 0xffffff,
2220 .usecase_id = LLCC_MODHW,
2225 .bonus_ways = 0xffffff,
2228 .usecase_id = LLCC_CMPT,
2233 .bonus_ways = 0xffffff,
2236 .usecase_id = LLCC_GPUHTW,
2241 .bonus_ways = 0xffffff,
2244 .usecase_id = LLCC_GPU,
2248 .bonus_ways = 0xffffff,
2250 .write_scid_en = true,
2251 .write_scid_cacheable_en = true,
2253 .usecase_id = LLCC_MMUHWT,
2258 .bonus_ways = 0xffffff,
2260 .activate_on_init = true,
2262 .usecase_id = LLCC_DISP,
2267 .bonus_ways = 0xffffff,
2270 .usecase_id = LLCC_MDMPNG,
2275 .bonus_ways = 0xf00000,
2278 .usecase_id = LLCC_AUDHW,
2283 .bonus_ways = 0xffffff,
2286 .usecase_id = LLCC_CVP,
2291 .bonus_ways = 0xffffff,
2294 .usecase_id = LLCC_MODPE,
2299 .bonus_ways = 0xf00000,
2301 .alloc_oneway_en = true,
2304 .usecase_id = LLCC_WRCACHE,
2309 .bonus_ways = 0xffffff,
2311 .activate_on_init = true,
2313 .usecase_id = LLCC_CAMEXP0,
2321 .usecase_id = LLCC_CPUHWT,
2326 .bonus_ways = 0xffffff,
2328 .activate_on_init = true,
2330 .usecase_id = LLCC_CAMEXP1,
2335 .bonus_ways = 0xfffff0,
2338 .usecase_id = LLCC_CMPTHCP,
2343 .bonus_ways = 0xffffff,
2346 .usecase_id = LLCC_LCPDARE,
2351 .bonus_ways = 0xffffff,
2353 .activate_on_init = true,
2354 .alloc_oneway_en = true,
2357 .usecase_id = LLCC_AENPU,
2362 .bonus_ways = 0xfe01ff,
2365 .usecase_id = LLCC_ISLAND1,
2370 .bonus_ways = 0xfe00,
2373 .usecase_id = LLCC_ISLAND4,
2378 .bonus_ways = 0x10000,
2381 .usecase_id = LLCC_CAMEXP2,
2386 .bonus_ways = 0xfffff0,
2389 .usecase_id = LLCC_CAMEXP3,
2394 .bonus_ways = 0xfffff0,
2397 .usecase_id = LLCC_CAMEXP4,
2402 .bonus_ways = 0xfffff0,
2405 .usecase_id = LLCC_DISP_WB,
2410 .bonus_ways = 0xffffff,
2413 .usecase_id = LLCC_DISP_1,
2418 .bonus_ways = 0xffffff,
2421 .usecase_id = LLCC_VIDVSP,
2426 .bonus_ways = 0xffffff,
2431 static const struct llcc_slice_config sm8650_data[] = {
2433 .usecase_id = LLCC_CPUSS,
2437 .bonus_ways = 0xffffff,
2439 .activate_on_init = true,
2442 .usecase_id = LLCC_VIDSC0,
2447 .bonus_ways = 0xffffff,
2450 .usecase_id = LLCC_AUDIO,
2455 .bonus_ways = 0xffffff,
2458 .usecase_id = LLCC_MDMHPGRW,
2462 .bonus_ways = 0xffffff,
2465 .usecase_id = LLCC_MODHW,
2470 .bonus_ways = 0xffffff,
2473 .usecase_id = LLCC_CMPT,
2478 .bonus_ways = 0xffffff,
2481 .usecase_id = LLCC_GPUHTW,
2486 .bonus_ways = 0xffffff,
2489 .usecase_id = LLCC_GPU,
2493 .bonus_ways = 0xffffff,
2495 .write_scid_en = true,
2496 .write_scid_cacheable_en = true,
2498 .usecase_id = LLCC_MMUHWT,
2503 .bonus_ways = 0xffffff,
2505 .activate_on_init = true,
2507 .usecase_id = LLCC_DISP,
2512 .bonus_ways = 0xffffff,
2515 .usecase_id = LLCC_MDMHPFX,
2520 .bonus_ways = 0xffffff,
2523 .usecase_id = LLCC_MDMPNG,
2530 .usecase_id = LLCC_AUDHW,
2535 .bonus_ways = 0xffffff,
2538 .usecase_id = LLCC_CVP,
2543 .bonus_ways = 0xffffff,
2546 .usecase_id = LLCC_MODPE,
2551 .bonus_ways = 0xf00000,
2553 .alloc_oneway_en = true,
2555 .usecase_id = LLCC_WRCACHE,
2560 .bonus_ways = 0xffffff,
2562 .activate_on_init = true,
2564 .usecase_id = LLCC_CAMEXP0,
2572 .usecase_id = LLCC_CAMEXP1,
2577 .bonus_ways = 0xfffff0,
2580 .usecase_id = LLCC_CMPTHCP,
2585 .bonus_ways = 0xffffff,
2588 .usecase_id = LLCC_LCPDARE,
2593 .bonus_ways = 0xffffff,
2595 .activate_on_init = true,
2596 .alloc_oneway_en = true,
2598 .usecase_id = LLCC_AENPU,
2603 .bonus_ways = 0xffffff,
2606 .usecase_id = LLCC_ISLAND1,
2611 .res_ways = 0x7fffff,
2614 .usecase_id = LLCC_DISP_WB,
2619 .bonus_ways = 0xffffff,
2622 .usecase_id = LLCC_VIDVSP,
2627 .bonus_ways = 0xffffff,
2632 static const struct llcc_slice_config qcs615_data[] = {
2634 .usecase_id = LLCC_CPUSS,
2640 .activate_on_init = true,
2641 .write_scid_en = true,
2643 .usecase_id = LLCC_MDM,
2650 .activate_on_init = true,
2652 .usecase_id = LLCC_GPUHTW,
2659 .activate_on_init = true,
2661 .usecase_id = LLCC_GPU,
2667 .activate_on_init = true,
2671 static const struct llcc_slice_config qcs8300_data[] = {
2673 .usecase_id = LLCC_GPUHTW,
2680 .retain_on_pc = true,
2682 .usecase_id = LLCC_GPU,
2689 .retain_on_pc = true,
2690 .write_scid_en = true,
2692 .usecase_id = LLCC_MMUHWT,
2699 .activate_on_init = true,
2701 .usecase_id = LLCC_ECC,
2708 .activate_on_init = true,
2710 .usecase_id = LLCC_WRCACHE,
2717 .activate_on_init = true,
2721 static const struct llcc_slice_config qdu1000_data_2ch[] = {
2723 .usecase_id = LLCC_MDMHPGRW,
2728 .bonus_ways = 0xfff,
2730 .retain_on_pc = true,
2732 .usecase_id = LLCC_MODHW,
2737 .bonus_ways = 0xfff,
2739 .retain_on_pc = true,
2741 .usecase_id = LLCC_MDMPNG,
2748 .retain_on_pc = true,
2750 .usecase_id = LLCC_ECC,
2755 .bonus_ways = 0xffc,
2757 .activate_on_init = true,
2759 .usecase_id = LLCC_MODPE,
2764 .bonus_ways = 0xfff,
2766 .retain_on_pc = true,
2768 .usecase_id = LLCC_APTCM,
2775 .retain_on_pc = true,
2777 .usecase_id = LLCC_WRCACHE,
2784 .activate_on_init = true,
2788 static const struct llcc_slice_config qdu1000_data_4ch[] = {
2790 .usecase_id = LLCC_MDMHPGRW,
2795 .bonus_ways = 0xfff,
2797 .retain_on_pc = true,
2799 .usecase_id = LLCC_MODHW,
2804 .bonus_ways = 0xfff,
2806 .retain_on_pc = true,
2808 .usecase_id = LLCC_MDMPNG,
2815 .retain_on_pc = true,
2817 .usecase_id = LLCC_ECC,
2822 .bonus_ways = 0xffc,
2824 .activate_on_init = true,
2826 .usecase_id = LLCC_MODPE,
2831 .bonus_ways = 0xfff,
2833 .retain_on_pc = true,
2835 .usecase_id = LLCC_APTCM,
2842 .retain_on_pc = true,
2844 .usecase_id = LLCC_WRCACHE,
2851 .activate_on_init = true,
2855 static const struct llcc_slice_config qdu1000_data_8ch[] = {
2857 .usecase_id = LLCC_MDMHPGRW,
2862 .bonus_ways = 0xfff,
2864 .retain_on_pc = true,
2866 .usecase_id = LLCC_MODHW,
2871 .bonus_ways = 0xfff,
2873 .retain_on_pc = true,
2875 .usecase_id = LLCC_MDMPNG,
2882 .retain_on_pc = true,
2884 .usecase_id = LLCC_ECC,
2889 .bonus_ways = 0xffc,
2891 .activate_on_init = true,
2893 .usecase_id = LLCC_MODPE,
2898 .bonus_ways = 0xfff,
2900 .retain_on_pc = true,
2902 .usecase_id = LLCC_APTCM,
2909 .retain_on_pc = true,
2911 .usecase_id = LLCC_WRCACHE,
2918 .activate_on_init = true,
2922 static const struct llcc_slice_config x1e80100_data[] = {
2924 .usecase_id = LLCC_CPUSS,
2929 .bonus_ways = 0xfff,
2931 .activate_on_init = true,
2933 .usecase_id = LLCC_VIDSC0,
2938 .bonus_ways = 0xfff,
2941 .usecase_id = LLCC_AUDIO,
2946 .bonus_ways = 0xfff,
2949 .usecase_id = LLCC_CMPT,
2954 .bonus_ways = 0xfff,
2957 .usecase_id = LLCC_GPUHTW,
2962 .bonus_ways = 0xfff,
2965 .usecase_id = LLCC_GPU,
2969 .bonus_ways = 0xfff,
2971 .write_scid_en = true,
2972 .write_scid_cacheable_en = true,
2975 .usecase_id = LLCC_MMUHWT,
2980 .bonus_ways = 0xfff,
2982 .activate_on_init = true,
2984 .usecase_id = LLCC_AUDHW,
2989 .bonus_ways = 0xfff,
2992 .usecase_id = LLCC_CVP,
2997 .bonus_ways = 0xfff,
3000 .usecase_id = LLCC_WRCACHE,
3005 .bonus_ways = 0xfff,
3008 .usecase_id = LLCC_CAMEXP0,
3016 .usecase_id = LLCC_CAMEXP1,
3021 .bonus_ways = 0xffc,
3024 .usecase_id = LLCC_LCPDARE,
3029 .bonus_ways = 0xfff,
3031 .activate_on_init = true,
3032 .alloc_oneway_en = true,
3034 .usecase_id = LLCC_AENPU,
3039 .bonus_ways = 0xfff,
3042 .usecase_id = LLCC_ISLAND1,
3050 .usecase_id = LLCC_CAMEXP2,
3055 .bonus_ways = 0xffc,
3058 .usecase_id = LLCC_CAMEXP3,
3063 .bonus_ways = 0xffc,
3066 .usecase_id = LLCC_CAMEXP4,
3071 .bonus_ways = 0xffc,
3076 static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = {
3077 .trp_ecc_error_status0 = 0x20344,
3078 .trp_ecc_error_status1 = 0x20348,
3079 .trp_ecc_sb_err_syn0 = 0x2304c,
3080 .trp_ecc_db_err_syn0 = 0x20370,
3081 .trp_ecc_error_cntr_clear = 0x20440,
3082 .trp_interrupt_0_status = 0x20480,
3083 .trp_interrupt_0_clear = 0x20484,
3084 .trp_interrupt_0_enable = 0x20488,
3086 /* LLCC Common registers */
3087 .cmn_status0 = 0x3000c,
3088 .cmn_interrupt_0_enable = 0x3001c,
3089 .cmn_interrupt_2_enable = 0x3003c,
3091 /* LLCC DRP registers */
3092 .drp_ecc_error_cfg = 0x40000,
3093 .drp_ecc_error_cntr_clear = 0x40004,
3094 .drp_interrupt_status = 0x41000,
3095 .drp_interrupt_clear = 0x41008,
3096 .drp_interrupt_enable = 0x4100c,
3097 .drp_ecc_error_status0 = 0x42044,
3098 .drp_ecc_error_status1 = 0x42048,
3099 .drp_ecc_sb_err_syn0 = 0x4204c,
3100 .drp_ecc_db_err_syn0 = 0x42070,
3103 static const struct llcc_edac_reg_offset llcc_v2_1_edac_reg_offset = {
3104 .trp_ecc_error_status0 = 0x20344,
3105 .trp_ecc_error_status1 = 0x20348,
3106 .trp_ecc_sb_err_syn0 = 0x2034c,
3107 .trp_ecc_db_err_syn0 = 0x20370,
3108 .trp_ecc_error_cntr_clear = 0x20440,
3109 .trp_interrupt_0_status = 0x20480,
3110 .trp_interrupt_0_clear = 0x20484,
3111 .trp_interrupt_0_enable = 0x20488,
3113 /* LLCC Common registers */
3114 .cmn_status0 = 0x3400c,
3115 .cmn_interrupt_0_enable = 0x3401c,
3116 .cmn_interrupt_2_enable = 0x3403c,
3118 /* LLCC DRP registers */
3119 .drp_ecc_error_cfg = 0x50000,
3120 .drp_ecc_error_cntr_clear = 0x50004,
3121 .drp_interrupt_status = 0x50020,
3122 .drp_interrupt_clear = 0x50028,
3123 .drp_interrupt_enable = 0x5002c,
3124 .drp_ecc_error_status0 = 0x520f4,
3125 .drp_ecc_error_status1 = 0x520f8,
3126 .drp_ecc_sb_err_syn0 = 0x520fc,
3127 .drp_ecc_db_err_syn0 = 0x52120,
3130 /* LLCC register offset starting from v1.0.0 */
3131 static const u32 llcc_v1_reg_offset[] = {
3132 [LLCC_COMMON_HW_INFO] = 0x00030000,
3133 [LLCC_COMMON_STATUS0] = 0x0003000c,
3136 /* LLCC register offset starting from v2.0.1 */
3137 static const u32 llcc_v2_1_reg_offset[] = {
3138 [LLCC_COMMON_HW_INFO] = 0x00034000,
3139 [LLCC_COMMON_STATUS0] = 0x0003400c,
3142 static const struct qcom_llcc_config qcs615_cfg[] = {
3144 .sct_data = qcs615_data,
3145 .size = ARRAY_SIZE(qcs615_data),
3146 .reg_offset = llcc_v1_reg_offset,
3147 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3151 static const struct qcom_llcc_config qcs8300_cfg[] = {
3153 .sct_data = qcs8300_data,
3154 .size = ARRAY_SIZE(qcs8300_data),
3155 .reg_offset = llcc_v2_1_reg_offset,
3156 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3161 static const struct qcom_llcc_config qdu1000_cfg[] = {
3163 .sct_data = qdu1000_data_8ch,
3164 .size = ARRAY_SIZE(qdu1000_data_8ch),
3165 .reg_offset = llcc_v2_1_reg_offset,
3166 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3169 .sct_data = qdu1000_data_4ch,
3170 .size = ARRAY_SIZE(qdu1000_data_4ch),
3171 .reg_offset = llcc_v2_1_reg_offset,
3172 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3175 .sct_data = qdu1000_data_4ch,
3176 .size = ARRAY_SIZE(qdu1000_data_4ch),
3177 .reg_offset = llcc_v2_1_reg_offset,
3178 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3181 .sct_data = qdu1000_data_2ch,
3182 .size = ARRAY_SIZE(qdu1000_data_2ch),
3183 .reg_offset = llcc_v2_1_reg_offset,
3184 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3188 static const struct qcom_llcc_config sa8775p_cfg[] = {
3190 .sct_data = sa8775p_data,
3191 .size = ARRAY_SIZE(sa8775p_data),
3192 .reg_offset = llcc_v2_1_reg_offset,
3193 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3197 static const struct qcom_llcc_config sar1130p_cfg[] = {
3199 .sct_data = sar1130p_data,
3200 .size = ARRAY_SIZE(sar1130p_data),
3201 .reg_offset = llcc_v2_1_reg_offset,
3202 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3203 .max_cap_shift = 14,
3208 static const struct qcom_llcc_config sar2130p_cfg[] = {
3210 .sct_data = sar2130p_data,
3211 .size = ARRAY_SIZE(sar2130p_data),
3212 .reg_offset = llcc_v2_1_reg_offset,
3213 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3214 .max_cap_shift = 14,
3219 static const struct qcom_llcc_config sc7180_cfg[] = {
3221 .sct_data = sc7180_data,
3222 .size = ARRAY_SIZE(sc7180_data),
3223 .reg_offset = llcc_v1_reg_offset,
3224 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3228 static const struct qcom_llcc_config sc7280_cfg[] = {
3230 .sct_data = sc7280_data,
3231 .size = ARRAY_SIZE(sc7280_data),
3232 .reg_offset = llcc_v1_reg_offset,
3233 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3237 static const struct qcom_llcc_config sc8180x_cfg[] = {
3239 .sct_data = sc8180x_data,
3240 .size = ARRAY_SIZE(sc8180x_data),
3241 .reg_offset = llcc_v1_reg_offset,
3242 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3246 static const struct qcom_llcc_config sc8280xp_cfg[] = {
3248 .sct_data = sc8280xp_data,
3249 .size = ARRAY_SIZE(sc8280xp_data),
3250 .reg_offset = llcc_v1_reg_offset,
3251 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3255 static const struct qcom_llcc_config sdm845_cfg[] = {
3257 .sct_data = sdm845_data,
3258 .size = ARRAY_SIZE(sdm845_data),
3259 .skip_llcc_cfg = true,
3260 .reg_offset = llcc_v1_reg_offset,
3261 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3266 static const struct qcom_llcc_config sm6350_cfg[] = {
3268 .sct_data = sm6350_data,
3269 .size = ARRAY_SIZE(sm6350_data),
3270 .reg_offset = llcc_v1_reg_offset,
3271 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3275 static const struct qcom_llcc_config sm7150_cfg[] = {
3277 .sct_data = sm7150_data,
3278 .size = ARRAY_SIZE(sm7150_data),
3279 .reg_offset = llcc_v1_reg_offset,
3280 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3284 static const struct qcom_llcc_config sm8150_cfg[] = {
3286 .sct_data = sm8150_data,
3287 .size = ARRAY_SIZE(sm8150_data),
3288 .reg_offset = llcc_v1_reg_offset,
3289 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3293 static const struct qcom_llcc_config sm8250_cfg[] = {
3295 .sct_data = sm8250_data,
3296 .size = ARRAY_SIZE(sm8250_data),
3297 .reg_offset = llcc_v1_reg_offset,
3298 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3302 static const struct qcom_llcc_config sm8350_cfg[] = {
3304 .sct_data = sm8350_data,
3305 .size = ARRAY_SIZE(sm8350_data),
3306 .reg_offset = llcc_v1_reg_offset,
3307 .edac_reg_offset = &llcc_v1_edac_reg_offset,
3311 static const struct qcom_llcc_config sm8450_cfg[] = {
3313 .sct_data = sm8450_data,
3314 .size = ARRAY_SIZE(sm8450_data),
3315 .reg_offset = llcc_v2_1_reg_offset,
3316 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3320 static const struct qcom_llcc_config sm8550_cfg[] = {
3322 .sct_data = sm8550_data,
3323 .size = ARRAY_SIZE(sm8550_data),
3324 .reg_offset = llcc_v2_1_reg_offset,
3325 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3329 static const struct qcom_llcc_config sm8650_cfg[] = {
3331 .sct_data = sm8650_data,
3332 .size = ARRAY_SIZE(sm8650_data),
3333 .reg_offset = llcc_v2_1_reg_offset,
3334 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3338 static const struct qcom_llcc_config x1e80100_cfg[] = {
3340 .sct_data = x1e80100_data,
3341 .size = ARRAY_SIZE(x1e80100_data),
3342 .reg_offset = llcc_v2_1_reg_offset,
3343 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,
3344 .irq_configured = true,
3348 static const struct qcom_sct_config qcs615_cfgs = {
3349 .llcc_config = qcs615_cfg,
3350 .num_config = ARRAY_SIZE(qcs615_cfg),
3353 static const struct qcom_sct_config qcs8300_cfgs = {
3354 .llcc_config = qcs8300_cfg,
3355 .num_config = ARRAY_SIZE(qcs8300_cfg),
3358 static const struct qcom_sct_config qdu1000_cfgs = {
3359 .llcc_config = qdu1000_cfg,
3360 .num_config = ARRAY_SIZE(qdu1000_cfg),
3363 static const struct qcom_sct_config sa8775p_cfgs = {
3364 .llcc_config = sa8775p_cfg,
3365 .num_config = ARRAY_SIZE(sa8775p_cfg),
3368 static const struct qcom_sct_config sar1130p_cfgs = {
3369 .llcc_config = sar1130p_cfg,
3370 .num_config = ARRAY_SIZE(sar1130p_cfg),
3373 static const struct qcom_sct_config sar2130p_cfgs = {
3374 .llcc_config = sar2130p_cfg,
3375 .num_config = ARRAY_SIZE(sar2130p_cfg),
3378 static const struct qcom_sct_config sc7180_cfgs = {
3379 .llcc_config = sc7180_cfg,
3380 .num_config = ARRAY_SIZE(sc7180_cfg),
3383 static const struct qcom_sct_config sc7280_cfgs = {
3384 .llcc_config = sc7280_cfg,
3385 .num_config = ARRAY_SIZE(sc7280_cfg),
3388 static const struct qcom_sct_config sc8180x_cfgs = {
3389 .llcc_config = sc8180x_cfg,
3390 .num_config = ARRAY_SIZE(sc8180x_cfg),
3393 static const struct qcom_sct_config sc8280xp_cfgs = {
3394 .llcc_config = sc8280xp_cfg,
3395 .num_config = ARRAY_SIZE(sc8280xp_cfg),
3398 static const struct qcom_sct_config sdm845_cfgs = {
3399 .llcc_config = sdm845_cfg,
3400 .num_config = ARRAY_SIZE(sdm845_cfg),
3403 static const struct qcom_sct_config sm6350_cfgs = {
3404 .llcc_config = sm6350_cfg,
3405 .num_config = ARRAY_SIZE(sm6350_cfg),
3408 static const struct qcom_sct_config sm7150_cfgs = {
3409 .llcc_config = sm7150_cfg,
3410 .num_config = ARRAY_SIZE(sm7150_cfg),
3413 static const struct qcom_sct_config sm8150_cfgs = {
3414 .llcc_config = sm8150_cfg,
3415 .num_config = ARRAY_SIZE(sm8150_cfg),
3418 static const struct qcom_sct_config sm8250_cfgs = {
3419 .llcc_config = sm8250_cfg,
3420 .num_config = ARRAY_SIZE(sm8250_cfg),
3423 static const struct qcom_sct_config sm8350_cfgs = {
3424 .llcc_config = sm8350_cfg,
3425 .num_config = ARRAY_SIZE(sm8350_cfg),
3428 static const struct qcom_sct_config sm8450_cfgs = {
3429 .llcc_config = sm8450_cfg,
3430 .num_config = ARRAY_SIZE(sm8450_cfg),
3433 static const struct qcom_sct_config sm8550_cfgs = {
3434 .llcc_config = sm8550_cfg,
3435 .num_config = ARRAY_SIZE(sm8550_cfg),
3438 static const struct qcom_sct_config sm8650_cfgs = {
3439 .llcc_config = sm8650_cfg,
3440 .num_config = ARRAY_SIZE(sm8650_cfg),
3443 static const struct qcom_sct_config x1e80100_cfgs = {
3444 .llcc_config = x1e80100_cfg,
3445 .num_config = ARRAY_SIZE(x1e80100_cfg),
3448 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
3451 * llcc_slice_getd - get llcc slice descriptor
3452 * @uid: usecase_id for the client
3454 * A pointer to llcc slice descriptor will be returned on success
3455 * and error pointer is returned on failure
3457 struct llcc_slice_desc *llcc_slice_getd(u32 uid)
3459 const struct llcc_slice_config *cfg;
3460 struct llcc_slice_desc *desc;
3463 if (IS_ERR(drv_data))
3464 return ERR_CAST(drv_data);
3466 cfg = drv_data->cfg;
3467 sz = drv_data->cfg_size;
3469 for (count = 0; cfg && count < sz; count++, cfg++)
3470 if (cfg->usecase_id == uid)
3473 if (count == sz || !cfg)
3474 return ERR_PTR(-ENODEV);
3476 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
3478 return ERR_PTR(-ENOMEM);
3480 desc->slice_id = cfg->slice_id;
3481 desc->slice_size = cfg->max_cap;
3485 EXPORT_SYMBOL_GPL(llcc_slice_getd);
3488 * llcc_slice_putd - llcc slice descriptor
3489 * @desc: Pointer to llcc slice descriptor
3491 void llcc_slice_putd(struct llcc_slice_desc *desc)
3493 if (!IS_ERR_OR_NULL(desc))
3496 EXPORT_SYMBOL_GPL(llcc_slice_putd);
3498 static int llcc_update_act_ctrl(u32 sid,
3499 u32 act_ctrl_reg_val, u32 status)
3501 struct regmap *regmap;
3508 if (IS_ERR(drv_data))
3509 return PTR_ERR(drv_data);
3511 act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);
3512 act_clear_reg = LLCC_TRP_ACT_CLEARn(sid);
3513 status_reg = LLCC_TRP_STATUSn(sid);
3515 /* Set the ACTIVE trigger */
3516 act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;
3517 ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
3522 /* Clear the ACTIVE trigger */
3523 act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;
3524 ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
3529 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
3530 regmap = drv_data->bcast_and_regmap ?: drv_data->bcast_regmap;
3531 ret = regmap_read_poll_timeout(regmap, status_reg,
3532 slice_status, (slice_status & ACT_COMPLETE),
3533 0, LLCC_STATUS_READ_DELAY);
3538 ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,
3539 slice_status, !(slice_status & status),
3540 0, LLCC_STATUS_READ_DELAY);
3544 if (drv_data->version >= LLCC_VERSION_4_1_0_0)
3545 ret = regmap_write(drv_data->bcast_regmap, act_clear_reg,
3552 * llcc_slice_activate - Activate the llcc slice
3553 * @desc: Pointer to llcc slice descriptor
3555 * A value of zero will be returned on success and a negative errno will
3556 * be returned in error cases
3558 int llcc_slice_activate(struct llcc_slice_desc *desc)
3563 if (IS_ERR(drv_data))
3564 return PTR_ERR(drv_data);
3566 if (IS_ERR_OR_NULL(desc))
3569 mutex_lock(&drv_data->lock);
3570 if (test_bit(desc->slice_id, drv_data->bitmap)) {
3571 mutex_unlock(&drv_data->lock);
3575 act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT;
3577 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
3580 mutex_unlock(&drv_data->lock);
3584 __set_bit(desc->slice_id, drv_data->bitmap);
3585 mutex_unlock(&drv_data->lock);
3589 EXPORT_SYMBOL_GPL(llcc_slice_activate);
3592 * llcc_slice_deactivate - Deactivate the llcc slice
3593 * @desc: Pointer to llcc slice descriptor
3595 * A value of zero will be returned on success and a negative errno will
3596 * be returned in error cases
3598 int llcc_slice_deactivate(struct llcc_slice_desc *desc)
3603 if (IS_ERR(drv_data))
3604 return PTR_ERR(drv_data);
3606 if (IS_ERR_OR_NULL(desc))
3609 mutex_lock(&drv_data->lock);
3610 if (!test_bit(desc->slice_id, drv_data->bitmap)) {
3611 mutex_unlock(&drv_data->lock);
3614 act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT;
3616 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
3619 mutex_unlock(&drv_data->lock);
3623 __clear_bit(desc->slice_id, drv_data->bitmap);
3624 mutex_unlock(&drv_data->lock);
3628 EXPORT_SYMBOL_GPL(llcc_slice_deactivate);
3631 * llcc_get_slice_id - return the slice id
3632 * @desc: Pointer to llcc slice descriptor
3634 int llcc_get_slice_id(struct llcc_slice_desc *desc)
3636 if (IS_ERR_OR_NULL(desc))
3639 return desc->slice_id;
3641 EXPORT_SYMBOL_GPL(llcc_get_slice_id);
3644 * llcc_get_slice_size - return the slice id
3645 * @desc: Pointer to llcc slice descriptor
3647 size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
3649 if (IS_ERR_OR_NULL(desc))
3652 return desc->slice_size;
3654 EXPORT_SYMBOL_GPL(llcc_get_slice_size);
3656 static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
3657 const struct qcom_llcc_config *cfg)
3666 u32 max_cap_cacheline;
3667 struct llcc_slice_desc desc;
3669 attr1_val = config->cache_mode;
3670 attr1_val |= config->probe_target_ways << ATTR1_PROBE_TARGET_WAYS_SHIFT;
3671 attr1_val |= config->fixed_size << ATTR1_FIXED_SIZE_SHIFT;
3672 attr1_val |= config->priority << ATTR1_PRIORITY_SHIFT;
3674 max_cap_cacheline = MAX_CAP_TO_BYTES(config->max_cap);
3677 * LLCC instances can vary for each target.
3678 * The SW writes to broadcast register which gets propagated
3679 * to each llcc instance (llcc0,.. llccN).
3680 * Since the size of the memory is divided equally amongst the
3681 * llcc instances, we need to configure the max cap accordingly.
3683 max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;
3684 max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;
3685 if (cfg->max_cap_shift)
3686 attr1_val |= max_cap_cacheline << cfg->max_cap_shift;
3688 attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;
3690 attr1_cfg = LLCC_TRP_ATTR1_CFGn(config->slice_id);
3692 ret = regmap_write(drv_data->bcast_regmap, attr1_cfg, attr1_val);
3696 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
3697 attr2_cfg = LLCC_TRP_ATTR2_CFGn(config->slice_id);
3698 attr0_val = config->res_ways;
3699 attr2_val = config->bonus_ways;
3701 attr0_val = config->res_ways & ATTR0_RES_WAYS_MASK;
3702 attr0_val |= config->bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
3705 attr0_cfg = LLCC_TRP_ATTR0_CFGn(config->slice_id);
3707 ret = regmap_write(drv_data->bcast_regmap, attr0_cfg, attr0_val);
3711 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
3712 ret = regmap_write(drv_data->bcast_regmap, attr2_cfg, attr2_val);
3717 /* At least SDM845 disallows non-secure writes to these registers */
3718 if (!cfg->skip_llcc_cfg) {
3719 u32 disable_cap_alloc, retain_pc;
3721 disable_cap_alloc = config->dis_cap_alloc << config->slice_id;
3722 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_SCID_DIS_CAP_ALLOC,
3723 BIT(config->slice_id), disable_cap_alloc);
3727 if (drv_data->version < LLCC_VERSION_4_1_0_0) {
3728 retain_pc = config->retain_on_pc << config->slice_id;
3729 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_PCB_ACT,
3730 BIT(config->slice_id), retain_pc);
3736 if (drv_data->version >= LLCC_VERSION_2_0_0_0) {
3739 wren = config->write_scid_en << config->slice_id;
3740 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_EN,
3741 BIT(config->slice_id), wren);
3746 if (drv_data->version >= LLCC_VERSION_2_1_0_0) {
3749 wr_cache_en = config->write_scid_cacheable_en << config->slice_id;
3750 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_CACHEABLE_EN,
3751 BIT(config->slice_id), wr_cache_en);
3756 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
3761 u32 alloc_oneway_en;
3766 stale_en = config->stale_en << config->slice_id;
3767 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG1,
3768 BIT(config->slice_id), stale_en);
3772 stale_cap_en = config->stale_cap_en << config->slice_id;
3773 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG2,
3774 BIT(config->slice_id), stale_cap_en);
3778 mru_uncap_en = config->mru_uncap_en << config->slice_id;
3779 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG3,
3780 BIT(config->slice_id), mru_uncap_en);
3784 mru_rollover = config->mru_rollover << config->slice_id;
3785 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG4,
3786 BIT(config->slice_id), mru_rollover);
3790 alloc_oneway_en = config->alloc_oneway_en << config->slice_id;
3791 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG5,
3792 BIT(config->slice_id), alloc_oneway_en);
3796 ovcap_en = config->ovcap_en << config->slice_id;
3797 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG6,
3798 BIT(config->slice_id), ovcap_en);
3802 ovcap_prio = config->ovcap_prio << config->slice_id;
3803 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG7,
3804 BIT(config->slice_id), ovcap_prio);
3808 vict_prio = config->vict_prio << config->slice_id;
3809 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG8,
3810 BIT(config->slice_id), vict_prio);
3815 if (config->activate_on_init) {
3816 desc.slice_id = config->slice_id;
3817 ret = llcc_slice_activate(&desc);
3823 static int qcom_llcc_cfg_program(struct platform_device *pdev,
3824 const struct qcom_llcc_config *cfg)
3829 const struct llcc_slice_config *llcc_table;
3831 sz = drv_data->cfg_size;
3832 llcc_table = drv_data->cfg;
3834 for (i = 0; i < sz; i++) {
3835 ret = _qcom_llcc_cfg_program(&llcc_table[i], cfg);
3843 static int qcom_llcc_get_cfg_index(struct platform_device *pdev, u8 *cfg_index, int num_config)
3847 ret = nvmem_cell_read_u8(&pdev->dev, "multi-chan-ddr", cfg_index);
3848 if (ret == -ENOENT || ret == -EOPNOTSUPP) {
3855 if (!ret && *cfg_index >= num_config)
3861 static void qcom_llcc_remove(struct platform_device *pdev)
3863 /* Set the global pointer to a error code to avoid referencing it */
3864 drv_data = ERR_PTR(-ENODEV);
3867 static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index,
3871 struct regmap_config llcc_regmap_config = {
3878 base = devm_platform_ioremap_resource(pdev, index);
3880 return ERR_CAST(base);
3882 llcc_regmap_config.name = name;
3883 return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config);
3886 static int qcom_llcc_probe(struct platform_device *pdev)
3889 struct device *dev = &pdev->dev;
3891 struct platform_device *llcc_edac;
3892 const struct qcom_sct_config *cfgs;
3893 const struct qcom_llcc_config *cfg;
3894 const struct llcc_slice_config *llcc_cfg;
3898 struct regmap *regmap;
3900 if (!IS_ERR(drv_data))
3903 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
3909 /* Initialize the first LLCC bank regmap */
3910 regmap = qcom_llcc_init_mmio(pdev, 0, "llcc0_base");
3911 if (IS_ERR(regmap)) {
3912 ret = PTR_ERR(regmap);
3916 cfgs = of_device_get_match_data(&pdev->dev);
3921 ret = qcom_llcc_get_cfg_index(pdev, &cfg_index, cfgs->num_config);
3924 cfg = &cfgs->llcc_config[cfg_index];
3926 if (cfg->num_banks) {
3927 num_banks = cfg->num_banks;
3929 ret = regmap_read(regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], &num_banks);
3933 num_banks &= LLCC_LB_CNT_MASK;
3934 num_banks >>= LLCC_LB_CNT_SHIFT;
3937 drv_data->num_banks = num_banks;
3939 drv_data->regmaps = devm_kcalloc(dev, num_banks, sizeof(*drv_data->regmaps), GFP_KERNEL);
3940 if (!drv_data->regmaps) {
3945 drv_data->regmaps[0] = regmap;
3947 /* Initialize rest of LLCC bank regmaps */
3948 for (i = 1; i < num_banks; i++) {
3949 char *base __free(kfree) = kasprintf(GFP_KERNEL, "llcc%d_base", i);
3951 drv_data->regmaps[i] = qcom_llcc_init_mmio(pdev, i, base);
3952 if (IS_ERR(drv_data->regmaps[i])) {
3953 ret = PTR_ERR(drv_data->regmaps[i]);
3958 drv_data->bcast_regmap = qcom_llcc_init_mmio(pdev, i, "llcc_broadcast_base");
3959 if (IS_ERR(drv_data->bcast_regmap)) {
3960 ret = PTR_ERR(drv_data->bcast_regmap);
3964 /* Extract version of the IP */
3965 ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO],
3970 drv_data->version = version;
3972 /* Applicable only when drv_data->version >= 4.1 */
3973 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {
3974 drv_data->bcast_and_regmap = qcom_llcc_init_mmio(pdev, i + 1, "llcc_broadcast_and_base");
3975 if (IS_ERR(drv_data->bcast_and_regmap)) {
3976 ret = PTR_ERR(drv_data->bcast_and_regmap);
3978 drv_data->bcast_and_regmap = NULL;
3984 llcc_cfg = cfg->sct_data;
3987 for (i = 0; i < sz; i++)
3988 if (llcc_cfg[i].slice_id > drv_data->max_slices)
3989 drv_data->max_slices = llcc_cfg[i].slice_id;
3991 drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices,
3993 if (!drv_data->bitmap) {
3998 drv_data->cfg = llcc_cfg;
3999 drv_data->cfg_size = sz;
4000 drv_data->edac_reg_offset = cfg->edac_reg_offset;
4001 drv_data->ecc_irq_configured = cfg->irq_configured;
4002 mutex_init(&drv_data->lock);
4003 platform_set_drvdata(pdev, drv_data);
4005 ret = qcom_llcc_cfg_program(pdev, cfg);
4009 drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
4012 * On some platforms, the access to EDAC registers will be locked by
4013 * the bootloader. So probing the EDAC driver will result in a crash.
4014 * Hence, disable the creation of EDAC platform device for the
4015 * problematic platforms.
4017 if (!cfg->no_edac) {
4018 llcc_edac = platform_device_register_data(&pdev->dev,
4019 "qcom_llcc_edac", -1, drv_data,
4021 if (IS_ERR(llcc_edac))
4022 dev_err(dev, "Failed to register llcc edac driver\n");
4027 drv_data = ERR_PTR(-ENODEV);
4031 static const struct of_device_id qcom_llcc_of_match[] = {
4032 { .compatible = "qcom,qcs615-llcc", .data = &qcs615_cfgs},
4033 { .compatible = "qcom,qcs8300-llcc", .data = &qcs8300_cfgs},
4034 { .compatible = "qcom,qdu1000-llcc", .data = &qdu1000_cfgs},
4035 { .compatible = "qcom,sa8775p-llcc", .data = &sa8775p_cfgs },
4036 { .compatible = "qcom,sar1130p-llcc", .data = &sar1130p_cfgs },
4037 { .compatible = "qcom,sar2130p-llcc", .data = &sar2130p_cfgs },
4038 { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfgs },
4039 { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfgs },
4040 { .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfgs },
4041 { .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfgs },
4042 { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfgs },
4043 { .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfgs },
4044 { .compatible = "qcom,sm7150-llcc", .data = &sm7150_cfgs },
4045 { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfgs },
4046 { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfgs },
4047 { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfgs },
4048 { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfgs },
4049 { .compatible = "qcom,sm8550-llcc", .data = &sm8550_cfgs },
4050 { .compatible = "qcom,sm8650-llcc", .data = &sm8650_cfgs },
4051 { .compatible = "qcom,x1e80100-llcc", .data = &x1e80100_cfgs },
4054 MODULE_DEVICE_TABLE(of, qcom_llcc_of_match);
4056 static struct platform_driver qcom_llcc_driver = {
4058 .name = "qcom-llcc",
4059 .of_match_table = qcom_llcc_of_match,
4061 .probe = qcom_llcc_probe,
4062 .remove = qcom_llcc_remove,
4064 module_platform_driver(qcom_llcc_driver);
4066 MODULE_DESCRIPTION("Qualcomm Last Level Cache Controller");
4067 MODULE_LICENSE("GPL v2");