brintos

brintos / linux-shallow public Read only

0
0
Text · 49.8 KiB · 28bcc65 Raw
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