35
35
#define ATTR0_RES_WAYS_MASK GENMASK(15, 0)
36
36
#define ATTR0_BONUS_WAYS_MASK GENMASK(31, 16)
37
37
#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)
38
43
#define LLCC_STATUS_READ_DELAY 100
39
44
40
45
#define CACHE_LINE_SIZE_SHIFT 6
49
54
#define LLCC_TRP_ATTR0_CFGn (n ) (0x21000 + SZ_8 * n)
50
55
#define LLCC_TRP_ATTR1_CFGn (n ) (0x21004 + SZ_8 * n)
51
56
#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))
52
61
53
62
#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00
54
63
#define LLCC_TRP_PCB_ACT 0x21f04
66
75
#define LLCC_VERSION_2_0_0_0 0x02000000
67
76
#define LLCC_VERSION_2_1_0_0 0x02010000
68
77
#define LLCC_VERSION_4_1_0_0 0x04010000
78
+ #define LLCC_VERSION_6_0_0_0 0X06000000
69
79
70
80
/**
71
81
* struct llcc_slice_config - Data associated with the llcc slice
106
116
* ovcap_en.
107
117
* @vict_prio: When current scid is under-capacity, allocate over other
108
118
* lower-than victim priority-line threshold scid.
119
+ * @parent_slice_id: For grouped slices, specifies the slice id of the parent.
109
120
*/
110
121
struct llcc_slice_config {
111
122
u32 usecase_id ;
@@ -130,6 +141,7 @@ struct llcc_slice_config {
130
141
bool ovcap_en ;
131
142
bool ovcap_prio ;
132
143
bool vict_prio ;
144
+ u32 parent_slice_id ;
133
145
};
134
146
135
147
struct qcom_llcc_config {
@@ -153,6 +165,21 @@ struct qcom_sct_config {
153
165
enum llcc_reg_offset {
154
166
LLCC_COMMON_HW_INFO ,
155
167
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 ,
156
183
};
157
184
158
185
static const struct llcc_slice_config ipq5424_data [] = {
@@ -3161,6 +3188,33 @@ static const struct llcc_edac_reg_offset llcc_v2_1_edac_reg_offset = {
3161
3188
.drp_ecc_db_err_syn0 = 0x52120 ,
3162
3189
};
3163
3190
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
+
3164
3218
/* LLCC register offset starting from v1.0.0 */
3165
3219
static const u32 llcc_v1_reg_offset [] = {
3166
3220
[LLCC_COMMON_HW_INFO ] = 0x00030000 ,
@@ -3173,6 +3227,27 @@ static const u32 llcc_v2_1_reg_offset[] = {
3173
3227
[LLCC_COMMON_STATUS0 ] = 0x0003400c ,
3174
3228
};
3175
3229
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
+
3176
3251
static const struct qcom_llcc_config qcs615_cfg [] = {
3177
3252
{
3178
3253
.sct_data = qcs615_data ,
@@ -3869,6 +3944,139 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
3869
3944
return ret ;
3870
3945
}
3871
3946
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
+
3872
4080
static int qcom_llcc_cfg_program (struct platform_device * pdev ,
3873
4081
const struct qcom_llcc_config * cfg )
3874
4082
{
@@ -3880,10 +4088,18 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev,
3880
4088
sz = drv_data -> cfg_size ;
3881
4089
llcc_table = drv_data -> cfg ;
3882
4090
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
+ }
3887
4103
}
3888
4104
3889
4105
return ret ;
0 commit comments