1413 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.4 *5 */6 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>12#include <linux/io.h>13#include <linux/kernel.h>14#include <linux/module.h>15#include <linux/mutex.h>16#include <linux/nvmem-consumer.h>17#include <linux/of.h>18#include <linux/regmap.h>19#include <linux/sizes.h>20#include <linux/slab.h>21#include <linux/soc/qcom/llcc-qcom.h>22 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 0x0131#define ATTR1_PROBE_TARGET_WAYS_SHIFT 0x0232#define ATTR1_FIXED_SIZE_SHIFT 0x0333#define ATTR1_PRIORITY_SHIFT 0x0434#define ATTR1_MAX_CAP_SHIFT 0x1035#define ATTR0_RES_WAYS_MASK GENMASK(15, 0)36#define ATTR0_BONUS_WAYS_MASK GENMASK(31, 16)37#define ATTR0_BONUS_WAYS_SHIFT 0x1038#define LLCC_STATUS_READ_DELAY 10039 40#define CACHE_LINE_SIZE_SHIFT 641 42#define LLCC_LB_CNT_MASK GENMASK(31, 28)43#define LLCC_LB_CNT_SHIFT 2844 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)52 53#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f0054#define LLCC_TRP_PCB_ACT 0x21f0455#define LLCC_TRP_ALGO_CFG1 0x21f0c56#define LLCC_TRP_ALGO_CFG2 0x21f1057#define LLCC_TRP_ALGO_CFG3 0x21f1458#define LLCC_TRP_ALGO_CFG4 0x21f1859#define LLCC_TRP_ALGO_CFG5 0x21f1c60#define LLCC_TRP_WRSC_EN 0x21f2061#define LLCC_TRP_ALGO_CFG6 0x21f2462#define LLCC_TRP_ALGO_CFG7 0x21f2863#define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c64#define LLCC_TRP_ALGO_CFG8 0x21f3065 66#define LLCC_VERSION_2_0_0_0 0x0200000067#define LLCC_VERSION_2_1_0_0 0x0201000068#define LLCC_VERSION_4_1_0_0 0x0401000069 70/**71 * struct llcc_slice_config - Data associated with the llcc slice72 * @usecase_id: Unique id for the client's use case73 * @slice_id: llcc slice id for each client74 * @max_cap: The maximum capacity of the cache slice provided in KB75 * @priority: Priority of the client used to select victim line for replacement76 * @fixed_size: Boolean indicating if the slice has a fixed capacity77 * @bonus_ways: Bonus ways are additional ways to be used for any slice,78 * if client ends up using more than reserved cache ways. Bonus79 * ways are allocated only if they are not reserved for some80 * other client.81 * @res_ways: Reserved ways for the cache slice, the reserved ways cannot82 * 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 the84 * slice: normal or TCM(Tightly Coupled Memory)85 * @probe_target_ways: Determines what ways to probe for access hit. When86 * 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 client89 * @retain_on_pc: If this bit is set and client has maintained active vote90 * then the ways assigned to this client are not flushed on power91 * collapse.92 * @activate_on_init: Activate the slice immediately after it is programmed93 * @write_scid_en: Bit enables write cache support for a given scid.94 * @write_scid_cacheable_en: Enables write cache cacheable support for a95 * 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 is99 * under-cap.100 * @mru_rollover: Roll-over on reserved cache ways.101 * @alloc_oneway_en: Allways allocate one way on over-cap even if there's no102 * 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 priority105 * over-cap scid. Depends on corresponding bit being set in106 * ovcap_en.107 * @vict_prio: When current scid is under-capacity, allocate over other108 * lower-than victim priority-line threshold scid.109 */110struct llcc_slice_config {111 u32 usecase_id;112 u32 slice_id;113 u32 max_cap;114 u32 priority;115 bool fixed_size;116 u32 bonus_ways;117 u32 res_ways;118 u32 cache_mode;119 u32 probe_target_ways;120 bool dis_cap_alloc;121 bool retain_on_pc;122 bool activate_on_init;123 bool write_scid_en;124 bool write_scid_cacheable_en;125 bool stale_en;126 bool stale_cap_en;127 bool mru_uncap_en;128 bool mru_rollover;129 bool alloc_oneway_en;130 bool ovcap_en;131 bool ovcap_prio;132 bool vict_prio;133};134 135struct 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 int size;140 bool need_llcc_cfg;141 bool no_edac;142 bool irq_configured;143};144 145struct qcom_sct_config {146 const struct qcom_llcc_config *llcc_config;147 int num_config;148};149 150enum llcc_reg_offset {151 LLCC_COMMON_HW_INFO,152 LLCC_COMMON_STATUS0,153};154 155static const struct llcc_slice_config sa8775p_data[] = {156 {LLCC_CPUSS, 1, 2048, 1, 0, 0x00FF, 0x0, 0, 0, 0, 1, 1, 0, 0},157 {LLCC_VIDSC0, 2, 512, 3, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},158 {LLCC_CPUSS1, 3, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},159 {LLCC_CPUHWT, 5, 512, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},160 {LLCC_AUDIO, 6, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 0, 0, 0},161 {LLCC_CMPT, 10, 4096, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},162 {LLCC_GPUHTW, 11, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},163 {LLCC_GPU, 12, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 1, 0},164 {LLCC_MMUHWT, 13, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 1, 0, 0},165 {LLCC_CMPTDMA, 15, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},166 {LLCC_DISP, 16, 4096, 2, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},167 {LLCC_VIDFW, 17, 3072, 1, 0, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},168 {LLCC_AUDHW, 22, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 0, 0, 0},169 {LLCC_CVP, 28, 256, 3, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0},170 {LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xF0, 1, 0, 0, 1, 0, 0, 0},171 {LLCC_WRCACHE, 31, 512, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 1, 0, 0},172};173 174static const struct llcc_slice_config sc7180_data[] = {175 { LLCC_CPUSS, 1, 256, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 1 },176 { LLCC_MDM, 8, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 },177 { LLCC_GPUHTW, 11, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 },178 { LLCC_GPU, 12, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 },179};180 181static const struct llcc_slice_config sc7280_data[] = {182 { LLCC_CPUSS, 1, 768, 1, 0, 0x3f, 0x0, 0, 0, 0, 1, 1, 0},183 { LLCC_MDMHPGRW, 7, 512, 2, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},184 { LLCC_CMPT, 10, 768, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},185 { LLCC_GPUHTW, 11, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},186 { LLCC_GPU, 12, 512, 1, 0, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},187 { LLCC_MMUHWT, 13, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 0, 1, 0},188 { LLCC_MDMPNG, 21, 768, 0, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},189 { LLCC_WLHW, 24, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},190 { LLCC_MODPE, 29, 64, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},191};192 193static const struct llcc_slice_config sc8180x_data[] = {194 { LLCC_CPUSS, 1, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1 },195 { LLCC_VIDSC0, 2, 512, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },196 { LLCC_VIDSC1, 3, 512, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },197 { LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },198 { LLCC_MDMHPGRW, 7, 3072, 1, 1, 0x3ff, 0xc00, 0, 0, 0, 1, 0 },199 { LLCC_MDM, 8, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },200 { LLCC_MODHW, 9, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },201 { LLCC_CMPT, 10, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },202 { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },203 { LLCC_GPU, 12, 5120, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },204 { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1 },205 { LLCC_CMPTDMA, 15, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },206 { LLCC_DISP, 16, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },207 { LLCC_VIDFW, 17, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },208 { LLCC_MDMHPFX, 20, 1024, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },209 { LLCC_MDMPNG, 21, 1024, 0, 1, 0xc, 0x0, 0, 0, 0, 1, 0 },210 { LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },211 { LLCC_NPU, 23, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },212 { LLCC_WLHW, 24, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },213 { LLCC_MODPE, 29, 512, 1, 1, 0xc, 0x0, 0, 0, 0, 1, 0 },214 { LLCC_APTCM, 30, 512, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0 },215 { LLCC_WRCACHE, 31, 128, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0 },216};217 218static const struct llcc_slice_config sc8280xp_data[] = {219 { LLCC_CPUSS, 1, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 },220 { LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },221 { LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 },222 { LLCC_CMPT, 10, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 },223 { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },224 { LLCC_GPU, 12, 4096, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 1 },225 { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },226 { LLCC_DISP, 16, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },227 { LLCC_AUDHW, 22, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },228 { LLCC_ECC, 26, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },229 { LLCC_CVP, 28, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },230 { LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0, 0 },231 { LLCC_WRCACHE, 31, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },232 { LLCC_CVPFW, 17, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },233 { LLCC_CPUSS1, 3, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },234 { LLCC_CPUHWT, 5, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },235};236 237static const struct llcc_slice_config sdm845_data[] = {238 { LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 },239 { LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 },240 { LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 },241 { LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0 },242 { LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },243 { LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },244 { LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0 },245 { LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },246 { LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },247 { LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0 },248 { LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0 },249 { LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1 },250 { LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },251 { LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },252 { LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },253 { LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0 },254 { LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0 },255 { LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0 },256};257 258static const struct llcc_slice_config sm6350_data[] = {259 { LLCC_CPUSS, 1, 768, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 1 },260 { LLCC_MDM, 8, 512, 2, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 },261 { LLCC_GPUHTW, 11, 256, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 },262 { LLCC_GPU, 12, 512, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 },263 { LLCC_MDMPNG, 21, 768, 0, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 },264 { LLCC_NPU, 23, 768, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 },265 { LLCC_MODPE, 29, 64, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 },266};267 268static const struct llcc_slice_config sm7150_data[] = {269 { LLCC_CPUSS, 1, 512, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 1 },270 { LLCC_MDM, 8, 128, 2, 0, 0xF, 0x0, 0, 0, 0, 1, 0 },271 { LLCC_GPUHTW, 11, 256, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0 },272 { LLCC_GPU, 12, 256, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0 },273 { LLCC_NPU, 23, 512, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 0 },274};275 276static const struct llcc_slice_config sm8150_data[] = {277 { LLCC_CPUSS, 1, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 1 },278 { LLCC_VIDSC0, 2, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },279 { LLCC_VIDSC1, 3, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },280 { LLCC_AUDIO, 6, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },281 { LLCC_MDMHPGRW, 7, 3072, 1, 0, 0xFF, 0xF00, 0, 0, 0, 1, 0 },282 { LLCC_MDM, 8, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },283 { LLCC_MODHW, 9, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },284 { LLCC_CMPT, 10, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },285 { LLCC_GPUHTW , 11, 512, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },286 { LLCC_GPU, 12, 2560, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },287 { LLCC_MMUHWT, 13, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1 },288 { LLCC_CMPTDMA, 15, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },289 { LLCC_DISP, 16, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },290 { LLCC_MDMHPFX, 20, 1024, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },291 { LLCC_MDMHPFX, 21, 1024, 0, 1, 0xF, 0x0, 0, 0, 0, 1, 0 },292 { LLCC_AUDHW, 22, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },293 { LLCC_NPU, 23, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },294 { LLCC_WLHW, 24, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },295 { LLCC_MODPE, 29, 256, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0 },296 { LLCC_APTCM, 30, 256, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0 },297 { LLCC_WRCACHE, 31, 128, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0 },298};299 300static const struct llcc_slice_config sm8250_data[] = {301 { LLCC_CPUSS, 1, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 },302 { LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },303 { LLCC_AUDIO, 6, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 },304 { LLCC_CMPT, 10, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 },305 { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },306 { LLCC_GPU, 12, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 1 },307 { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },308 { LLCC_CMPTDMA, 15, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },309 { LLCC_DISP, 16, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },310 { LLCC_VIDFW, 17, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },311 { LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },312 { LLCC_NPU, 23, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },313 { LLCC_WLHW, 24, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },314 { LLCC_CVP, 28, 256, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },315 { LLCC_APTCM, 30, 128, 3, 0, 0x0, 0x3, 1, 0, 0, 1, 0, 0 },316 { LLCC_WRCACHE, 31, 256, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },317};318 319static const struct llcc_slice_config sm8350_data[] = {320 { LLCC_CPUSS, 1, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 1 },321 { LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },322 { LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 },323 { LLCC_MDMHPGRW, 7, 1024, 3, 0, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },324 { LLCC_MODHW, 9, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },325 { LLCC_CMPT, 10, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },326 { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },327 { LLCC_GPU, 12, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 },328 { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },329 { LLCC_DISP, 16, 3072, 2, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },330 { LLCC_MDMPNG, 21, 1024, 0, 1, 0xf, 0x0, 0, 0, 0, 0, 1, 0 },331 { LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },332 { LLCC_CVP, 28, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },333 { LLCC_MODPE, 29, 256, 1, 1, 0xf, 0x0, 0, 0, 0, 0, 1, 0 },334 { LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0x1, 1, 0, 0, 0, 1, 0 },335 { LLCC_WRCACHE, 31, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },336 { LLCC_CVPFW, 17, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },337 { LLCC_CPUSS1, 3, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },338 { LLCC_CPUHWT, 5, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },339};340 341static const struct llcc_slice_config sm8450_data[] = {342 {LLCC_CPUSS, 1, 3072, 1, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 },343 {LLCC_VIDSC0, 2, 512, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },344 {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },345 {LLCC_MDMHPGRW, 7, 1024, 3, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },346 {LLCC_MODHW, 9, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },347 {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },348 {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },349 {LLCC_GPU, 12, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 1, 0 },350 {LLCC_MMUHWT, 13, 768, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 },351 {LLCC_DISP, 16, 4096, 2, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },352 {LLCC_MDMPNG, 21, 1024, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 },353 {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },354 {LLCC_CVP, 28, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },355 {LLCC_MODPE, 29, 64, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 },356 {LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xF0, 1, 0, 0, 1, 0, 0, 0 },357 {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 },358 {LLCC_CVPFW, 17, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },359 {LLCC_CPUSS1, 3, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },360 {LLCC_CAMEXP0, 4, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },361 {LLCC_CPUMTE, 23, 256, 1, 1, 0x0FFF, 0x0, 0, 0, 0, 0, 1, 0, 0 },362 {LLCC_CPUHWT, 5, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 },363 {LLCC_CAMEXP1, 27, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },364 {LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },365};366 367static const struct llcc_slice_config sm8550_data[] = {368 {LLCC_CPUSS, 1, 5120, 1, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, },369 {LLCC_VIDSC0, 2, 512, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },370 {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },371 {LLCC_MDMHPGRW, 25, 1024, 4, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },372 {LLCC_MODHW, 26, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },373 {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },374 {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },375 {LLCC_GPU, 9, 3096, 1, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, },376 {LLCC_MMUHWT, 18, 768, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },377 {LLCC_DISP, 16, 6144, 1, 1, 0xFFFFFF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },378 {LLCC_MDMPNG, 27, 1024, 0, 1, 0xF00000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },379 {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },380 {LLCC_CVP, 8, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },381 {LLCC_MODPE, 29, 64, 1, 1, 0xF00000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, },382 {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },383 {LLCC_CAMEXP0, 4, 256, 4, 1, 0xF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },384 {LLCC_CPUHWT, 5, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },385 {LLCC_CAMEXP1, 7, 3200, 3, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },386 {LLCC_CMPTHCP, 17, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },387 {LLCC_LCPDARE, 30, 128, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, },388 {LLCC_AENPU, 3, 3072, 1, 1, 0xFE01FF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },389 {LLCC_ISLAND1, 12, 1792, 7, 1, 0xFE00, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },390 {LLCC_ISLAND4, 15, 256, 7, 1, 0x10000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },391 {LLCC_CAMEXP2, 19, 3200, 3, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },392 {LLCC_CAMEXP3, 20, 3200, 2, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },393 {LLCC_CAMEXP4, 21, 3200, 2, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },394 {LLCC_DISP_WB, 23, 1024, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },395 {LLCC_DISP_1, 24, 6144, 1, 1, 0xFFFFFF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },396 {LLCC_VIDVSP, 28, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },397};398 399static const struct llcc_slice_config sm8650_data[] = {400 {LLCC_CPUSS, 1, 5120, 1, 0, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},401 {LLCC_VIDSC0, 2, 512, 3, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},402 {LLCC_AUDIO, 6, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},403 {LLCC_MDMHPGRW, 25, 1024, 3, 0, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},404 {LLCC_MODHW, 26, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},405 {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},406 {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},407 {LLCC_GPU, 9, 3096, 1, 0, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},408 {LLCC_MMUHWT, 18, 768, 1, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},409 {LLCC_DISP, 16, 6144, 1, 1, 0xFFFFFF, 0x0, 2, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},410 {LLCC_MDMHPFX, 24, 1024, 3, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},411 {LLCC_MDMPNG, 27, 1024, 0, 1, 0x000000, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},412 {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},413 {LLCC_CVP, 8, 256, 3, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},414 {LLCC_MODPE, 29, 128, 1, 1, 0xF00000, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},415 {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},416 {LLCC_CAMEXP0, 4, 256, 3, 1, 0xF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},417 {LLCC_CAMEXP1, 7, 3200, 3, 1, 0xFFFFF0, 0x0, 2, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},418 {LLCC_CMPTHCP, 17, 256, 3, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},419 {LLCC_LCPDARE, 30, 128, 3, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},420 {LLCC_AENPU, 3, 3072, 1, 1, 0xFFFFFF, 0x0, 2, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},421 {LLCC_ISLAND1, 12, 5888, 7, 1, 0x0, 0x7FFFFF, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},422 {LLCC_DISP_WB, 23, 1024, 3, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},423 {LLCC_VIDVSP, 28, 256, 3, 1, 0xFFFFFF, 0x0, 0, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},424};425 426static const struct llcc_slice_config qdu1000_data_2ch[] = {427 { LLCC_MDMHPGRW, 7, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },428 { LLCC_MODHW, 9, 256, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },429 { LLCC_MDMPNG, 21, 256, 0, 1, 0x3, 0x0, 0, 0, 0, 1, 0, 0, 0 },430 { LLCC_ECC, 26, 512, 3, 1, 0xffc, 0x0, 0, 0, 0, 0, 1, 0, 0 },431 { LLCC_MODPE, 29, 256, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },432 { LLCC_APTCM, 30, 256, 3, 1, 0x0, 0xc, 1, 0, 0, 1, 0, 0, 0 },433 { LLCC_WRCACHE, 31, 128, 1, 1, 0x3, 0x0, 0, 0, 0, 0, 1, 0, 0 },434};435 436static const struct llcc_slice_config qdu1000_data_4ch[] = {437 { LLCC_MDMHPGRW, 7, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },438 { LLCC_MODHW, 9, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },439 { LLCC_MDMPNG, 21, 512, 0, 1, 0x3, 0x0, 0, 0, 0, 1, 0, 0, 0 },440 { LLCC_ECC, 26, 1024, 3, 1, 0xffc, 0x0, 0, 0, 0, 0, 1, 0, 0 },441 { LLCC_MODPE, 29, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },442 { LLCC_APTCM, 30, 512, 3, 1, 0x0, 0xc, 1, 0, 0, 1, 0, 0, 0 },443 { LLCC_WRCACHE, 31, 256, 1, 1, 0x3, 0x0, 0, 0, 0, 0, 1, 0, 0 },444};445 446static const struct llcc_slice_config qdu1000_data_8ch[] = {447 { LLCC_MDMHPGRW, 7, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },448 { LLCC_MODHW, 9, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },449 { LLCC_MDMPNG, 21, 1024, 0, 1, 0x3, 0x0, 0, 0, 0, 1, 0, 0, 0 },450 { LLCC_ECC, 26, 2048, 3, 1, 0xffc, 0x0, 0, 0, 0, 0, 1, 0, 0 },451 { LLCC_MODPE, 29, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0, 0 },452 { LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xc, 1, 0, 0, 1, 0, 0, 0 },453 { LLCC_WRCACHE, 31, 512, 1, 1, 0x3, 0x0, 0, 0, 0, 0, 1, 0, 0 },454};455 456static const struct llcc_slice_config x1e80100_data[] = {457 {LLCC_CPUSS, 1, 6144, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},458 {LLCC_VIDSC0, 2, 512, 4, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},459 {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},460 {LLCC_CMPT, 10, 6144, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},461 {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},462 {LLCC_GPU, 9, 4608, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},463 {LLCC_MMUHWT, 18, 512, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},464 {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},465 {LLCC_CVP, 8, 512, 4, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},466 {LLCC_WRCACHE, 31, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},467 {LLCC_CAMEXP0, 4, 256, 4, 1, 0x3, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},468 {LLCC_CAMEXP1, 7, 3072, 3, 1, 0xFFC, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},469 {LLCC_LCPDARE, 30, 512, 3, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},470 {LLCC_AENPU, 3, 3072, 1, 1, 0xFFF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},471 {LLCC_ISLAND1, 12, 2048, 7, 1, 0x0, 0xF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},472 {LLCC_CAMEXP2, 19, 3072, 3, 1, 0xFFC, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},473 {LLCC_CAMEXP3, 20, 3072, 2, 1, 0xFFC, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},474 {LLCC_CAMEXP4, 21, 3072, 2, 1, 0xFFC, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},475};476 477static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = {478 .trp_ecc_error_status0 = 0x20344,479 .trp_ecc_error_status1 = 0x20348,480 .trp_ecc_sb_err_syn0 = 0x2304c,481 .trp_ecc_db_err_syn0 = 0x20370,482 .trp_ecc_error_cntr_clear = 0x20440,483 .trp_interrupt_0_status = 0x20480,484 .trp_interrupt_0_clear = 0x20484,485 .trp_interrupt_0_enable = 0x20488,486 487 /* LLCC Common registers */488 .cmn_status0 = 0x3000c,489 .cmn_interrupt_0_enable = 0x3001c,490 .cmn_interrupt_2_enable = 0x3003c,491 492 /* LLCC DRP registers */493 .drp_ecc_error_cfg = 0x40000,494 .drp_ecc_error_cntr_clear = 0x40004,495 .drp_interrupt_status = 0x41000,496 .drp_interrupt_clear = 0x41008,497 .drp_interrupt_enable = 0x4100c,498 .drp_ecc_error_status0 = 0x42044,499 .drp_ecc_error_status1 = 0x42048,500 .drp_ecc_sb_err_syn0 = 0x4204c,501 .drp_ecc_db_err_syn0 = 0x42070,502};503 504static const struct llcc_edac_reg_offset llcc_v2_1_edac_reg_offset = {505 .trp_ecc_error_status0 = 0x20344,506 .trp_ecc_error_status1 = 0x20348,507 .trp_ecc_sb_err_syn0 = 0x2034c,508 .trp_ecc_db_err_syn0 = 0x20370,509 .trp_ecc_error_cntr_clear = 0x20440,510 .trp_interrupt_0_status = 0x20480,511 .trp_interrupt_0_clear = 0x20484,512 .trp_interrupt_0_enable = 0x20488,513 514 /* LLCC Common registers */515 .cmn_status0 = 0x3400c,516 .cmn_interrupt_0_enable = 0x3401c,517 .cmn_interrupt_2_enable = 0x3403c,518 519 /* LLCC DRP registers */520 .drp_ecc_error_cfg = 0x50000,521 .drp_ecc_error_cntr_clear = 0x50004,522 .drp_interrupt_status = 0x50020,523 .drp_interrupt_clear = 0x50028,524 .drp_interrupt_enable = 0x5002c,525 .drp_ecc_error_status0 = 0x520f4,526 .drp_ecc_error_status1 = 0x520f8,527 .drp_ecc_sb_err_syn0 = 0x520fc,528 .drp_ecc_db_err_syn0 = 0x52120,529};530 531/* LLCC register offset starting from v1.0.0 */532static const u32 llcc_v1_reg_offset[] = {533 [LLCC_COMMON_HW_INFO] = 0x00030000,534 [LLCC_COMMON_STATUS0] = 0x0003000c,535};536 537/* LLCC register offset starting from v2.0.1 */538static const u32 llcc_v2_1_reg_offset[] = {539 [LLCC_COMMON_HW_INFO] = 0x00034000,540 [LLCC_COMMON_STATUS0] = 0x0003400c,541};542 543static const struct qcom_llcc_config qdu1000_cfg[] = {544 {545 .sct_data = qdu1000_data_8ch,546 .size = ARRAY_SIZE(qdu1000_data_8ch),547 .need_llcc_cfg = true,548 .reg_offset = llcc_v2_1_reg_offset,549 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,550 },551 {552 .sct_data = qdu1000_data_4ch,553 .size = ARRAY_SIZE(qdu1000_data_4ch),554 .need_llcc_cfg = true,555 .reg_offset = llcc_v2_1_reg_offset,556 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,557 },558 {559 .sct_data = qdu1000_data_4ch,560 .size = ARRAY_SIZE(qdu1000_data_4ch),561 .need_llcc_cfg = true,562 .reg_offset = llcc_v2_1_reg_offset,563 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,564 },565 {566 .sct_data = qdu1000_data_2ch,567 .size = ARRAY_SIZE(qdu1000_data_2ch),568 .need_llcc_cfg = true,569 .reg_offset = llcc_v2_1_reg_offset,570 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,571 },572};573 574static const struct qcom_llcc_config sa8775p_cfg[] = {575 {576 .sct_data = sa8775p_data,577 .size = ARRAY_SIZE(sa8775p_data),578 .need_llcc_cfg = true,579 .reg_offset = llcc_v2_1_reg_offset,580 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,581 },582};583 584static const struct qcom_llcc_config sc7180_cfg[] = {585 {586 .sct_data = sc7180_data,587 .size = ARRAY_SIZE(sc7180_data),588 .need_llcc_cfg = true,589 .reg_offset = llcc_v1_reg_offset,590 .edac_reg_offset = &llcc_v1_edac_reg_offset,591 },592};593 594static const struct qcom_llcc_config sc7280_cfg[] = {595 {596 .sct_data = sc7280_data,597 .size = ARRAY_SIZE(sc7280_data),598 .need_llcc_cfg = true,599 .reg_offset = llcc_v1_reg_offset,600 .edac_reg_offset = &llcc_v1_edac_reg_offset,601 },602};603 604static const struct qcom_llcc_config sc8180x_cfg[] = {605 {606 .sct_data = sc8180x_data,607 .size = ARRAY_SIZE(sc8180x_data),608 .need_llcc_cfg = true,609 .reg_offset = llcc_v1_reg_offset,610 .edac_reg_offset = &llcc_v1_edac_reg_offset,611 },612};613 614static const struct qcom_llcc_config sc8280xp_cfg[] = {615 {616 .sct_data = sc8280xp_data,617 .size = ARRAY_SIZE(sc8280xp_data),618 .need_llcc_cfg = true,619 .reg_offset = llcc_v1_reg_offset,620 .edac_reg_offset = &llcc_v1_edac_reg_offset,621 },622};623 624static const struct qcom_llcc_config sdm845_cfg[] = {625 {626 .sct_data = sdm845_data,627 .size = ARRAY_SIZE(sdm845_data),628 .need_llcc_cfg = false,629 .reg_offset = llcc_v1_reg_offset,630 .edac_reg_offset = &llcc_v1_edac_reg_offset,631 .no_edac = true,632 },633};634 635static const struct qcom_llcc_config sm6350_cfg[] = {636 {637 .sct_data = sm6350_data,638 .size = ARRAY_SIZE(sm6350_data),639 .need_llcc_cfg = true,640 .reg_offset = llcc_v1_reg_offset,641 .edac_reg_offset = &llcc_v1_edac_reg_offset,642 },643};644 645static const struct qcom_llcc_config sm7150_cfg[] = {646 {647 .sct_data = sm7150_data,648 .size = ARRAY_SIZE(sm7150_data),649 .need_llcc_cfg = true,650 .reg_offset = llcc_v1_reg_offset,651 .edac_reg_offset = &llcc_v1_edac_reg_offset,652 },653};654 655static const struct qcom_llcc_config sm8150_cfg[] = {656 {657 .sct_data = sm8150_data,658 .size = ARRAY_SIZE(sm8150_data),659 .need_llcc_cfg = true,660 .reg_offset = llcc_v1_reg_offset,661 .edac_reg_offset = &llcc_v1_edac_reg_offset,662 },663};664 665static const struct qcom_llcc_config sm8250_cfg[] = {666 {667 .sct_data = sm8250_data,668 .size = ARRAY_SIZE(sm8250_data),669 .need_llcc_cfg = true,670 .reg_offset = llcc_v1_reg_offset,671 .edac_reg_offset = &llcc_v1_edac_reg_offset,672 },673};674 675static const struct qcom_llcc_config sm8350_cfg[] = {676 {677 .sct_data = sm8350_data,678 .size = ARRAY_SIZE(sm8350_data),679 .need_llcc_cfg = true,680 .reg_offset = llcc_v1_reg_offset,681 .edac_reg_offset = &llcc_v1_edac_reg_offset,682 },683};684 685static const struct qcom_llcc_config sm8450_cfg[] = {686 {687 .sct_data = sm8450_data,688 .size = ARRAY_SIZE(sm8450_data),689 .need_llcc_cfg = true,690 .reg_offset = llcc_v2_1_reg_offset,691 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,692 },693};694 695static const struct qcom_llcc_config sm8550_cfg[] = {696 {697 .sct_data = sm8550_data,698 .size = ARRAY_SIZE(sm8550_data),699 .need_llcc_cfg = true,700 .reg_offset = llcc_v2_1_reg_offset,701 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,702 },703};704 705static const struct qcom_llcc_config sm8650_cfg[] = {706 {707 .sct_data = sm8650_data,708 .size = ARRAY_SIZE(sm8650_data),709 .need_llcc_cfg = true,710 .reg_offset = llcc_v2_1_reg_offset,711 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,712 },713};714 715static const struct qcom_llcc_config x1e80100_cfg[] = {716 {717 .sct_data = x1e80100_data,718 .size = ARRAY_SIZE(x1e80100_data),719 .need_llcc_cfg = true,720 .reg_offset = llcc_v2_1_reg_offset,721 .edac_reg_offset = &llcc_v2_1_edac_reg_offset,722 .irq_configured = true,723 },724};725 726static const struct qcom_sct_config qdu1000_cfgs = {727 .llcc_config = qdu1000_cfg,728 .num_config = ARRAY_SIZE(qdu1000_cfg),729};730 731static const struct qcom_sct_config sa8775p_cfgs = {732 .llcc_config = sa8775p_cfg,733 .num_config = ARRAY_SIZE(sa8775p_cfg),734};735 736static const struct qcom_sct_config sc7180_cfgs = {737 .llcc_config = sc7180_cfg,738 .num_config = ARRAY_SIZE(sc7180_cfg),739};740 741static const struct qcom_sct_config sc7280_cfgs = {742 .llcc_config = sc7280_cfg,743 .num_config = ARRAY_SIZE(sc7280_cfg),744};745 746static const struct qcom_sct_config sc8180x_cfgs = {747 .llcc_config = sc8180x_cfg,748 .num_config = ARRAY_SIZE(sc8180x_cfg),749};750 751static const struct qcom_sct_config sc8280xp_cfgs = {752 .llcc_config = sc8280xp_cfg,753 .num_config = ARRAY_SIZE(sc8280xp_cfg),754};755 756static const struct qcom_sct_config sdm845_cfgs = {757 .llcc_config = sdm845_cfg,758 .num_config = ARRAY_SIZE(sdm845_cfg),759};760 761static const struct qcom_sct_config sm6350_cfgs = {762 .llcc_config = sm6350_cfg,763 .num_config = ARRAY_SIZE(sm6350_cfg),764};765 766static const struct qcom_sct_config sm7150_cfgs = {767 .llcc_config = sm7150_cfg,768 .num_config = ARRAY_SIZE(sm7150_cfg),769};770 771static const struct qcom_sct_config sm8150_cfgs = {772 .llcc_config = sm8150_cfg,773 .num_config = ARRAY_SIZE(sm8150_cfg),774};775 776static const struct qcom_sct_config sm8250_cfgs = {777 .llcc_config = sm8250_cfg,778 .num_config = ARRAY_SIZE(sm8250_cfg),779};780 781static const struct qcom_sct_config sm8350_cfgs = {782 .llcc_config = sm8350_cfg,783 .num_config = ARRAY_SIZE(sm8350_cfg),784};785 786static const struct qcom_sct_config sm8450_cfgs = {787 .llcc_config = sm8450_cfg,788 .num_config = ARRAY_SIZE(sm8450_cfg),789};790 791static const struct qcom_sct_config sm8550_cfgs = {792 .llcc_config = sm8550_cfg,793 .num_config = ARRAY_SIZE(sm8550_cfg),794};795 796static const struct qcom_sct_config sm8650_cfgs = {797 .llcc_config = sm8650_cfg,798 .num_config = ARRAY_SIZE(sm8650_cfg),799};800 801static const struct qcom_sct_config x1e80100_cfgs = {802 .llcc_config = x1e80100_cfg,803 .num_config = ARRAY_SIZE(x1e80100_cfg),804};805 806static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;807 808/**809 * llcc_slice_getd - get llcc slice descriptor810 * @uid: usecase_id for the client811 *812 * A pointer to llcc slice descriptor will be returned on success813 * and error pointer is returned on failure814 */815struct llcc_slice_desc *llcc_slice_getd(u32 uid)816{817 const struct llcc_slice_config *cfg;818 struct llcc_slice_desc *desc;819 u32 sz, count;820 821 if (IS_ERR(drv_data))822 return ERR_CAST(drv_data);823 824 cfg = drv_data->cfg;825 sz = drv_data->cfg_size;826 827 for (count = 0; cfg && count < sz; count++, cfg++)828 if (cfg->usecase_id == uid)829 break;830 831 if (count == sz || !cfg)832 return ERR_PTR(-ENODEV);833 834 desc = kzalloc(sizeof(*desc), GFP_KERNEL);835 if (!desc)836 return ERR_PTR(-ENOMEM);837 838 desc->slice_id = cfg->slice_id;839 desc->slice_size = cfg->max_cap;840 841 return desc;842}843EXPORT_SYMBOL_GPL(llcc_slice_getd);844 845/**846 * llcc_slice_putd - llcc slice descriptor847 * @desc: Pointer to llcc slice descriptor848 */849void llcc_slice_putd(struct llcc_slice_desc *desc)850{851 if (!IS_ERR_OR_NULL(desc))852 kfree(desc);853}854EXPORT_SYMBOL_GPL(llcc_slice_putd);855 856static int llcc_update_act_ctrl(u32 sid,857 u32 act_ctrl_reg_val, u32 status)858{859 struct regmap *regmap;860 u32 act_ctrl_reg;861 u32 act_clear_reg;862 u32 status_reg;863 u32 slice_status;864 int ret;865 866 if (IS_ERR(drv_data))867 return PTR_ERR(drv_data);868 869 act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);870 act_clear_reg = LLCC_TRP_ACT_CLEARn(sid);871 status_reg = LLCC_TRP_STATUSn(sid);872 873 /* Set the ACTIVE trigger */874 act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;875 ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,876 act_ctrl_reg_val);877 if (ret)878 return ret;879 880 /* Clear the ACTIVE trigger */881 act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;882 ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,883 act_ctrl_reg_val);884 if (ret)885 return ret;886 887 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {888 regmap = drv_data->bcast_and_regmap ?: drv_data->bcast_regmap;889 ret = regmap_read_poll_timeout(regmap, status_reg,890 slice_status, (slice_status & ACT_COMPLETE),891 0, LLCC_STATUS_READ_DELAY);892 if (ret)893 return ret;894 }895 896 ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,897 slice_status, !(slice_status & status),898 0, LLCC_STATUS_READ_DELAY);899 if (ret)900 return ret;901 902 if (drv_data->version >= LLCC_VERSION_4_1_0_0)903 ret = regmap_write(drv_data->bcast_regmap, act_clear_reg,904 ACT_CLEAR);905 906 return ret;907}908 909/**910 * llcc_slice_activate - Activate the llcc slice911 * @desc: Pointer to llcc slice descriptor912 *913 * A value of zero will be returned on success and a negative errno will914 * be returned in error cases915 */916int llcc_slice_activate(struct llcc_slice_desc *desc)917{918 int ret;919 u32 act_ctrl_val;920 921 if (IS_ERR(drv_data))922 return PTR_ERR(drv_data);923 924 if (IS_ERR_OR_NULL(desc))925 return -EINVAL;926 927 mutex_lock(&drv_data->lock);928 if (test_bit(desc->slice_id, drv_data->bitmap)) {929 mutex_unlock(&drv_data->lock);930 return 0;931 }932 933 act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT;934 935 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,936 DEACTIVATE);937 if (ret) {938 mutex_unlock(&drv_data->lock);939 return ret;940 }941 942 __set_bit(desc->slice_id, drv_data->bitmap);943 mutex_unlock(&drv_data->lock);944 945 return ret;946}947EXPORT_SYMBOL_GPL(llcc_slice_activate);948 949/**950 * llcc_slice_deactivate - Deactivate the llcc slice951 * @desc: Pointer to llcc slice descriptor952 *953 * A value of zero will be returned on success and a negative errno will954 * be returned in error cases955 */956int llcc_slice_deactivate(struct llcc_slice_desc *desc)957{958 u32 act_ctrl_val;959 int ret;960 961 if (IS_ERR(drv_data))962 return PTR_ERR(drv_data);963 964 if (IS_ERR_OR_NULL(desc))965 return -EINVAL;966 967 mutex_lock(&drv_data->lock);968 if (!test_bit(desc->slice_id, drv_data->bitmap)) {969 mutex_unlock(&drv_data->lock);970 return 0;971 }972 act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT;973 974 ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,975 ACTIVATE);976 if (ret) {977 mutex_unlock(&drv_data->lock);978 return ret;979 }980 981 __clear_bit(desc->slice_id, drv_data->bitmap);982 mutex_unlock(&drv_data->lock);983 984 return ret;985}986EXPORT_SYMBOL_GPL(llcc_slice_deactivate);987 988/**989 * llcc_get_slice_id - return the slice id990 * @desc: Pointer to llcc slice descriptor991 */992int llcc_get_slice_id(struct llcc_slice_desc *desc)993{994 if (IS_ERR_OR_NULL(desc))995 return -EINVAL;996 997 return desc->slice_id;998}999EXPORT_SYMBOL_GPL(llcc_get_slice_id);1000 1001/**1002 * llcc_get_slice_size - return the slice id1003 * @desc: Pointer to llcc slice descriptor1004 */1005size_t llcc_get_slice_size(struct llcc_slice_desc *desc)1006{1007 if (IS_ERR_OR_NULL(desc))1008 return 0;1009 1010 return desc->slice_size;1011}1012EXPORT_SYMBOL_GPL(llcc_get_slice_size);1013 1014static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,1015 const struct qcom_llcc_config *cfg)1016{1017 int ret;1018 u32 attr2_cfg;1019 u32 attr1_cfg;1020 u32 attr0_cfg;1021 u32 attr2_val;1022 u32 attr1_val;1023 u32 attr0_val;1024 u32 max_cap_cacheline;1025 struct llcc_slice_desc desc;1026 1027 attr1_val = config->cache_mode;1028 attr1_val |= config->probe_target_ways << ATTR1_PROBE_TARGET_WAYS_SHIFT;1029 attr1_val |= config->fixed_size << ATTR1_FIXED_SIZE_SHIFT;1030 attr1_val |= config->priority << ATTR1_PRIORITY_SHIFT;1031 1032 max_cap_cacheline = MAX_CAP_TO_BYTES(config->max_cap);1033 1034 /*1035 * LLCC instances can vary for each target.1036 * The SW writes to broadcast register which gets propagated1037 * to each llcc instance (llcc0,.. llccN).1038 * Since the size of the memory is divided equally amongst the1039 * llcc instances, we need to configure the max cap accordingly.1040 */1041 max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;1042 max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;1043 attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;1044 1045 attr1_cfg = LLCC_TRP_ATTR1_CFGn(config->slice_id);1046 1047 ret = regmap_write(drv_data->bcast_regmap, attr1_cfg, attr1_val);1048 if (ret)1049 return ret;1050 1051 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {1052 attr2_cfg = LLCC_TRP_ATTR2_CFGn(config->slice_id);1053 attr0_val = config->res_ways;1054 attr2_val = config->bonus_ways;1055 } else {1056 attr0_val = config->res_ways & ATTR0_RES_WAYS_MASK;1057 attr0_val |= config->bonus_ways << ATTR0_BONUS_WAYS_SHIFT;1058 }1059 1060 attr0_cfg = LLCC_TRP_ATTR0_CFGn(config->slice_id);1061 1062 ret = regmap_write(drv_data->bcast_regmap, attr0_cfg, attr0_val);1063 if (ret)1064 return ret;1065 1066 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {1067 ret = regmap_write(drv_data->bcast_regmap, attr2_cfg, attr2_val);1068 if (ret)1069 return ret;1070 }1071 1072 if (cfg->need_llcc_cfg) {1073 u32 disable_cap_alloc, retain_pc;1074 1075 disable_cap_alloc = config->dis_cap_alloc << config->slice_id;1076 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_SCID_DIS_CAP_ALLOC,1077 BIT(config->slice_id), disable_cap_alloc);1078 if (ret)1079 return ret;1080 1081 if (drv_data->version < LLCC_VERSION_4_1_0_0) {1082 retain_pc = config->retain_on_pc << config->slice_id;1083 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_PCB_ACT,1084 BIT(config->slice_id), retain_pc);1085 if (ret)1086 return ret;1087 }1088 }1089 1090 if (drv_data->version >= LLCC_VERSION_2_0_0_0) {1091 u32 wren;1092 1093 wren = config->write_scid_en << config->slice_id;1094 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_EN,1095 BIT(config->slice_id), wren);1096 if (ret)1097 return ret;1098 }1099 1100 if (drv_data->version >= LLCC_VERSION_2_1_0_0) {1101 u32 wr_cache_en;1102 1103 wr_cache_en = config->write_scid_cacheable_en << config->slice_id;1104 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_CACHEABLE_EN,1105 BIT(config->slice_id), wr_cache_en);1106 if (ret)1107 return ret;1108 }1109 1110 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {1111 u32 stale_en;1112 u32 stale_cap_en;1113 u32 mru_uncap_en;1114 u32 mru_rollover;1115 u32 alloc_oneway_en;1116 u32 ovcap_en;1117 u32 ovcap_prio;1118 u32 vict_prio;1119 1120 stale_en = config->stale_en << config->slice_id;1121 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG1,1122 BIT(config->slice_id), stale_en);1123 if (ret)1124 return ret;1125 1126 stale_cap_en = config->stale_cap_en << config->slice_id;1127 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG2,1128 BIT(config->slice_id), stale_cap_en);1129 if (ret)1130 return ret;1131 1132 mru_uncap_en = config->mru_uncap_en << config->slice_id;1133 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG3,1134 BIT(config->slice_id), mru_uncap_en);1135 if (ret)1136 return ret;1137 1138 mru_rollover = config->mru_rollover << config->slice_id;1139 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG4,1140 BIT(config->slice_id), mru_rollover);1141 if (ret)1142 return ret;1143 1144 alloc_oneway_en = config->alloc_oneway_en << config->slice_id;1145 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG5,1146 BIT(config->slice_id), alloc_oneway_en);1147 if (ret)1148 return ret;1149 1150 ovcap_en = config->ovcap_en << config->slice_id;1151 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG6,1152 BIT(config->slice_id), ovcap_en);1153 if (ret)1154 return ret;1155 1156 ovcap_prio = config->ovcap_prio << config->slice_id;1157 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG7,1158 BIT(config->slice_id), ovcap_prio);1159 if (ret)1160 return ret;1161 1162 vict_prio = config->vict_prio << config->slice_id;1163 ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG8,1164 BIT(config->slice_id), vict_prio);1165 if (ret)1166 return ret;1167 }1168 1169 if (config->activate_on_init) {1170 desc.slice_id = config->slice_id;1171 ret = llcc_slice_activate(&desc);1172 }1173 1174 return ret;1175}1176 1177static int qcom_llcc_cfg_program(struct platform_device *pdev,1178 const struct qcom_llcc_config *cfg)1179{1180 int i;1181 u32 sz;1182 int ret = 0;1183 const struct llcc_slice_config *llcc_table;1184 1185 sz = drv_data->cfg_size;1186 llcc_table = drv_data->cfg;1187 1188 for (i = 0; i < sz; i++) {1189 ret = _qcom_llcc_cfg_program(&llcc_table[i], cfg);1190 if (ret)1191 return ret;1192 }1193 1194 return ret;1195}1196 1197static int qcom_llcc_get_cfg_index(struct platform_device *pdev, u8 *cfg_index, int num_config)1198{1199 int ret;1200 1201 ret = nvmem_cell_read_u8(&pdev->dev, "multi-chan-ddr", cfg_index);1202 if (ret == -ENOENT || ret == -EOPNOTSUPP) {1203 if (num_config > 1)1204 return -EINVAL;1205 *cfg_index = 0;1206 return 0;1207 }1208 1209 if (!ret && *cfg_index >= num_config)1210 ret = -EINVAL;1211 1212 return ret;1213}1214 1215static void qcom_llcc_remove(struct platform_device *pdev)1216{1217 /* Set the global pointer to a error code to avoid referencing it */1218 drv_data = ERR_PTR(-ENODEV);1219}1220 1221static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index,1222 const char *name)1223{1224 void __iomem *base;1225 struct regmap_config llcc_regmap_config = {1226 .reg_bits = 32,1227 .reg_stride = 4,1228 .val_bits = 32,1229 .fast_io = true,1230 };1231 1232 base = devm_platform_ioremap_resource(pdev, index);1233 if (IS_ERR(base))1234 return ERR_CAST(base);1235 1236 llcc_regmap_config.name = name;1237 return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config);1238}1239 1240static int qcom_llcc_probe(struct platform_device *pdev)1241{1242 u32 num_banks;1243 struct device *dev = &pdev->dev;1244 int ret, i;1245 struct platform_device *llcc_edac;1246 const struct qcom_sct_config *cfgs;1247 const struct qcom_llcc_config *cfg;1248 const struct llcc_slice_config *llcc_cfg;1249 u32 sz;1250 u8 cfg_index;1251 u32 version;1252 struct regmap *regmap;1253 1254 if (!IS_ERR(drv_data))1255 return -EBUSY;1256 1257 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);1258 if (!drv_data) {1259 ret = -ENOMEM;1260 goto err;1261 }1262 1263 /* Initialize the first LLCC bank regmap */1264 regmap = qcom_llcc_init_mmio(pdev, 0, "llcc0_base");1265 if (IS_ERR(regmap)) {1266 ret = PTR_ERR(regmap);1267 goto err;1268 }1269 1270 cfgs = of_device_get_match_data(&pdev->dev);1271 if (!cfgs) {1272 ret = -EINVAL;1273 goto err;1274 }1275 ret = qcom_llcc_get_cfg_index(pdev, &cfg_index, cfgs->num_config);1276 if (ret)1277 goto err;1278 cfg = &cfgs->llcc_config[cfg_index];1279 1280 ret = regmap_read(regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], &num_banks);1281 if (ret)1282 goto err;1283 1284 num_banks &= LLCC_LB_CNT_MASK;1285 num_banks >>= LLCC_LB_CNT_SHIFT;1286 drv_data->num_banks = num_banks;1287 1288 drv_data->regmaps = devm_kcalloc(dev, num_banks, sizeof(*drv_data->regmaps), GFP_KERNEL);1289 if (!drv_data->regmaps) {1290 ret = -ENOMEM;1291 goto err;1292 }1293 1294 drv_data->regmaps[0] = regmap;1295 1296 /* Initialize rest of LLCC bank regmaps */1297 for (i = 1; i < num_banks; i++) {1298 char *base __free(kfree) = kasprintf(GFP_KERNEL, "llcc%d_base", i);1299 1300 drv_data->regmaps[i] = qcom_llcc_init_mmio(pdev, i, base);1301 if (IS_ERR(drv_data->regmaps[i])) {1302 ret = PTR_ERR(drv_data->regmaps[i]);1303 goto err;1304 }1305 }1306 1307 drv_data->bcast_regmap = qcom_llcc_init_mmio(pdev, i, "llcc_broadcast_base");1308 if (IS_ERR(drv_data->bcast_regmap)) {1309 ret = PTR_ERR(drv_data->bcast_regmap);1310 goto err;1311 }1312 1313 /* Extract version of the IP */1314 ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO],1315 &version);1316 if (ret)1317 goto err;1318 1319 drv_data->version = version;1320 1321 /* Applicable only when drv_data->version >= 4.1 */1322 if (drv_data->version >= LLCC_VERSION_4_1_0_0) {1323 drv_data->bcast_and_regmap = qcom_llcc_init_mmio(pdev, i + 1, "llcc_broadcast_and_base");1324 if (IS_ERR(drv_data->bcast_and_regmap)) {1325 ret = PTR_ERR(drv_data->bcast_and_regmap);1326 if (ret == -EINVAL)1327 drv_data->bcast_and_regmap = NULL;1328 else1329 goto err;1330 }1331 }1332 1333 llcc_cfg = cfg->sct_data;1334 sz = cfg->size;1335 1336 for (i = 0; i < sz; i++)1337 if (llcc_cfg[i].slice_id > drv_data->max_slices)1338 drv_data->max_slices = llcc_cfg[i].slice_id;1339 1340 drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices,1341 GFP_KERNEL);1342 if (!drv_data->bitmap) {1343 ret = -ENOMEM;1344 goto err;1345 }1346 1347 drv_data->cfg = llcc_cfg;1348 drv_data->cfg_size = sz;1349 drv_data->edac_reg_offset = cfg->edac_reg_offset;1350 drv_data->ecc_irq_configured = cfg->irq_configured;1351 mutex_init(&drv_data->lock);1352 platform_set_drvdata(pdev, drv_data);1353 1354 ret = qcom_llcc_cfg_program(pdev, cfg);1355 if (ret)1356 goto err;1357 1358 drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);1359 1360 /*1361 * On some platforms, the access to EDAC registers will be locked by1362 * the bootloader. So probing the EDAC driver will result in a crash.1363 * Hence, disable the creation of EDAC platform device for the1364 * problematic platforms.1365 */1366 if (!cfg->no_edac) {1367 llcc_edac = platform_device_register_data(&pdev->dev,1368 "qcom_llcc_edac", -1, drv_data,1369 sizeof(*drv_data));1370 if (IS_ERR(llcc_edac))1371 dev_err(dev, "Failed to register llcc edac driver\n");1372 }1373 1374 return 0;1375err:1376 drv_data = ERR_PTR(-ENODEV);1377 return ret;1378}1379 1380static const struct of_device_id qcom_llcc_of_match[] = {1381 { .compatible = "qcom,qdu1000-llcc", .data = &qdu1000_cfgs},1382 { .compatible = "qcom,sa8775p-llcc", .data = &sa8775p_cfgs },1383 { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfgs },1384 { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfgs },1385 { .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfgs },1386 { .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfgs },1387 { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfgs },1388 { .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfgs },1389 { .compatible = "qcom,sm7150-llcc", .data = &sm7150_cfgs },1390 { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfgs },1391 { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfgs },1392 { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfgs },1393 { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfgs },1394 { .compatible = "qcom,sm8550-llcc", .data = &sm8550_cfgs },1395 { .compatible = "qcom,sm8650-llcc", .data = &sm8650_cfgs },1396 { .compatible = "qcom,x1e80100-llcc", .data = &x1e80100_cfgs },1397 { }1398};1399MODULE_DEVICE_TABLE(of, qcom_llcc_of_match);1400 1401static struct platform_driver qcom_llcc_driver = {1402 .driver = {1403 .name = "qcom-llcc",1404 .of_match_table = qcom_llcc_of_match,1405 },1406 .probe = qcom_llcc_probe,1407 .remove_new = qcom_llcc_remove,1408};1409module_platform_driver(qcom_llcc_driver);1410 1411MODULE_DESCRIPTION("Qualcomm Last Level Cache Controller");1412MODULE_LICENSE("GPL v2");1413