3535#define ATTR0_RES_WAYS_MASK GENMASK(15, 0)
3636#define ATTR0_BONUS_WAYS_MASK GENMASK(31, 16)
3737#define ATTR0_BONUS_WAYS_SHIFT 16
38+ #define ATTR2_PROBE_TARGET_WAYS_MASK BIT(4)
39+ #define ATTR2_FIXED_SIZE_MASK BIT(8)
40+ #define ATTR2_PRIORITY_MASK GENMASK(14, 12)
41+ #define ATTR2_PARENT_SCID_MASK GENMASK(21, 16)
42+ #define ATTR2_IN_A_GROUP_MASK BIT(24)
3843#define LLCC_STATUS_READ_DELAY 100
3944
4045#define CACHE_LINE_SIZE_SHIFT 6
4954#define LLCC_TRP_ATTR0_CFGn (n ) (0x21000 + SZ_8 * n)
5055#define LLCC_TRP_ATTR1_CFGn (n ) (0x21004 + SZ_8 * n)
5156#define LLCC_TRP_ATTR2_CFGn (n ) (0x21100 + SZ_4 * n)
57+ #define LLCC_V6_TRP_ATTR0_CFGn (n ) (cfg->reg_offset[LLCC_TRP_ATTR0_CFG] + SZ_64 * (n))
58+ #define LLCC_V6_TRP_ATTR1_CFGn (n ) (cfg->reg_offset[LLCC_TRP_ATTR1_CFG] + SZ_64 * (n))
59+ #define LLCC_V6_TRP_ATTR2_CFGn (n ) (cfg->reg_offset[LLCC_TRP_ATTR2_CFG] + SZ_64 * (n))
60+ #define LLCC_V6_TRP_ATTR3_CFGn (n ) (cfg->reg_offset[LLCC_TRP_ATTR3_CFG] + SZ_64 * (n))
5261
5362#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00
5463#define LLCC_TRP_PCB_ACT 0x21f04
6675#define LLCC_VERSION_2_0_0_0 0x02000000
6776#define LLCC_VERSION_2_1_0_0 0x02010000
6877#define LLCC_VERSION_4_1_0_0 0x04010000
78+ #define LLCC_VERSION_6_0_0_0 0X06000000
6979
7080/**
7181 * struct llcc_slice_config - Data associated with the llcc slice
106116 * ovcap_en.
107117 * @vict_prio: When current scid is under-capacity, allocate over other
108118 * lower-than victim priority-line threshold scid.
119+ * @parent_slice_id: For grouped slices, specifies the slice id of the parent.
109120 */
110121struct llcc_slice_config {
111122 u32 usecase_id ;
@@ -130,6 +141,7 @@ struct llcc_slice_config {
130141 bool ovcap_en ;
131142 bool ovcap_prio ;
132143 bool vict_prio ;
144+ u32 parent_slice_id ;
133145};
134146
135147struct qcom_llcc_config {
@@ -153,6 +165,21 @@ struct qcom_sct_config {
153165enum llcc_reg_offset {
154166 LLCC_COMMON_HW_INFO ,
155167 LLCC_COMMON_STATUS0 ,
168+ LLCC_TRP_ATTR0_CFG ,
169+ LLCC_TRP_ATTR1_CFG ,
170+ LLCC_TRP_ATTR2_CFG ,
171+ LLCC_TRP_ATTR3_CFG ,
172+ LLCC_TRP_SID_DIS_CAP_ALLOC ,
173+ LLCC_TRP_ALGO_STALE_EN ,
174+ LLCC_TRP_ALGO_STALE_CAP_EN ,
175+ LLCC_TRP_ALGO_MRU0 ,
176+ LLCC_TRP_ALGO_MRU1 ,
177+ LLCC_TRP_ALGO_ALLOC0 ,
178+ LLCC_TRP_ALGO_ALLOC1 ,
179+ LLCC_TRP_ALGO_ALLOC2 ,
180+ LLCC_TRP_ALGO_ALLOC3 ,
181+ LLCC_TRP_WRS_EN ,
182+ LLCC_TRP_WRS_CACHEABLE_EN ,
156183};
157184
158185static const struct llcc_slice_config ipq5424_data [] = {
@@ -3161,6 +3188,33 @@ static const struct llcc_edac_reg_offset llcc_v2_1_edac_reg_offset = {
31613188 .drp_ecc_db_err_syn0 = 0x52120 ,
31623189};
31633190
3191+ static const struct llcc_edac_reg_offset llcc_v6_edac_reg_offset = {
3192+ .trp_ecc_error_status0 = 0x47448 ,
3193+ .trp_ecc_error_status1 = 0x47450 ,
3194+ .trp_ecc_sb_err_syn0 = 0x47490 ,
3195+ .trp_ecc_db_err_syn0 = 0x474d0 ,
3196+ .trp_ecc_error_cntr_clear = 0x47444 ,
3197+ .trp_interrupt_0_status = 0x47600 ,
3198+ .trp_interrupt_0_clear = 0x47604 ,
3199+ .trp_interrupt_0_enable = 0x47608 ,
3200+
3201+ /* LLCC Common registers */
3202+ .cmn_status0 = 0x6400c ,
3203+ .cmn_interrupt_0_enable = 0x6401c ,
3204+ .cmn_interrupt_2_enable = 0x6403c ,
3205+
3206+ /* LLCC DRP registers */
3207+ .drp_ecc_error_cfg = 0x80000 ,
3208+ .drp_ecc_error_cntr_clear = 0x80004 ,
3209+ .drp_interrupt_status = 0x80020 ,
3210+ .drp_interrupt_clear = 0x80028 ,
3211+ .drp_interrupt_enable = 0x8002c ,
3212+ .drp_ecc_error_status0 = 0x820f4 ,
3213+ .drp_ecc_error_status1 = 0x820f8 ,
3214+ .drp_ecc_sb_err_syn0 = 0x820fc ,
3215+ .drp_ecc_db_err_syn0 = 0x82120 ,
3216+ };
3217+
31643218/* LLCC register offset starting from v1.0.0 */
31653219static const u32 llcc_v1_reg_offset [] = {
31663220 [LLCC_COMMON_HW_INFO ] = 0x00030000 ,
@@ -3173,6 +3227,27 @@ static const u32 llcc_v2_1_reg_offset[] = {
31733227 [LLCC_COMMON_STATUS0 ] = 0x0003400c ,
31743228};
31753229
3230+ /* LLCC register offset starting from v6.0.0 */
3231+ static const u32 llcc_v6_reg_offset [] = {
3232+ [LLCC_COMMON_HW_INFO ] = 0x00064000 ,
3233+ [LLCC_COMMON_STATUS0 ] = 0x0006400c ,
3234+ [LLCC_TRP_ATTR0_CFG ] = 0x00041000 ,
3235+ [LLCC_TRP_ATTR1_CFG ] = 0x00041008 ,
3236+ [LLCC_TRP_ATTR2_CFG ] = 0x00041010 ,
3237+ [LLCC_TRP_ATTR3_CFG ] = 0x00041014 ,
3238+ [LLCC_TRP_SID_DIS_CAP_ALLOC ] = 0x00042000 ,
3239+ [LLCC_TRP_ALGO_STALE_EN ] = 0x00042008 ,
3240+ [LLCC_TRP_ALGO_STALE_CAP_EN ] = 0x00042010 ,
3241+ [LLCC_TRP_ALGO_MRU0 ] = 0x00042018 ,
3242+ [LLCC_TRP_ALGO_MRU1 ] = 0x00042020 ,
3243+ [LLCC_TRP_ALGO_ALLOC0 ] = 0x00042028 ,
3244+ [LLCC_TRP_ALGO_ALLOC1 ] = 0x00042030 ,
3245+ [LLCC_TRP_ALGO_ALLOC2 ] = 0x00042038 ,
3246+ [LLCC_TRP_ALGO_ALLOC3 ] = 0x00042040 ,
3247+ [LLCC_TRP_WRS_EN ] = 0x00042080 ,
3248+ [LLCC_TRP_WRS_CACHEABLE_EN ] = 0x00042088 ,
3249+ };
3250+
31763251static const struct qcom_llcc_config qcs615_cfg [] = {
31773252 {
31783253 .sct_data = qcs615_data ,
@@ -3869,6 +3944,139 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
38693944 return ret ;
38703945}
38713946
3947+ static int _qcom_llcc_cfg_program_v6 (const struct llcc_slice_config * config ,
3948+ const struct qcom_llcc_config * cfg )
3949+ {
3950+ u32 stale_en , stale_cap_en , mru_uncap_en , mru_rollover ;
3951+ u32 alloc_oneway_en , ovcap_en , ovcap_prio , vict_prio ;
3952+ u32 attr0_cfg , attr1_cfg , attr2_cfg , attr3_cfg ;
3953+ u32 attr0_val , attr1_val , attr2_val , attr3_val ;
3954+ u32 slice_offset , reg_offset ;
3955+ struct llcc_slice_desc * desc ;
3956+ u32 wren , wr_cache_en ;
3957+ int ret ;
3958+
3959+ attr0_cfg = LLCC_V6_TRP_ATTR0_CFGn (config -> slice_id );
3960+ attr1_cfg = LLCC_V6_TRP_ATTR1_CFGn (config -> slice_id );
3961+ attr2_cfg = LLCC_V6_TRP_ATTR2_CFGn (config -> slice_id );
3962+ attr3_cfg = LLCC_V6_TRP_ATTR3_CFGn (config -> slice_id );
3963+
3964+ attr0_val = config -> res_ways ;
3965+ attr1_val = config -> bonus_ways ;
3966+ attr2_val = config -> cache_mode ;
3967+ attr2_val |= FIELD_PREP (ATTR2_PROBE_TARGET_WAYS_MASK , config -> probe_target_ways );
3968+ attr2_val |= FIELD_PREP (ATTR2_FIXED_SIZE_MASK , config -> fixed_size );
3969+ attr2_val |= FIELD_PREP (ATTR2_PRIORITY_MASK , config -> priority );
3970+
3971+ if (config -> parent_slice_id && config -> fixed_size ) {
3972+ attr2_val |= FIELD_PREP (ATTR2_PARENT_SCID_MASK , config -> parent_slice_id );
3973+ attr2_val |= ATTR2_IN_A_GROUP_MASK ;
3974+ }
3975+
3976+ attr3_val = MAX_CAP_TO_BYTES (config -> max_cap );
3977+ attr3_val /= drv_data -> num_banks ;
3978+ attr3_val >>= CACHE_LINE_SIZE_SHIFT ;
3979+
3980+ ret = regmap_write (drv_data -> bcast_regmap , attr0_cfg , attr0_val );
3981+ if (ret )
3982+ return ret ;
3983+
3984+ ret = regmap_write (drv_data -> bcast_regmap , attr1_cfg , attr1_val );
3985+ if (ret )
3986+ return ret ;
3987+
3988+ ret = regmap_write (drv_data -> bcast_regmap , attr2_cfg , attr2_val );
3989+ if (ret )
3990+ return ret ;
3991+
3992+ ret = regmap_write (drv_data -> bcast_regmap , attr3_cfg , attr3_val );
3993+ if (ret )
3994+ return ret ;
3995+
3996+ slice_offset = config -> slice_id % 32 ;
3997+ reg_offset = (config -> slice_id / 32 ) * 4 ;
3998+
3999+ wren = config -> write_scid_en << slice_offset ;
4000+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4001+ cfg -> reg_offset [LLCC_TRP_WRS_EN ] + reg_offset ,
4002+ BIT (slice_offset ), wren );
4003+ if (ret )
4004+ return ret ;
4005+
4006+ wr_cache_en = config -> write_scid_cacheable_en << slice_offset ;
4007+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4008+ cfg -> reg_offset [LLCC_TRP_WRS_CACHEABLE_EN ] + reg_offset ,
4009+ BIT (slice_offset ), wr_cache_en );
4010+ if (ret )
4011+ return ret ;
4012+
4013+ stale_en = config -> stale_en << slice_offset ;
4014+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4015+ cfg -> reg_offset [LLCC_TRP_ALGO_STALE_EN ] + reg_offset ,
4016+ BIT (slice_offset ), stale_en );
4017+ if (ret )
4018+ return ret ;
4019+
4020+ stale_cap_en = config -> stale_cap_en << slice_offset ;
4021+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4022+ cfg -> reg_offset [LLCC_TRP_ALGO_STALE_CAP_EN ] + reg_offset ,
4023+ BIT (slice_offset ), stale_cap_en );
4024+ if (ret )
4025+ return ret ;
4026+
4027+ mru_uncap_en = config -> mru_uncap_en << slice_offset ;
4028+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4029+ cfg -> reg_offset [LLCC_TRP_ALGO_MRU0 ] + reg_offset ,
4030+ BIT (slice_offset ), mru_uncap_en );
4031+ if (ret )
4032+ return ret ;
4033+
4034+ mru_rollover = config -> mru_rollover << slice_offset ;
4035+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4036+ cfg -> reg_offset [LLCC_TRP_ALGO_MRU1 ] + reg_offset ,
4037+ BIT (slice_offset ), mru_rollover );
4038+ if (ret )
4039+ return ret ;
4040+
4041+ alloc_oneway_en = config -> alloc_oneway_en << slice_offset ;
4042+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4043+ cfg -> reg_offset [LLCC_TRP_ALGO_ALLOC0 ] + reg_offset ,
4044+ BIT (slice_offset ), alloc_oneway_en );
4045+ if (ret )
4046+ return ret ;
4047+
4048+ ovcap_en = config -> ovcap_en << slice_offset ;
4049+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4050+ cfg -> reg_offset [LLCC_TRP_ALGO_ALLOC1 ] + reg_offset ,
4051+ BIT (slice_offset ), ovcap_en );
4052+ if (ret )
4053+ return ret ;
4054+
4055+ ovcap_prio = config -> ovcap_prio << slice_offset ;
4056+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4057+ cfg -> reg_offset [LLCC_TRP_ALGO_ALLOC2 ] + reg_offset ,
4058+ BIT (slice_offset ), ovcap_prio );
4059+ if (ret )
4060+ return ret ;
4061+
4062+ vict_prio = config -> vict_prio << slice_offset ;
4063+ ret = regmap_update_bits (drv_data -> bcast_regmap ,
4064+ cfg -> reg_offset [LLCC_TRP_ALGO_ALLOC3 ] + reg_offset ,
4065+ BIT (slice_offset ), vict_prio );
4066+ if (ret )
4067+ return ret ;
4068+
4069+ if (config -> activate_on_init ) {
4070+ desc = llcc_slice_getd (config -> usecase_id );
4071+ if (PTR_ERR_OR_ZERO (desc ))
4072+ return - EINVAL ;
4073+
4074+ ret = llcc_slice_activate (desc );
4075+ }
4076+
4077+ return ret ;
4078+ }
4079+
38724080static int qcom_llcc_cfg_program (struct platform_device * pdev ,
38734081 const struct qcom_llcc_config * cfg )
38744082{
@@ -3880,10 +4088,18 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev,
38804088 sz = drv_data -> cfg_size ;
38814089 llcc_table = drv_data -> cfg ;
38824090
3883- for (i = 0 ; i < sz ; i ++ ) {
3884- ret = _qcom_llcc_cfg_program (& llcc_table [i ], cfg );
3885- if (ret )
3886- return ret ;
4091+ if (drv_data -> version >= LLCC_VERSION_6_0_0_0 ) {
4092+ for (i = 0 ; i < sz ; i ++ ) {
4093+ ret = _qcom_llcc_cfg_program_v6 (& llcc_table [i ], cfg );
4094+ if (ret )
4095+ return ret ;
4096+ }
4097+ } else {
4098+ for (i = 0 ; i < sz ; i ++ ) {
4099+ ret = _qcom_llcc_cfg_program (& llcc_table [i ], cfg );
4100+ if (ret )
4101+ return ret ;
4102+ }
38874103 }
38884104
38894105 return ret ;
0 commit comments