162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/bitfield.h> 862306a36Sopenharmony_ci#include <linux/bitmap.h> 962306a36Sopenharmony_ci#include <linux/bitops.h> 1062306a36Sopenharmony_ci#include <linux/device.h> 1162306a36Sopenharmony_ci#include <linux/io.h> 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/mutex.h> 1562306a36Sopenharmony_ci#include <linux/of.h> 1662306a36Sopenharmony_ci#include <linux/regmap.h> 1762306a36Sopenharmony_ci#include <linux/sizes.h> 1862306a36Sopenharmony_ci#include <linux/slab.h> 1962306a36Sopenharmony_ci#include <linux/soc/qcom/llcc-qcom.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define ACTIVATE BIT(0) 2262306a36Sopenharmony_ci#define DEACTIVATE BIT(1) 2362306a36Sopenharmony_ci#define ACT_CLEAR BIT(0) 2462306a36Sopenharmony_ci#define ACT_COMPLETE BIT(4) 2562306a36Sopenharmony_ci#define ACT_CTRL_OPCODE_ACTIVATE BIT(0) 2662306a36Sopenharmony_ci#define ACT_CTRL_OPCODE_DEACTIVATE BIT(1) 2762306a36Sopenharmony_ci#define ACT_CTRL_ACT_TRIG BIT(0) 2862306a36Sopenharmony_ci#define ACT_CTRL_OPCODE_SHIFT 0x01 2962306a36Sopenharmony_ci#define ATTR1_PROBE_TARGET_WAYS_SHIFT 0x02 3062306a36Sopenharmony_ci#define ATTR1_FIXED_SIZE_SHIFT 0x03 3162306a36Sopenharmony_ci#define ATTR1_PRIORITY_SHIFT 0x04 3262306a36Sopenharmony_ci#define ATTR1_MAX_CAP_SHIFT 0x10 3362306a36Sopenharmony_ci#define ATTR0_RES_WAYS_MASK GENMASK(15, 0) 3462306a36Sopenharmony_ci#define ATTR0_BONUS_WAYS_MASK GENMASK(31, 16) 3562306a36Sopenharmony_ci#define ATTR0_BONUS_WAYS_SHIFT 0x10 3662306a36Sopenharmony_ci#define LLCC_STATUS_READ_DELAY 100 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#define CACHE_LINE_SIZE_SHIFT 6 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define LLCC_LB_CNT_MASK GENMASK(31, 28) 4162306a36Sopenharmony_ci#define LLCC_LB_CNT_SHIFT 28 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define MAX_CAP_TO_BYTES(n) (n * SZ_1K) 4462306a36Sopenharmony_ci#define LLCC_TRP_ACT_CTRLn(n) (n * SZ_4K) 4562306a36Sopenharmony_ci#define LLCC_TRP_ACT_CLEARn(n) (8 + n * SZ_4K) 4662306a36Sopenharmony_ci#define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K) 4762306a36Sopenharmony_ci#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n) 4862306a36Sopenharmony_ci#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n) 4962306a36Sopenharmony_ci#define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_4 * n) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00 5262306a36Sopenharmony_ci#define LLCC_TRP_PCB_ACT 0x21f04 5362306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG1 0x21f0c 5462306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG2 0x21f10 5562306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG3 0x21f14 5662306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG4 0x21f18 5762306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG5 0x21f1c 5862306a36Sopenharmony_ci#define LLCC_TRP_WRSC_EN 0x21f20 5962306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG6 0x21f24 6062306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG7 0x21f28 6162306a36Sopenharmony_ci#define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c 6262306a36Sopenharmony_ci#define LLCC_TRP_ALGO_CFG8 0x21f30 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci#define LLCC_VERSION_2_0_0_0 0x02000000 6562306a36Sopenharmony_ci#define LLCC_VERSION_2_1_0_0 0x02010000 6662306a36Sopenharmony_ci#define LLCC_VERSION_4_1_0_0 0x04010000 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/** 6962306a36Sopenharmony_ci * struct llcc_slice_config - Data associated with the llcc slice 7062306a36Sopenharmony_ci * @usecase_id: Unique id for the client's use case 7162306a36Sopenharmony_ci * @slice_id: llcc slice id for each client 7262306a36Sopenharmony_ci * @max_cap: The maximum capacity of the cache slice provided in KB 7362306a36Sopenharmony_ci * @priority: Priority of the client used to select victim line for replacement 7462306a36Sopenharmony_ci * @fixed_size: Boolean indicating if the slice has a fixed capacity 7562306a36Sopenharmony_ci * @bonus_ways: Bonus ways are additional ways to be used for any slice, 7662306a36Sopenharmony_ci * if client ends up using more than reserved cache ways. Bonus 7762306a36Sopenharmony_ci * ways are allocated only if they are not reserved for some 7862306a36Sopenharmony_ci * other client. 7962306a36Sopenharmony_ci * @res_ways: Reserved ways for the cache slice, the reserved ways cannot 8062306a36Sopenharmony_ci * be used by any other client than the one its assigned to. 8162306a36Sopenharmony_ci * @cache_mode: Each slice operates as a cache, this controls the mode of the 8262306a36Sopenharmony_ci * slice: normal or TCM(Tightly Coupled Memory) 8362306a36Sopenharmony_ci * @probe_target_ways: Determines what ways to probe for access hit. When 8462306a36Sopenharmony_ci * configured to 1 only bonus and reserved ways are probed. 8562306a36Sopenharmony_ci * When configured to 0 all ways in llcc are probed. 8662306a36Sopenharmony_ci * @dis_cap_alloc: Disable capacity based allocation for a client 8762306a36Sopenharmony_ci * @retain_on_pc: If this bit is set and client has maintained active vote 8862306a36Sopenharmony_ci * then the ways assigned to this client are not flushed on power 8962306a36Sopenharmony_ci * collapse. 9062306a36Sopenharmony_ci * @activate_on_init: Activate the slice immediately after it is programmed 9162306a36Sopenharmony_ci * @write_scid_en: Bit enables write cache support for a given scid. 9262306a36Sopenharmony_ci * @write_scid_cacheable_en: Enables write cache cacheable support for a 9362306a36Sopenharmony_ci * given scid (not supported on v2 or older hardware). 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_cistruct llcc_slice_config { 9662306a36Sopenharmony_ci u32 usecase_id; 9762306a36Sopenharmony_ci u32 slice_id; 9862306a36Sopenharmony_ci u32 max_cap; 9962306a36Sopenharmony_ci u32 priority; 10062306a36Sopenharmony_ci bool fixed_size; 10162306a36Sopenharmony_ci u32 bonus_ways; 10262306a36Sopenharmony_ci u32 res_ways; 10362306a36Sopenharmony_ci u32 cache_mode; 10462306a36Sopenharmony_ci u32 probe_target_ways; 10562306a36Sopenharmony_ci bool dis_cap_alloc; 10662306a36Sopenharmony_ci bool retain_on_pc; 10762306a36Sopenharmony_ci bool activate_on_init; 10862306a36Sopenharmony_ci bool write_scid_en; 10962306a36Sopenharmony_ci bool write_scid_cacheable_en; 11062306a36Sopenharmony_ci bool stale_en; 11162306a36Sopenharmony_ci bool stale_cap_en; 11262306a36Sopenharmony_ci bool mru_uncap_en; 11362306a36Sopenharmony_ci bool mru_rollover; 11462306a36Sopenharmony_ci bool alloc_oneway_en; 11562306a36Sopenharmony_ci bool ovcap_en; 11662306a36Sopenharmony_ci bool ovcap_prio; 11762306a36Sopenharmony_ci bool vict_prio; 11862306a36Sopenharmony_ci}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistruct qcom_llcc_config { 12162306a36Sopenharmony_ci const struct llcc_slice_config *sct_data; 12262306a36Sopenharmony_ci const u32 *reg_offset; 12362306a36Sopenharmony_ci const struct llcc_edac_reg_offset *edac_reg_offset; 12462306a36Sopenharmony_ci int size; 12562306a36Sopenharmony_ci bool need_llcc_cfg; 12662306a36Sopenharmony_ci bool no_edac; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cienum llcc_reg_offset { 13062306a36Sopenharmony_ci LLCC_COMMON_HW_INFO, 13162306a36Sopenharmony_ci LLCC_COMMON_STATUS0, 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic const struct llcc_slice_config sc7180_data[] = { 13562306a36Sopenharmony_ci { LLCC_CPUSS, 1, 256, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 1 }, 13662306a36Sopenharmony_ci { LLCC_MDM, 8, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 }, 13762306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 }, 13862306a36Sopenharmony_ci { LLCC_GPU, 12, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 }, 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic const struct llcc_slice_config sc7280_data[] = { 14262306a36Sopenharmony_ci { LLCC_CPUSS, 1, 768, 1, 0, 0x3f, 0x0, 0, 0, 0, 1, 1, 0}, 14362306a36Sopenharmony_ci { LLCC_MDMHPGRW, 7, 512, 2, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, 14462306a36Sopenharmony_ci { LLCC_CMPT, 10, 768, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, 14562306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, 14662306a36Sopenharmony_ci { LLCC_GPU, 12, 512, 1, 0, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, 14762306a36Sopenharmony_ci { LLCC_MMUHWT, 13, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 0, 1, 0}, 14862306a36Sopenharmony_ci { LLCC_MDMPNG, 21, 768, 0, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, 14962306a36Sopenharmony_ci { LLCC_WLHW, 24, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, 15062306a36Sopenharmony_ci { LLCC_MODPE, 29, 64, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, 15162306a36Sopenharmony_ci}; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic const struct llcc_slice_config sc8180x_data[] = { 15462306a36Sopenharmony_ci { LLCC_CPUSS, 1, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1 }, 15562306a36Sopenharmony_ci { LLCC_VIDSC0, 2, 512, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 15662306a36Sopenharmony_ci { LLCC_VIDSC1, 3, 512, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 15762306a36Sopenharmony_ci { LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 15862306a36Sopenharmony_ci { LLCC_MDMHPGRW, 7, 3072, 1, 1, 0x3ff, 0xc00, 0, 0, 0, 1, 0 }, 15962306a36Sopenharmony_ci { LLCC_MDM, 8, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16062306a36Sopenharmony_ci { LLCC_MODHW, 9, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16162306a36Sopenharmony_ci { LLCC_CMPT, 10, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16262306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16362306a36Sopenharmony_ci { LLCC_GPU, 12, 5120, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16462306a36Sopenharmony_ci { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1 }, 16562306a36Sopenharmony_ci { LLCC_CMPTDMA, 15, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16662306a36Sopenharmony_ci { LLCC_DISP, 16, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16762306a36Sopenharmony_ci { LLCC_VIDFW, 17, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16862306a36Sopenharmony_ci { LLCC_MDMHPFX, 20, 1024, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 16962306a36Sopenharmony_ci { LLCC_MDMPNG, 21, 1024, 0, 1, 0xc, 0x0, 0, 0, 0, 1, 0 }, 17062306a36Sopenharmony_ci { LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 17162306a36Sopenharmony_ci { LLCC_NPU, 23, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 17262306a36Sopenharmony_ci { LLCC_WLHW, 24, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 }, 17362306a36Sopenharmony_ci { LLCC_MODPE, 29, 512, 1, 1, 0xc, 0x0, 0, 0, 0, 1, 0 }, 17462306a36Sopenharmony_ci { LLCC_APTCM, 30, 512, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0 }, 17562306a36Sopenharmony_ci { LLCC_WRCACHE, 31, 128, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0 }, 17662306a36Sopenharmony_ci}; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic const struct llcc_slice_config sc8280xp_data[] = { 17962306a36Sopenharmony_ci { LLCC_CPUSS, 1, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 }, 18062306a36Sopenharmony_ci { LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 18162306a36Sopenharmony_ci { LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 }, 18262306a36Sopenharmony_ci { LLCC_CMPT, 10, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 }, 18362306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 18462306a36Sopenharmony_ci { LLCC_GPU, 12, 4096, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 1 }, 18562306a36Sopenharmony_ci { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 18662306a36Sopenharmony_ci { LLCC_DISP, 16, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 18762306a36Sopenharmony_ci { LLCC_AUDHW, 22, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 18862306a36Sopenharmony_ci { LLCC_DRE, 26, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 18962306a36Sopenharmony_ci { LLCC_CVP, 28, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 19062306a36Sopenharmony_ci { LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0, 0 }, 19162306a36Sopenharmony_ci { LLCC_WRCACHE, 31, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 19262306a36Sopenharmony_ci { LLCC_CVPFW, 17, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 19362306a36Sopenharmony_ci { LLCC_CPUSS1, 3, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 19462306a36Sopenharmony_ci { LLCC_CPUHWT, 5, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 19562306a36Sopenharmony_ci}; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic const struct llcc_slice_config sdm845_data[] = { 19862306a36Sopenharmony_ci { LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 }, 19962306a36Sopenharmony_ci { LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 }, 20062306a36Sopenharmony_ci { LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 }, 20162306a36Sopenharmony_ci { LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0 }, 20262306a36Sopenharmony_ci { LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 20362306a36Sopenharmony_ci { LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 20462306a36Sopenharmony_ci { LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0 }, 20562306a36Sopenharmony_ci { LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 20662306a36Sopenharmony_ci { LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 20762306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0 }, 20862306a36Sopenharmony_ci { LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0 }, 20962306a36Sopenharmony_ci { LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1 }, 21062306a36Sopenharmony_ci { LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 21162306a36Sopenharmony_ci { LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 21262306a36Sopenharmony_ci { LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 21362306a36Sopenharmony_ci { LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0 }, 21462306a36Sopenharmony_ci { LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0 }, 21562306a36Sopenharmony_ci { LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0 }, 21662306a36Sopenharmony_ci}; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cistatic const struct llcc_slice_config sm6350_data[] = { 21962306a36Sopenharmony_ci { LLCC_CPUSS, 1, 768, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 1 }, 22062306a36Sopenharmony_ci { LLCC_MDM, 8, 512, 2, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 }, 22162306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 256, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 }, 22262306a36Sopenharmony_ci { LLCC_GPU, 12, 512, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 }, 22362306a36Sopenharmony_ci { LLCC_MDMPNG, 21, 768, 0, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 }, 22462306a36Sopenharmony_ci { LLCC_NPU, 23, 768, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 }, 22562306a36Sopenharmony_ci { LLCC_MODPE, 29, 64, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1, 0 }, 22662306a36Sopenharmony_ci}; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic const struct llcc_slice_config sm7150_data[] = { 22962306a36Sopenharmony_ci { LLCC_CPUSS, 1, 512, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 1 }, 23062306a36Sopenharmony_ci { LLCC_MDM, 8, 128, 2, 0, 0xF, 0x0, 0, 0, 0, 1, 0 }, 23162306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 256, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0 }, 23262306a36Sopenharmony_ci { LLCC_GPU, 12, 256, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0 }, 23362306a36Sopenharmony_ci { LLCC_NPU, 23, 512, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 0 }, 23462306a36Sopenharmony_ci}; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic const struct llcc_slice_config sm8150_data[] = { 23762306a36Sopenharmony_ci { LLCC_CPUSS, 1, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 1 }, 23862306a36Sopenharmony_ci { LLCC_VIDSC0, 2, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 23962306a36Sopenharmony_ci { LLCC_VIDSC1, 3, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24062306a36Sopenharmony_ci { LLCC_AUDIO, 6, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24162306a36Sopenharmony_ci { LLCC_MDMHPGRW, 7, 3072, 1, 0, 0xFF, 0xF00, 0, 0, 0, 1, 0 }, 24262306a36Sopenharmony_ci { LLCC_MDM, 8, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24362306a36Sopenharmony_ci { LLCC_MODHW, 9, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24462306a36Sopenharmony_ci { LLCC_CMPT, 10, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24562306a36Sopenharmony_ci { LLCC_GPUHTW , 11, 512, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24662306a36Sopenharmony_ci { LLCC_GPU, 12, 2560, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24762306a36Sopenharmony_ci { LLCC_MMUHWT, 13, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1 }, 24862306a36Sopenharmony_ci { LLCC_CMPTDMA, 15, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 24962306a36Sopenharmony_ci { LLCC_DISP, 16, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 25062306a36Sopenharmony_ci { LLCC_MDMHPFX, 20, 1024, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 25162306a36Sopenharmony_ci { LLCC_MDMHPFX, 21, 1024, 0, 1, 0xF, 0x0, 0, 0, 0, 1, 0 }, 25262306a36Sopenharmony_ci { LLCC_AUDHW, 22, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 25362306a36Sopenharmony_ci { LLCC_NPU, 23, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 25462306a36Sopenharmony_ci { LLCC_WLHW, 24, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 }, 25562306a36Sopenharmony_ci { LLCC_MODPE, 29, 256, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0 }, 25662306a36Sopenharmony_ci { LLCC_APTCM, 30, 256, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0 }, 25762306a36Sopenharmony_ci { LLCC_WRCACHE, 31, 128, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0 }, 25862306a36Sopenharmony_ci}; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic const struct llcc_slice_config sm8250_data[] = { 26162306a36Sopenharmony_ci { LLCC_CPUSS, 1, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 }, 26262306a36Sopenharmony_ci { LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 26362306a36Sopenharmony_ci { LLCC_AUDIO, 6, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 }, 26462306a36Sopenharmony_ci { LLCC_CMPT, 10, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 }, 26562306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 26662306a36Sopenharmony_ci { LLCC_GPU, 12, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 1 }, 26762306a36Sopenharmony_ci { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 26862306a36Sopenharmony_ci { LLCC_CMPTDMA, 15, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 26962306a36Sopenharmony_ci { LLCC_DISP, 16, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 27062306a36Sopenharmony_ci { LLCC_VIDFW, 17, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 27162306a36Sopenharmony_ci { LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 27262306a36Sopenharmony_ci { LLCC_NPU, 23, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 27362306a36Sopenharmony_ci { LLCC_WLHW, 24, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 27462306a36Sopenharmony_ci { LLCC_CVP, 28, 256, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, 27562306a36Sopenharmony_ci { LLCC_APTCM, 30, 128, 3, 0, 0x0, 0x3, 1, 0, 0, 1, 0, 0 }, 27662306a36Sopenharmony_ci { LLCC_WRCACHE, 31, 256, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 27762306a36Sopenharmony_ci}; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic const struct llcc_slice_config sm8350_data[] = { 28062306a36Sopenharmony_ci { LLCC_CPUSS, 1, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 1 }, 28162306a36Sopenharmony_ci { LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 28262306a36Sopenharmony_ci { LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 }, 28362306a36Sopenharmony_ci { LLCC_MDMHPGRW, 7, 1024, 3, 0, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 28462306a36Sopenharmony_ci { LLCC_MODHW, 9, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 28562306a36Sopenharmony_ci { LLCC_CMPT, 10, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 28662306a36Sopenharmony_ci { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 28762306a36Sopenharmony_ci { LLCC_GPU, 12, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 }, 28862306a36Sopenharmony_ci { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 }, 28962306a36Sopenharmony_ci { LLCC_DISP, 16, 3072, 2, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 29062306a36Sopenharmony_ci { LLCC_MDMPNG, 21, 1024, 0, 1, 0xf, 0x0, 0, 0, 0, 0, 1, 0 }, 29162306a36Sopenharmony_ci { LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 29262306a36Sopenharmony_ci { LLCC_CVP, 28, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 29362306a36Sopenharmony_ci { LLCC_MODPE, 29, 256, 1, 1, 0xf, 0x0, 0, 0, 0, 0, 1, 0 }, 29462306a36Sopenharmony_ci { LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0x1, 1, 0, 0, 0, 1, 0 }, 29562306a36Sopenharmony_ci { LLCC_WRCACHE, 31, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 }, 29662306a36Sopenharmony_ci { LLCC_CVPFW, 17, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 29762306a36Sopenharmony_ci { LLCC_CPUSS1, 3, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, 29862306a36Sopenharmony_ci { LLCC_CPUHWT, 5, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 }, 29962306a36Sopenharmony_ci}; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_cistatic const struct llcc_slice_config sm8450_data[] = { 30262306a36Sopenharmony_ci {LLCC_CPUSS, 1, 3072, 1, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 }, 30362306a36Sopenharmony_ci {LLCC_VIDSC0, 2, 512, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 30462306a36Sopenharmony_ci {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, 30562306a36Sopenharmony_ci {LLCC_MDMHPGRW, 7, 1024, 3, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 30662306a36Sopenharmony_ci {LLCC_MODHW, 9, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 30762306a36Sopenharmony_ci {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 30862306a36Sopenharmony_ci {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 30962306a36Sopenharmony_ci {LLCC_GPU, 12, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 1, 0 }, 31062306a36Sopenharmony_ci {LLCC_MMUHWT, 13, 768, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 }, 31162306a36Sopenharmony_ci {LLCC_DISP, 16, 4096, 2, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 31262306a36Sopenharmony_ci {LLCC_MDMPNG, 21, 1024, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 31362306a36Sopenharmony_ci {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, 31462306a36Sopenharmony_ci {LLCC_CVP, 28, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 31562306a36Sopenharmony_ci {LLCC_MODPE, 29, 64, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 31662306a36Sopenharmony_ci {LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xF0, 1, 0, 0, 1, 0, 0, 0 }, 31762306a36Sopenharmony_ci {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 }, 31862306a36Sopenharmony_ci {LLCC_CVPFW, 17, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 31962306a36Sopenharmony_ci {LLCC_CPUSS1, 3, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 32062306a36Sopenharmony_ci {LLCC_CAMEXP0, 4, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 32162306a36Sopenharmony_ci {LLCC_CPUMTE, 23, 256, 1, 1, 0x0FFF, 0x0, 0, 0, 0, 0, 1, 0, 0 }, 32262306a36Sopenharmony_ci {LLCC_CPUHWT, 5, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 }, 32362306a36Sopenharmony_ci {LLCC_CAMEXP1, 27, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, 32462306a36Sopenharmony_ci {LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, 32562306a36Sopenharmony_ci}; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic const struct llcc_slice_config sm8550_data[] = { 32862306a36Sopenharmony_ci {LLCC_CPUSS, 1, 5120, 1, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 32962306a36Sopenharmony_ci {LLCC_VIDSC0, 2, 512, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33062306a36Sopenharmony_ci {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33162306a36Sopenharmony_ci {LLCC_MDMHPGRW, 25, 1024, 4, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33262306a36Sopenharmony_ci {LLCC_MODHW, 26, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33362306a36Sopenharmony_ci {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33462306a36Sopenharmony_ci {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33562306a36Sopenharmony_ci {LLCC_GPU, 9, 3096, 1, 0, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, 33662306a36Sopenharmony_ci {LLCC_MMUHWT, 18, 768, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33762306a36Sopenharmony_ci {LLCC_DISP, 16, 6144, 1, 1, 0xFFFFFF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33862306a36Sopenharmony_ci {LLCC_MDMPNG, 27, 1024, 0, 1, 0xF00000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 33962306a36Sopenharmony_ci {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34062306a36Sopenharmony_ci {LLCC_CVP, 8, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34162306a36Sopenharmony_ci {LLCC_MODPE, 29, 64, 1, 1, 0xF00000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, }, 34262306a36Sopenharmony_ci {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34362306a36Sopenharmony_ci {LLCC_CAMEXP0, 4, 256, 4, 1, 0xF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34462306a36Sopenharmony_ci {LLCC_CPUHWT, 5, 512, 1, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34562306a36Sopenharmony_ci {LLCC_CAMEXP1, 7, 3200, 3, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34662306a36Sopenharmony_ci {LLCC_CMPTHCP, 17, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34762306a36Sopenharmony_ci {LLCC_LCPDARE, 30, 128, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, }, 34862306a36Sopenharmony_ci {LLCC_AENPU, 3, 3072, 1, 1, 0xFE01FF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 34962306a36Sopenharmony_ci {LLCC_ISLAND1, 12, 1792, 7, 1, 0xFE00, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35062306a36Sopenharmony_ci {LLCC_ISLAND4, 15, 256, 7, 1, 0x10000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35162306a36Sopenharmony_ci {LLCC_CAMEXP2, 19, 3200, 3, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35262306a36Sopenharmony_ci {LLCC_CAMEXP3, 20, 3200, 2, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35362306a36Sopenharmony_ci {LLCC_CAMEXP4, 21, 3200, 2, 1, 0xFFFFF0, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35462306a36Sopenharmony_ci {LLCC_DISP_WB, 23, 1024, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35562306a36Sopenharmony_ci {LLCC_DISP_1, 24, 6144, 1, 1, 0xFFFFFF, 0x0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35662306a36Sopenharmony_ci {LLCC_VIDVSP, 28, 256, 4, 1, 0xFFFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 35762306a36Sopenharmony_ci}; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_cistatic const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = { 36062306a36Sopenharmony_ci .trp_ecc_error_status0 = 0x20344, 36162306a36Sopenharmony_ci .trp_ecc_error_status1 = 0x20348, 36262306a36Sopenharmony_ci .trp_ecc_sb_err_syn0 = 0x2304c, 36362306a36Sopenharmony_ci .trp_ecc_db_err_syn0 = 0x20370, 36462306a36Sopenharmony_ci .trp_ecc_error_cntr_clear = 0x20440, 36562306a36Sopenharmony_ci .trp_interrupt_0_status = 0x20480, 36662306a36Sopenharmony_ci .trp_interrupt_0_clear = 0x20484, 36762306a36Sopenharmony_ci .trp_interrupt_0_enable = 0x20488, 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci /* LLCC Common registers */ 37062306a36Sopenharmony_ci .cmn_status0 = 0x3000c, 37162306a36Sopenharmony_ci .cmn_interrupt_0_enable = 0x3001c, 37262306a36Sopenharmony_ci .cmn_interrupt_2_enable = 0x3003c, 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci /* LLCC DRP registers */ 37562306a36Sopenharmony_ci .drp_ecc_error_cfg = 0x40000, 37662306a36Sopenharmony_ci .drp_ecc_error_cntr_clear = 0x40004, 37762306a36Sopenharmony_ci .drp_interrupt_status = 0x41000, 37862306a36Sopenharmony_ci .drp_interrupt_clear = 0x41008, 37962306a36Sopenharmony_ci .drp_interrupt_enable = 0x4100c, 38062306a36Sopenharmony_ci .drp_ecc_error_status0 = 0x42044, 38162306a36Sopenharmony_ci .drp_ecc_error_status1 = 0x42048, 38262306a36Sopenharmony_ci .drp_ecc_sb_err_syn0 = 0x4204c, 38362306a36Sopenharmony_ci .drp_ecc_db_err_syn0 = 0x42070, 38462306a36Sopenharmony_ci}; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_cistatic const struct llcc_edac_reg_offset llcc_v2_1_edac_reg_offset = { 38762306a36Sopenharmony_ci .trp_ecc_error_status0 = 0x20344, 38862306a36Sopenharmony_ci .trp_ecc_error_status1 = 0x20348, 38962306a36Sopenharmony_ci .trp_ecc_sb_err_syn0 = 0x2034c, 39062306a36Sopenharmony_ci .trp_ecc_db_err_syn0 = 0x20370, 39162306a36Sopenharmony_ci .trp_ecc_error_cntr_clear = 0x20440, 39262306a36Sopenharmony_ci .trp_interrupt_0_status = 0x20480, 39362306a36Sopenharmony_ci .trp_interrupt_0_clear = 0x20484, 39462306a36Sopenharmony_ci .trp_interrupt_0_enable = 0x20488, 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci /* LLCC Common registers */ 39762306a36Sopenharmony_ci .cmn_status0 = 0x3400c, 39862306a36Sopenharmony_ci .cmn_interrupt_0_enable = 0x3401c, 39962306a36Sopenharmony_ci .cmn_interrupt_2_enable = 0x3403c, 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci /* LLCC DRP registers */ 40262306a36Sopenharmony_ci .drp_ecc_error_cfg = 0x50000, 40362306a36Sopenharmony_ci .drp_ecc_error_cntr_clear = 0x50004, 40462306a36Sopenharmony_ci .drp_interrupt_status = 0x50020, 40562306a36Sopenharmony_ci .drp_interrupt_clear = 0x50028, 40662306a36Sopenharmony_ci .drp_interrupt_enable = 0x5002c, 40762306a36Sopenharmony_ci .drp_ecc_error_status0 = 0x520f4, 40862306a36Sopenharmony_ci .drp_ecc_error_status1 = 0x520f8, 40962306a36Sopenharmony_ci .drp_ecc_sb_err_syn0 = 0x520fc, 41062306a36Sopenharmony_ci .drp_ecc_db_err_syn0 = 0x52120, 41162306a36Sopenharmony_ci}; 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci/* LLCC register offset starting from v1.0.0 */ 41462306a36Sopenharmony_cistatic const u32 llcc_v1_reg_offset[] = { 41562306a36Sopenharmony_ci [LLCC_COMMON_HW_INFO] = 0x00030000, 41662306a36Sopenharmony_ci [LLCC_COMMON_STATUS0] = 0x0003000c, 41762306a36Sopenharmony_ci}; 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci/* LLCC register offset starting from v2.0.1 */ 42062306a36Sopenharmony_cistatic const u32 llcc_v2_1_reg_offset[] = { 42162306a36Sopenharmony_ci [LLCC_COMMON_HW_INFO] = 0x00034000, 42262306a36Sopenharmony_ci [LLCC_COMMON_STATUS0] = 0x0003400c, 42362306a36Sopenharmony_ci}; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_cistatic const struct qcom_llcc_config sc7180_cfg = { 42662306a36Sopenharmony_ci .sct_data = sc7180_data, 42762306a36Sopenharmony_ci .size = ARRAY_SIZE(sc7180_data), 42862306a36Sopenharmony_ci .need_llcc_cfg = true, 42962306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 43062306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 43162306a36Sopenharmony_ci}; 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_cistatic const struct qcom_llcc_config sc7280_cfg = { 43462306a36Sopenharmony_ci .sct_data = sc7280_data, 43562306a36Sopenharmony_ci .size = ARRAY_SIZE(sc7280_data), 43662306a36Sopenharmony_ci .need_llcc_cfg = true, 43762306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 43862306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 43962306a36Sopenharmony_ci}; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_cistatic const struct qcom_llcc_config sc8180x_cfg = { 44262306a36Sopenharmony_ci .sct_data = sc8180x_data, 44362306a36Sopenharmony_ci .size = ARRAY_SIZE(sc8180x_data), 44462306a36Sopenharmony_ci .need_llcc_cfg = true, 44562306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 44662306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 44762306a36Sopenharmony_ci}; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_cistatic const struct qcom_llcc_config sc8280xp_cfg = { 45062306a36Sopenharmony_ci .sct_data = sc8280xp_data, 45162306a36Sopenharmony_ci .size = ARRAY_SIZE(sc8280xp_data), 45262306a36Sopenharmony_ci .need_llcc_cfg = true, 45362306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 45462306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 45562306a36Sopenharmony_ci}; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_cistatic const struct qcom_llcc_config sdm845_cfg = { 45862306a36Sopenharmony_ci .sct_data = sdm845_data, 45962306a36Sopenharmony_ci .size = ARRAY_SIZE(sdm845_data), 46062306a36Sopenharmony_ci .need_llcc_cfg = false, 46162306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 46262306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 46362306a36Sopenharmony_ci .no_edac = true, 46462306a36Sopenharmony_ci}; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_cistatic const struct qcom_llcc_config sm6350_cfg = { 46762306a36Sopenharmony_ci .sct_data = sm6350_data, 46862306a36Sopenharmony_ci .size = ARRAY_SIZE(sm6350_data), 46962306a36Sopenharmony_ci .need_llcc_cfg = true, 47062306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 47162306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 47262306a36Sopenharmony_ci}; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_cistatic const struct qcom_llcc_config sm7150_cfg = { 47562306a36Sopenharmony_ci .sct_data = sm7150_data, 47662306a36Sopenharmony_ci .size = ARRAY_SIZE(sm7150_data), 47762306a36Sopenharmony_ci .need_llcc_cfg = true, 47862306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 47962306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 48062306a36Sopenharmony_ci}; 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_cistatic const struct qcom_llcc_config sm8150_cfg = { 48362306a36Sopenharmony_ci .sct_data = sm8150_data, 48462306a36Sopenharmony_ci .size = ARRAY_SIZE(sm8150_data), 48562306a36Sopenharmony_ci .need_llcc_cfg = true, 48662306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 48762306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 48862306a36Sopenharmony_ci}; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_cistatic const struct qcom_llcc_config sm8250_cfg = { 49162306a36Sopenharmony_ci .sct_data = sm8250_data, 49262306a36Sopenharmony_ci .size = ARRAY_SIZE(sm8250_data), 49362306a36Sopenharmony_ci .need_llcc_cfg = true, 49462306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 49562306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 49662306a36Sopenharmony_ci}; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_cistatic const struct qcom_llcc_config sm8350_cfg = { 49962306a36Sopenharmony_ci .sct_data = sm8350_data, 50062306a36Sopenharmony_ci .size = ARRAY_SIZE(sm8350_data), 50162306a36Sopenharmony_ci .need_llcc_cfg = true, 50262306a36Sopenharmony_ci .reg_offset = llcc_v1_reg_offset, 50362306a36Sopenharmony_ci .edac_reg_offset = &llcc_v1_edac_reg_offset, 50462306a36Sopenharmony_ci}; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic const struct qcom_llcc_config sm8450_cfg = { 50762306a36Sopenharmony_ci .sct_data = sm8450_data, 50862306a36Sopenharmony_ci .size = ARRAY_SIZE(sm8450_data), 50962306a36Sopenharmony_ci .need_llcc_cfg = true, 51062306a36Sopenharmony_ci .reg_offset = llcc_v2_1_reg_offset, 51162306a36Sopenharmony_ci .edac_reg_offset = &llcc_v2_1_edac_reg_offset, 51262306a36Sopenharmony_ci}; 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_cistatic const struct qcom_llcc_config sm8550_cfg = { 51562306a36Sopenharmony_ci .sct_data = sm8550_data, 51662306a36Sopenharmony_ci .size = ARRAY_SIZE(sm8550_data), 51762306a36Sopenharmony_ci .need_llcc_cfg = true, 51862306a36Sopenharmony_ci .reg_offset = llcc_v2_1_reg_offset, 51962306a36Sopenharmony_ci .edac_reg_offset = &llcc_v2_1_edac_reg_offset, 52062306a36Sopenharmony_ci}; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_cistatic struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci/** 52562306a36Sopenharmony_ci * llcc_slice_getd - get llcc slice descriptor 52662306a36Sopenharmony_ci * @uid: usecase_id for the client 52762306a36Sopenharmony_ci * 52862306a36Sopenharmony_ci * A pointer to llcc slice descriptor will be returned on success 52962306a36Sopenharmony_ci * and error pointer is returned on failure 53062306a36Sopenharmony_ci */ 53162306a36Sopenharmony_cistruct llcc_slice_desc *llcc_slice_getd(u32 uid) 53262306a36Sopenharmony_ci{ 53362306a36Sopenharmony_ci const struct llcc_slice_config *cfg; 53462306a36Sopenharmony_ci struct llcc_slice_desc *desc; 53562306a36Sopenharmony_ci u32 sz, count; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci if (IS_ERR(drv_data)) 53862306a36Sopenharmony_ci return ERR_CAST(drv_data); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci cfg = drv_data->cfg; 54162306a36Sopenharmony_ci sz = drv_data->cfg_size; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci for (count = 0; cfg && count < sz; count++, cfg++) 54462306a36Sopenharmony_ci if (cfg->usecase_id == uid) 54562306a36Sopenharmony_ci break; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci if (count == sz || !cfg) 54862306a36Sopenharmony_ci return ERR_PTR(-ENODEV); 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci desc = kzalloc(sizeof(*desc), GFP_KERNEL); 55162306a36Sopenharmony_ci if (!desc) 55262306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci desc->slice_id = cfg->slice_id; 55562306a36Sopenharmony_ci desc->slice_size = cfg->max_cap; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci return desc; 55862306a36Sopenharmony_ci} 55962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(llcc_slice_getd); 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci/** 56262306a36Sopenharmony_ci * llcc_slice_putd - llcc slice descritpor 56362306a36Sopenharmony_ci * @desc: Pointer to llcc slice descriptor 56462306a36Sopenharmony_ci */ 56562306a36Sopenharmony_civoid llcc_slice_putd(struct llcc_slice_desc *desc) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci if (!IS_ERR_OR_NULL(desc)) 56862306a36Sopenharmony_ci kfree(desc); 56962306a36Sopenharmony_ci} 57062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(llcc_slice_putd); 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_cistatic int llcc_update_act_ctrl(u32 sid, 57362306a36Sopenharmony_ci u32 act_ctrl_reg_val, u32 status) 57462306a36Sopenharmony_ci{ 57562306a36Sopenharmony_ci u32 act_ctrl_reg; 57662306a36Sopenharmony_ci u32 act_clear_reg; 57762306a36Sopenharmony_ci u32 status_reg; 57862306a36Sopenharmony_ci u32 slice_status; 57962306a36Sopenharmony_ci int ret; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci if (IS_ERR(drv_data)) 58262306a36Sopenharmony_ci return PTR_ERR(drv_data); 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid); 58562306a36Sopenharmony_ci act_clear_reg = LLCC_TRP_ACT_CLEARn(sid); 58662306a36Sopenharmony_ci status_reg = LLCC_TRP_STATUSn(sid); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci /* Set the ACTIVE trigger */ 58962306a36Sopenharmony_ci act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG; 59062306a36Sopenharmony_ci ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg, 59162306a36Sopenharmony_ci act_ctrl_reg_val); 59262306a36Sopenharmony_ci if (ret) 59362306a36Sopenharmony_ci return ret; 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci /* Clear the ACTIVE trigger */ 59662306a36Sopenharmony_ci act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG; 59762306a36Sopenharmony_ci ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg, 59862306a36Sopenharmony_ci act_ctrl_reg_val); 59962306a36Sopenharmony_ci if (ret) 60062306a36Sopenharmony_ci return ret; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci if (drv_data->version >= LLCC_VERSION_4_1_0_0) { 60362306a36Sopenharmony_ci ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg, 60462306a36Sopenharmony_ci slice_status, (slice_status & ACT_COMPLETE), 60562306a36Sopenharmony_ci 0, LLCC_STATUS_READ_DELAY); 60662306a36Sopenharmony_ci if (ret) 60762306a36Sopenharmony_ci return ret; 60862306a36Sopenharmony_ci } 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg, 61162306a36Sopenharmony_ci slice_status, !(slice_status & status), 61262306a36Sopenharmony_ci 0, LLCC_STATUS_READ_DELAY); 61362306a36Sopenharmony_ci if (ret) 61462306a36Sopenharmony_ci return ret; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci if (drv_data->version >= LLCC_VERSION_4_1_0_0) 61762306a36Sopenharmony_ci ret = regmap_write(drv_data->bcast_regmap, act_clear_reg, 61862306a36Sopenharmony_ci ACT_CLEAR); 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci return ret; 62162306a36Sopenharmony_ci} 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci/** 62462306a36Sopenharmony_ci * llcc_slice_activate - Activate the llcc slice 62562306a36Sopenharmony_ci * @desc: Pointer to llcc slice descriptor 62662306a36Sopenharmony_ci * 62762306a36Sopenharmony_ci * A value of zero will be returned on success and a negative errno will 62862306a36Sopenharmony_ci * be returned in error cases 62962306a36Sopenharmony_ci */ 63062306a36Sopenharmony_ciint llcc_slice_activate(struct llcc_slice_desc *desc) 63162306a36Sopenharmony_ci{ 63262306a36Sopenharmony_ci int ret; 63362306a36Sopenharmony_ci u32 act_ctrl_val; 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci if (IS_ERR(drv_data)) 63662306a36Sopenharmony_ci return PTR_ERR(drv_data); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci if (IS_ERR_OR_NULL(desc)) 63962306a36Sopenharmony_ci return -EINVAL; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci mutex_lock(&drv_data->lock); 64262306a36Sopenharmony_ci if (test_bit(desc->slice_id, drv_data->bitmap)) { 64362306a36Sopenharmony_ci mutex_unlock(&drv_data->lock); 64462306a36Sopenharmony_ci return 0; 64562306a36Sopenharmony_ci } 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT; 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val, 65062306a36Sopenharmony_ci DEACTIVATE); 65162306a36Sopenharmony_ci if (ret) { 65262306a36Sopenharmony_ci mutex_unlock(&drv_data->lock); 65362306a36Sopenharmony_ci return ret; 65462306a36Sopenharmony_ci } 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci __set_bit(desc->slice_id, drv_data->bitmap); 65762306a36Sopenharmony_ci mutex_unlock(&drv_data->lock); 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci return ret; 66062306a36Sopenharmony_ci} 66162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(llcc_slice_activate); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci/** 66462306a36Sopenharmony_ci * llcc_slice_deactivate - Deactivate the llcc slice 66562306a36Sopenharmony_ci * @desc: Pointer to llcc slice descriptor 66662306a36Sopenharmony_ci * 66762306a36Sopenharmony_ci * A value of zero will be returned on success and a negative errno will 66862306a36Sopenharmony_ci * be returned in error cases 66962306a36Sopenharmony_ci */ 67062306a36Sopenharmony_ciint llcc_slice_deactivate(struct llcc_slice_desc *desc) 67162306a36Sopenharmony_ci{ 67262306a36Sopenharmony_ci u32 act_ctrl_val; 67362306a36Sopenharmony_ci int ret; 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci if (IS_ERR(drv_data)) 67662306a36Sopenharmony_ci return PTR_ERR(drv_data); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci if (IS_ERR_OR_NULL(desc)) 67962306a36Sopenharmony_ci return -EINVAL; 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci mutex_lock(&drv_data->lock); 68262306a36Sopenharmony_ci if (!test_bit(desc->slice_id, drv_data->bitmap)) { 68362306a36Sopenharmony_ci mutex_unlock(&drv_data->lock); 68462306a36Sopenharmony_ci return 0; 68562306a36Sopenharmony_ci } 68662306a36Sopenharmony_ci act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT; 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val, 68962306a36Sopenharmony_ci ACTIVATE); 69062306a36Sopenharmony_ci if (ret) { 69162306a36Sopenharmony_ci mutex_unlock(&drv_data->lock); 69262306a36Sopenharmony_ci return ret; 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci __clear_bit(desc->slice_id, drv_data->bitmap); 69662306a36Sopenharmony_ci mutex_unlock(&drv_data->lock); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci return ret; 69962306a36Sopenharmony_ci} 70062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(llcc_slice_deactivate); 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci/** 70362306a36Sopenharmony_ci * llcc_get_slice_id - return the slice id 70462306a36Sopenharmony_ci * @desc: Pointer to llcc slice descriptor 70562306a36Sopenharmony_ci */ 70662306a36Sopenharmony_ciint llcc_get_slice_id(struct llcc_slice_desc *desc) 70762306a36Sopenharmony_ci{ 70862306a36Sopenharmony_ci if (IS_ERR_OR_NULL(desc)) 70962306a36Sopenharmony_ci return -EINVAL; 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci return desc->slice_id; 71262306a36Sopenharmony_ci} 71362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(llcc_get_slice_id); 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci/** 71662306a36Sopenharmony_ci * llcc_get_slice_size - return the slice id 71762306a36Sopenharmony_ci * @desc: Pointer to llcc slice descriptor 71862306a36Sopenharmony_ci */ 71962306a36Sopenharmony_cisize_t llcc_get_slice_size(struct llcc_slice_desc *desc) 72062306a36Sopenharmony_ci{ 72162306a36Sopenharmony_ci if (IS_ERR_OR_NULL(desc)) 72262306a36Sopenharmony_ci return 0; 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci return desc->slice_size; 72562306a36Sopenharmony_ci} 72662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(llcc_get_slice_size); 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_cistatic int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, 72962306a36Sopenharmony_ci const struct qcom_llcc_config *cfg) 73062306a36Sopenharmony_ci{ 73162306a36Sopenharmony_ci int ret; 73262306a36Sopenharmony_ci u32 attr2_cfg; 73362306a36Sopenharmony_ci u32 attr1_cfg; 73462306a36Sopenharmony_ci u32 attr0_cfg; 73562306a36Sopenharmony_ci u32 attr2_val; 73662306a36Sopenharmony_ci u32 attr1_val; 73762306a36Sopenharmony_ci u32 attr0_val; 73862306a36Sopenharmony_ci u32 max_cap_cacheline; 73962306a36Sopenharmony_ci struct llcc_slice_desc desc; 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci attr1_val = config->cache_mode; 74262306a36Sopenharmony_ci attr1_val |= config->probe_target_ways << ATTR1_PROBE_TARGET_WAYS_SHIFT; 74362306a36Sopenharmony_ci attr1_val |= config->fixed_size << ATTR1_FIXED_SIZE_SHIFT; 74462306a36Sopenharmony_ci attr1_val |= config->priority << ATTR1_PRIORITY_SHIFT; 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci max_cap_cacheline = MAX_CAP_TO_BYTES(config->max_cap); 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci /* 74962306a36Sopenharmony_ci * LLCC instances can vary for each target. 75062306a36Sopenharmony_ci * The SW writes to broadcast register which gets propagated 75162306a36Sopenharmony_ci * to each llcc instance (llcc0,.. llccN). 75262306a36Sopenharmony_ci * Since the size of the memory is divided equally amongst the 75362306a36Sopenharmony_ci * llcc instances, we need to configure the max cap accordingly. 75462306a36Sopenharmony_ci */ 75562306a36Sopenharmony_ci max_cap_cacheline = max_cap_cacheline / drv_data->num_banks; 75662306a36Sopenharmony_ci max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT; 75762306a36Sopenharmony_ci attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT; 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci attr1_cfg = LLCC_TRP_ATTR1_CFGn(config->slice_id); 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci ret = regmap_write(drv_data->bcast_regmap, attr1_cfg, attr1_val); 76262306a36Sopenharmony_ci if (ret) 76362306a36Sopenharmony_ci return ret; 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci if (drv_data->version >= LLCC_VERSION_4_1_0_0) { 76662306a36Sopenharmony_ci attr2_cfg = LLCC_TRP_ATTR2_CFGn(config->slice_id); 76762306a36Sopenharmony_ci attr0_val = config->res_ways; 76862306a36Sopenharmony_ci attr2_val = config->bonus_ways; 76962306a36Sopenharmony_ci } else { 77062306a36Sopenharmony_ci attr0_val = config->res_ways & ATTR0_RES_WAYS_MASK; 77162306a36Sopenharmony_ci attr0_val |= config->bonus_ways << ATTR0_BONUS_WAYS_SHIFT; 77262306a36Sopenharmony_ci } 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci attr0_cfg = LLCC_TRP_ATTR0_CFGn(config->slice_id); 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci ret = regmap_write(drv_data->bcast_regmap, attr0_cfg, attr0_val); 77762306a36Sopenharmony_ci if (ret) 77862306a36Sopenharmony_ci return ret; 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci if (drv_data->version >= LLCC_VERSION_4_1_0_0) { 78162306a36Sopenharmony_ci ret = regmap_write(drv_data->bcast_regmap, attr2_cfg, attr2_val); 78262306a36Sopenharmony_ci if (ret) 78362306a36Sopenharmony_ci return ret; 78462306a36Sopenharmony_ci } 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci if (cfg->need_llcc_cfg) { 78762306a36Sopenharmony_ci u32 disable_cap_alloc, retain_pc; 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci disable_cap_alloc = config->dis_cap_alloc << config->slice_id; 79062306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_SCID_DIS_CAP_ALLOC, 79162306a36Sopenharmony_ci BIT(config->slice_id), disable_cap_alloc); 79262306a36Sopenharmony_ci if (ret) 79362306a36Sopenharmony_ci return ret; 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci if (drv_data->version < LLCC_VERSION_4_1_0_0) { 79662306a36Sopenharmony_ci retain_pc = config->retain_on_pc << config->slice_id; 79762306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_PCB_ACT, 79862306a36Sopenharmony_ci BIT(config->slice_id), retain_pc); 79962306a36Sopenharmony_ci if (ret) 80062306a36Sopenharmony_ci return ret; 80162306a36Sopenharmony_ci } 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci if (drv_data->version >= LLCC_VERSION_2_0_0_0) { 80562306a36Sopenharmony_ci u32 wren; 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci wren = config->write_scid_en << config->slice_id; 80862306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_EN, 80962306a36Sopenharmony_ci BIT(config->slice_id), wren); 81062306a36Sopenharmony_ci if (ret) 81162306a36Sopenharmony_ci return ret; 81262306a36Sopenharmony_ci } 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci if (drv_data->version >= LLCC_VERSION_2_1_0_0) { 81562306a36Sopenharmony_ci u32 wr_cache_en; 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci wr_cache_en = config->write_scid_cacheable_en << config->slice_id; 81862306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_CACHEABLE_EN, 81962306a36Sopenharmony_ci BIT(config->slice_id), wr_cache_en); 82062306a36Sopenharmony_ci if (ret) 82162306a36Sopenharmony_ci return ret; 82262306a36Sopenharmony_ci } 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci if (drv_data->version >= LLCC_VERSION_4_1_0_0) { 82562306a36Sopenharmony_ci u32 stale_en; 82662306a36Sopenharmony_ci u32 stale_cap_en; 82762306a36Sopenharmony_ci u32 mru_uncap_en; 82862306a36Sopenharmony_ci u32 mru_rollover; 82962306a36Sopenharmony_ci u32 alloc_oneway_en; 83062306a36Sopenharmony_ci u32 ovcap_en; 83162306a36Sopenharmony_ci u32 ovcap_prio; 83262306a36Sopenharmony_ci u32 vict_prio; 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci stale_en = config->stale_en << config->slice_id; 83562306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG1, 83662306a36Sopenharmony_ci BIT(config->slice_id), stale_en); 83762306a36Sopenharmony_ci if (ret) 83862306a36Sopenharmony_ci return ret; 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci stale_cap_en = config->stale_cap_en << config->slice_id; 84162306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG2, 84262306a36Sopenharmony_ci BIT(config->slice_id), stale_cap_en); 84362306a36Sopenharmony_ci if (ret) 84462306a36Sopenharmony_ci return ret; 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci mru_uncap_en = config->mru_uncap_en << config->slice_id; 84762306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG3, 84862306a36Sopenharmony_ci BIT(config->slice_id), mru_uncap_en); 84962306a36Sopenharmony_ci if (ret) 85062306a36Sopenharmony_ci return ret; 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci mru_rollover = config->mru_rollover << config->slice_id; 85362306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG4, 85462306a36Sopenharmony_ci BIT(config->slice_id), mru_rollover); 85562306a36Sopenharmony_ci if (ret) 85662306a36Sopenharmony_ci return ret; 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci alloc_oneway_en = config->alloc_oneway_en << config->slice_id; 85962306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG5, 86062306a36Sopenharmony_ci BIT(config->slice_id), alloc_oneway_en); 86162306a36Sopenharmony_ci if (ret) 86262306a36Sopenharmony_ci return ret; 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci ovcap_en = config->ovcap_en << config->slice_id; 86562306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG6, 86662306a36Sopenharmony_ci BIT(config->slice_id), ovcap_en); 86762306a36Sopenharmony_ci if (ret) 86862306a36Sopenharmony_ci return ret; 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci ovcap_prio = config->ovcap_prio << config->slice_id; 87162306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG7, 87262306a36Sopenharmony_ci BIT(config->slice_id), ovcap_prio); 87362306a36Sopenharmony_ci if (ret) 87462306a36Sopenharmony_ci return ret; 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci vict_prio = config->vict_prio << config->slice_id; 87762306a36Sopenharmony_ci ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_ALGO_CFG8, 87862306a36Sopenharmony_ci BIT(config->slice_id), vict_prio); 87962306a36Sopenharmony_ci if (ret) 88062306a36Sopenharmony_ci return ret; 88162306a36Sopenharmony_ci } 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci if (config->activate_on_init) { 88462306a36Sopenharmony_ci desc.slice_id = config->slice_id; 88562306a36Sopenharmony_ci ret = llcc_slice_activate(&desc); 88662306a36Sopenharmony_ci } 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci return ret; 88962306a36Sopenharmony_ci} 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_cistatic int qcom_llcc_cfg_program(struct platform_device *pdev, 89262306a36Sopenharmony_ci const struct qcom_llcc_config *cfg) 89362306a36Sopenharmony_ci{ 89462306a36Sopenharmony_ci int i; 89562306a36Sopenharmony_ci u32 sz; 89662306a36Sopenharmony_ci int ret = 0; 89762306a36Sopenharmony_ci const struct llcc_slice_config *llcc_table; 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci sz = drv_data->cfg_size; 90062306a36Sopenharmony_ci llcc_table = drv_data->cfg; 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci for (i = 0; i < sz; i++) { 90362306a36Sopenharmony_ci ret = _qcom_llcc_cfg_program(&llcc_table[i], cfg); 90462306a36Sopenharmony_ci if (ret) 90562306a36Sopenharmony_ci return ret; 90662306a36Sopenharmony_ci } 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci return ret; 90962306a36Sopenharmony_ci} 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_cistatic int qcom_llcc_remove(struct platform_device *pdev) 91262306a36Sopenharmony_ci{ 91362306a36Sopenharmony_ci /* Set the global pointer to a error code to avoid referencing it */ 91462306a36Sopenharmony_ci drv_data = ERR_PTR(-ENODEV); 91562306a36Sopenharmony_ci return 0; 91662306a36Sopenharmony_ci} 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_cistatic struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index, 91962306a36Sopenharmony_ci const char *name) 92062306a36Sopenharmony_ci{ 92162306a36Sopenharmony_ci void __iomem *base; 92262306a36Sopenharmony_ci struct regmap_config llcc_regmap_config = { 92362306a36Sopenharmony_ci .reg_bits = 32, 92462306a36Sopenharmony_ci .reg_stride = 4, 92562306a36Sopenharmony_ci .val_bits = 32, 92662306a36Sopenharmony_ci .fast_io = true, 92762306a36Sopenharmony_ci }; 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci base = devm_platform_ioremap_resource(pdev, index); 93062306a36Sopenharmony_ci if (IS_ERR(base)) 93162306a36Sopenharmony_ci return ERR_CAST(base); 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci llcc_regmap_config.name = name; 93462306a36Sopenharmony_ci return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config); 93562306a36Sopenharmony_ci} 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_cistatic int qcom_llcc_probe(struct platform_device *pdev) 93862306a36Sopenharmony_ci{ 93962306a36Sopenharmony_ci u32 num_banks; 94062306a36Sopenharmony_ci struct device *dev = &pdev->dev; 94162306a36Sopenharmony_ci int ret, i; 94262306a36Sopenharmony_ci struct platform_device *llcc_edac; 94362306a36Sopenharmony_ci const struct qcom_llcc_config *cfg; 94462306a36Sopenharmony_ci const struct llcc_slice_config *llcc_cfg; 94562306a36Sopenharmony_ci u32 sz; 94662306a36Sopenharmony_ci u32 version; 94762306a36Sopenharmony_ci struct regmap *regmap; 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci if (!IS_ERR(drv_data)) 95062306a36Sopenharmony_ci return -EBUSY; 95162306a36Sopenharmony_ci 95262306a36Sopenharmony_ci drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); 95362306a36Sopenharmony_ci if (!drv_data) { 95462306a36Sopenharmony_ci ret = -ENOMEM; 95562306a36Sopenharmony_ci goto err; 95662306a36Sopenharmony_ci } 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci /* Initialize the first LLCC bank regmap */ 95962306a36Sopenharmony_ci regmap = qcom_llcc_init_mmio(pdev, 0, "llcc0_base"); 96062306a36Sopenharmony_ci if (IS_ERR(regmap)) { 96162306a36Sopenharmony_ci ret = PTR_ERR(regmap); 96262306a36Sopenharmony_ci goto err; 96362306a36Sopenharmony_ci } 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci cfg = of_device_get_match_data(&pdev->dev); 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci ret = regmap_read(regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], &num_banks); 96862306a36Sopenharmony_ci if (ret) 96962306a36Sopenharmony_ci goto err; 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci num_banks &= LLCC_LB_CNT_MASK; 97262306a36Sopenharmony_ci num_banks >>= LLCC_LB_CNT_SHIFT; 97362306a36Sopenharmony_ci drv_data->num_banks = num_banks; 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci drv_data->regmaps = devm_kcalloc(dev, num_banks, sizeof(*drv_data->regmaps), GFP_KERNEL); 97662306a36Sopenharmony_ci if (!drv_data->regmaps) { 97762306a36Sopenharmony_ci ret = -ENOMEM; 97862306a36Sopenharmony_ci goto err; 97962306a36Sopenharmony_ci } 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci drv_data->regmaps[0] = regmap; 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci /* Initialize rest of LLCC bank regmaps */ 98462306a36Sopenharmony_ci for (i = 1; i < num_banks; i++) { 98562306a36Sopenharmony_ci char *base = kasprintf(GFP_KERNEL, "llcc%d_base", i); 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci drv_data->regmaps[i] = qcom_llcc_init_mmio(pdev, i, base); 98862306a36Sopenharmony_ci if (IS_ERR(drv_data->regmaps[i])) { 98962306a36Sopenharmony_ci ret = PTR_ERR(drv_data->regmaps[i]); 99062306a36Sopenharmony_ci kfree(base); 99162306a36Sopenharmony_ci goto err; 99262306a36Sopenharmony_ci } 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci kfree(base); 99562306a36Sopenharmony_ci } 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci drv_data->bcast_regmap = qcom_llcc_init_mmio(pdev, i, "llcc_broadcast_base"); 99862306a36Sopenharmony_ci if (IS_ERR(drv_data->bcast_regmap)) { 99962306a36Sopenharmony_ci ret = PTR_ERR(drv_data->bcast_regmap); 100062306a36Sopenharmony_ci goto err; 100162306a36Sopenharmony_ci } 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci /* Extract version of the IP */ 100462306a36Sopenharmony_ci ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO], 100562306a36Sopenharmony_ci &version); 100662306a36Sopenharmony_ci if (ret) 100762306a36Sopenharmony_ci goto err; 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci drv_data->version = version; 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci llcc_cfg = cfg->sct_data; 101262306a36Sopenharmony_ci sz = cfg->size; 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci for (i = 0; i < sz; i++) 101562306a36Sopenharmony_ci if (llcc_cfg[i].slice_id > drv_data->max_slices) 101662306a36Sopenharmony_ci drv_data->max_slices = llcc_cfg[i].slice_id; 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_ci drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices, 101962306a36Sopenharmony_ci GFP_KERNEL); 102062306a36Sopenharmony_ci if (!drv_data->bitmap) { 102162306a36Sopenharmony_ci ret = -ENOMEM; 102262306a36Sopenharmony_ci goto err; 102362306a36Sopenharmony_ci } 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci drv_data->cfg = llcc_cfg; 102662306a36Sopenharmony_ci drv_data->cfg_size = sz; 102762306a36Sopenharmony_ci drv_data->edac_reg_offset = cfg->edac_reg_offset; 102862306a36Sopenharmony_ci mutex_init(&drv_data->lock); 102962306a36Sopenharmony_ci platform_set_drvdata(pdev, drv_data); 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_ci ret = qcom_llcc_cfg_program(pdev, cfg); 103262306a36Sopenharmony_ci if (ret) 103362306a36Sopenharmony_ci goto err; 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci drv_data->ecc_irq = platform_get_irq_optional(pdev, 0); 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci /* 103862306a36Sopenharmony_ci * On some platforms, the access to EDAC registers will be locked by 103962306a36Sopenharmony_ci * the bootloader. So probing the EDAC driver will result in a crash. 104062306a36Sopenharmony_ci * Hence, disable the creation of EDAC platform device for the 104162306a36Sopenharmony_ci * problematic platforms. 104262306a36Sopenharmony_ci */ 104362306a36Sopenharmony_ci if (!cfg->no_edac) { 104462306a36Sopenharmony_ci llcc_edac = platform_device_register_data(&pdev->dev, 104562306a36Sopenharmony_ci "qcom_llcc_edac", -1, drv_data, 104662306a36Sopenharmony_ci sizeof(*drv_data)); 104762306a36Sopenharmony_ci if (IS_ERR(llcc_edac)) 104862306a36Sopenharmony_ci dev_err(dev, "Failed to register llcc edac driver\n"); 104962306a36Sopenharmony_ci } 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci return 0; 105262306a36Sopenharmony_cierr: 105362306a36Sopenharmony_ci drv_data = ERR_PTR(-ENODEV); 105462306a36Sopenharmony_ci return ret; 105562306a36Sopenharmony_ci} 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_cistatic const struct of_device_id qcom_llcc_of_match[] = { 105862306a36Sopenharmony_ci { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfg }, 105962306a36Sopenharmony_ci { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfg }, 106062306a36Sopenharmony_ci { .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfg }, 106162306a36Sopenharmony_ci { .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfg }, 106262306a36Sopenharmony_ci { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg }, 106362306a36Sopenharmony_ci { .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfg }, 106462306a36Sopenharmony_ci { .compatible = "qcom,sm7150-llcc", .data = &sm7150_cfg }, 106562306a36Sopenharmony_ci { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg }, 106662306a36Sopenharmony_ci { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg }, 106762306a36Sopenharmony_ci { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg }, 106862306a36Sopenharmony_ci { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg }, 106962306a36Sopenharmony_ci { .compatible = "qcom,sm8550-llcc", .data = &sm8550_cfg }, 107062306a36Sopenharmony_ci { } 107162306a36Sopenharmony_ci}; 107262306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, qcom_llcc_of_match); 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_cistatic struct platform_driver qcom_llcc_driver = { 107562306a36Sopenharmony_ci .driver = { 107662306a36Sopenharmony_ci .name = "qcom-llcc", 107762306a36Sopenharmony_ci .of_match_table = qcom_llcc_of_match, 107862306a36Sopenharmony_ci }, 107962306a36Sopenharmony_ci .probe = qcom_llcc_probe, 108062306a36Sopenharmony_ci .remove = qcom_llcc_remove, 108162306a36Sopenharmony_ci}; 108262306a36Sopenharmony_cimodule_platform_driver(qcom_llcc_driver); 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ciMODULE_DESCRIPTION("Qualcomm Last Level Cache Controller"); 108562306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 1086