Skip to content

Commit cbd7711

Browse files
Mani-Sadhasivamandersson
authored andcommitted
EDAC/qcom: Get rid of hardcoded register offsets
The LLCC EDAC register offsets varies between each SoC. Hardcoding the register offsets won't work and will often result in crash due to accessing the wrong locations. Hence, get the register offsets from the LLCC driver matching the individual SoCs. Cc: <[email protected]> # 6.0: 5365cea ("soc: qcom: llcc: Rename reg_offset structs to reflect LLCC version") Cc: <[email protected]> # 6.0: c13d7d2 ("soc: qcom: llcc: Pass LLCC version based register offsets to EDAC driver") Cc: <[email protected]> # 6.0 Fixes: a6e9d7e ("soc: qcom: llcc: Add configuration data for SM8450 SoC") Acked-by: Borislav Petkov (AMD) <[email protected]> Signed-off-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Bjorn Andersson <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 3d49f74 commit cbd7711

File tree

2 files changed

+58
-64
lines changed

2 files changed

+58
-64
lines changed

drivers/edac/qcom_edac.c

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,9 @@
2121
#define TRP_SYN_REG_CNT 6
2222
#define DRP_SYN_REG_CNT 8
2323

24-
#define LLCC_COMMON_STATUS0 0x0003000c
2524
#define LLCC_LB_CNT_MASK GENMASK(31, 28)
2625
#define LLCC_LB_CNT_SHIFT 28
2726

28-
/* Single & double bit syndrome register offsets */
29-
#define TRP_ECC_SB_ERR_SYN0 0x0002304c
30-
#define TRP_ECC_DB_ERR_SYN0 0x00020370
31-
#define DRP_ECC_SB_ERR_SYN0 0x0004204c
32-
#define DRP_ECC_DB_ERR_SYN0 0x00042070
33-
34-
/* Error register offsets */
35-
#define TRP_ECC_ERROR_STATUS1 0x00020348
36-
#define TRP_ECC_ERROR_STATUS0 0x00020344
37-
#define DRP_ECC_ERROR_STATUS1 0x00042048
38-
#define DRP_ECC_ERROR_STATUS0 0x00042044
39-
40-
/* TRP, DRP interrupt register offsets */
41-
#define DRP_INTERRUPT_STATUS 0x00041000
42-
#define TRP_INTERRUPT_0_STATUS 0x00020480
43-
#define DRP_INTERRUPT_CLEAR 0x00041008
44-
#define DRP_ECC_ERROR_CNTR_CLEAR 0x00040004
45-
#define TRP_INTERRUPT_0_CLEAR 0x00020484
46-
#define TRP_ECC_ERROR_CNTR_CLEAR 0x00020440
47-
4827
/* Mask and shift macros */
4928
#define ECC_DB_ERR_COUNT_MASK GENMASK(4, 0)
5029
#define ECC_DB_ERR_WAYS_MASK GENMASK(31, 16)
@@ -60,15 +39,6 @@
6039
#define DRP_TRP_INT_CLEAR GENMASK(1, 0)
6140
#define DRP_TRP_CNT_CLEAR GENMASK(1, 0)
6241

63-
/* Config registers offsets*/
64-
#define DRP_ECC_ERROR_CFG 0x00040000
65-
66-
/* Tag RAM, Data RAM interrupt register offsets */
67-
#define CMN_INTERRUPT_0_ENABLE 0x0003001c
68-
#define CMN_INTERRUPT_2_ENABLE 0x0003003c
69-
#define TRP_INTERRUPT_0_ENABLE 0x00020488
70-
#define DRP_INTERRUPT_ENABLE 0x0004100c
71-
7242
#define SB_ERROR_THRESHOLD 0x1
7343
#define SB_ERROR_THRESHOLD_SHIFT 24
7444
#define SB_DB_TRP_INTERRUPT_ENABLE 0x3
@@ -88,47 +58,35 @@ enum {
8858
static const struct llcc_edac_reg_data edac_reg_data[] = {
8959
[LLCC_DRAM_CE] = {
9060
.name = "DRAM Single-bit",
91-
.synd_reg = DRP_ECC_SB_ERR_SYN0,
92-
.count_status_reg = DRP_ECC_ERROR_STATUS1,
93-
.ways_status_reg = DRP_ECC_ERROR_STATUS0,
9461
.reg_cnt = DRP_SYN_REG_CNT,
9562
.count_mask = ECC_SB_ERR_COUNT_MASK,
9663
.ways_mask = ECC_SB_ERR_WAYS_MASK,
9764
.count_shift = ECC_SB_ERR_COUNT_SHIFT,
9865
},
9966
[LLCC_DRAM_UE] = {
10067
.name = "DRAM Double-bit",
101-
.synd_reg = DRP_ECC_DB_ERR_SYN0,
102-
.count_status_reg = DRP_ECC_ERROR_STATUS1,
103-
.ways_status_reg = DRP_ECC_ERROR_STATUS0,
10468
.reg_cnt = DRP_SYN_REG_CNT,
10569
.count_mask = ECC_DB_ERR_COUNT_MASK,
10670
.ways_mask = ECC_DB_ERR_WAYS_MASK,
10771
.ways_shift = ECC_DB_ERR_WAYS_SHIFT,
10872
},
10973
[LLCC_TRAM_CE] = {
11074
.name = "TRAM Single-bit",
111-
.synd_reg = TRP_ECC_SB_ERR_SYN0,
112-
.count_status_reg = TRP_ECC_ERROR_STATUS1,
113-
.ways_status_reg = TRP_ECC_ERROR_STATUS0,
11475
.reg_cnt = TRP_SYN_REG_CNT,
11576
.count_mask = ECC_SB_ERR_COUNT_MASK,
11677
.ways_mask = ECC_SB_ERR_WAYS_MASK,
11778
.count_shift = ECC_SB_ERR_COUNT_SHIFT,
11879
},
11980
[LLCC_TRAM_UE] = {
12081
.name = "TRAM Double-bit",
121-
.synd_reg = TRP_ECC_DB_ERR_SYN0,
122-
.count_status_reg = TRP_ECC_ERROR_STATUS1,
123-
.ways_status_reg = TRP_ECC_ERROR_STATUS0,
12482
.reg_cnt = TRP_SYN_REG_CNT,
12583
.count_mask = ECC_DB_ERR_COUNT_MASK,
12684
.ways_mask = ECC_DB_ERR_WAYS_MASK,
12785
.ways_shift = ECC_DB_ERR_WAYS_SHIFT,
12886
},
12987
};
13088

131-
static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap)
89+
static int qcom_llcc_core_setup(struct llcc_drv_data *drv, struct regmap *llcc_bcast_regmap)
13290
{
13391
u32 sb_err_threshold;
13492
int ret;
@@ -137,31 +95,31 @@ static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap)
13795
* Configure interrupt enable registers such that Tag, Data RAM related
13896
* interrupts are propagated to interrupt controller for servicing
13997
*/
140-
ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE,
98+
ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable,
14199
TRP0_INTERRUPT_ENABLE,
142100
TRP0_INTERRUPT_ENABLE);
143101
if (ret)
144102
return ret;
145103

146-
ret = regmap_update_bits(llcc_bcast_regmap, TRP_INTERRUPT_0_ENABLE,
104+
ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->trp_interrupt_0_enable,
147105
SB_DB_TRP_INTERRUPT_ENABLE,
148106
SB_DB_TRP_INTERRUPT_ENABLE);
149107
if (ret)
150108
return ret;
151109

152110
sb_err_threshold = (SB_ERROR_THRESHOLD << SB_ERROR_THRESHOLD_SHIFT);
153-
ret = regmap_write(llcc_bcast_regmap, DRP_ECC_ERROR_CFG,
111+
ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_ecc_error_cfg,
154112
sb_err_threshold);
155113
if (ret)
156114
return ret;
157115

158-
ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE,
116+
ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable,
159117
DRP0_INTERRUPT_ENABLE,
160118
DRP0_INTERRUPT_ENABLE);
161119
if (ret)
162120
return ret;
163121

164-
ret = regmap_write(llcc_bcast_regmap, DRP_INTERRUPT_ENABLE,
122+
ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_interrupt_enable,
165123
SB_DB_DRP_INTERRUPT_ENABLE);
166124
return ret;
167125
}
@@ -175,24 +133,28 @@ qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv)
175133
switch (err_type) {
176134
case LLCC_DRAM_CE:
177135
case LLCC_DRAM_UE:
178-
ret = regmap_write(drv->bcast_regmap, DRP_INTERRUPT_CLEAR,
136+
ret = regmap_write(drv->bcast_regmap,
137+
drv->edac_reg_offset->drp_interrupt_clear,
179138
DRP_TRP_INT_CLEAR);
180139
if (ret)
181140
return ret;
182141

183-
ret = regmap_write(drv->bcast_regmap, DRP_ECC_ERROR_CNTR_CLEAR,
142+
ret = regmap_write(drv->bcast_regmap,
143+
drv->edac_reg_offset->drp_ecc_error_cntr_clear,
184144
DRP_TRP_CNT_CLEAR);
185145
if (ret)
186146
return ret;
187147
break;
188148
case LLCC_TRAM_CE:
189149
case LLCC_TRAM_UE:
190-
ret = regmap_write(drv->bcast_regmap, TRP_INTERRUPT_0_CLEAR,
150+
ret = regmap_write(drv->bcast_regmap,
151+
drv->edac_reg_offset->trp_interrupt_0_clear,
191152
DRP_TRP_INT_CLEAR);
192153
if (ret)
193154
return ret;
194155

195-
ret = regmap_write(drv->bcast_regmap, TRP_ECC_ERROR_CNTR_CLEAR,
156+
ret = regmap_write(drv->bcast_regmap,
157+
drv->edac_reg_offset->trp_ecc_error_cntr_clear,
196158
DRP_TRP_CNT_CLEAR);
197159
if (ret)
198160
return ret;
@@ -205,16 +167,54 @@ qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv)
205167
return ret;
206168
}
207169

170+
struct qcom_llcc_syn_regs {
171+
u32 synd_reg;
172+
u32 count_status_reg;
173+
u32 ways_status_reg;
174+
};
175+
176+
static void get_reg_offsets(struct llcc_drv_data *drv, int err_type,
177+
struct qcom_llcc_syn_regs *syn_regs)
178+
{
179+
const struct llcc_edac_reg_offset *edac_reg_offset = drv->edac_reg_offset;
180+
181+
switch (err_type) {
182+
case LLCC_DRAM_CE:
183+
syn_regs->synd_reg = edac_reg_offset->drp_ecc_sb_err_syn0;
184+
syn_regs->count_status_reg = edac_reg_offset->drp_ecc_error_status1;
185+
syn_regs->ways_status_reg = edac_reg_offset->drp_ecc_error_status0;
186+
break;
187+
case LLCC_DRAM_UE:
188+
syn_regs->synd_reg = edac_reg_offset->drp_ecc_db_err_syn0;
189+
syn_regs->count_status_reg = edac_reg_offset->drp_ecc_error_status1;
190+
syn_regs->ways_status_reg = edac_reg_offset->drp_ecc_error_status0;
191+
break;
192+
case LLCC_TRAM_CE:
193+
syn_regs->synd_reg = edac_reg_offset->trp_ecc_sb_err_syn0;
194+
syn_regs->count_status_reg = edac_reg_offset->trp_ecc_error_status1;
195+
syn_regs->ways_status_reg = edac_reg_offset->trp_ecc_error_status0;
196+
break;
197+
case LLCC_TRAM_UE:
198+
syn_regs->synd_reg = edac_reg_offset->trp_ecc_db_err_syn0;
199+
syn_regs->count_status_reg = edac_reg_offset->trp_ecc_error_status1;
200+
syn_regs->ways_status_reg = edac_reg_offset->trp_ecc_error_status0;
201+
break;
202+
}
203+
}
204+
208205
/* Dump Syndrome registers data for Tag RAM, Data RAM bit errors*/
209206
static int
210207
dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
211208
{
212209
struct llcc_edac_reg_data reg_data = edac_reg_data[err_type];
210+
struct qcom_llcc_syn_regs regs = { };
213211
int err_cnt, err_ways, ret, i;
214212
u32 synd_reg, synd_val;
215213

214+
get_reg_offsets(drv, err_type, &regs);
215+
216216
for (i = 0; i < reg_data.reg_cnt; i++) {
217-
synd_reg = reg_data.synd_reg + (i * 4);
217+
synd_reg = regs.synd_reg + (i * 4);
218218
ret = regmap_read(drv->regmaps[bank], synd_reg,
219219
&synd_val);
220220
if (ret)
@@ -224,7 +224,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
224224
reg_data.name, i, synd_val);
225225
}
226226

227-
ret = regmap_read(drv->regmaps[bank], reg_data.count_status_reg,
227+
ret = regmap_read(drv->regmaps[bank], regs.count_status_reg,
228228
&err_cnt);
229229
if (ret)
230230
goto clear;
@@ -234,7 +234,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
234234
edac_printk(KERN_CRIT, EDAC_LLCC, "%s: Error count: 0x%4x\n",
235235
reg_data.name, err_cnt);
236236

237-
ret = regmap_read(drv->regmaps[bank], reg_data.ways_status_reg,
237+
ret = regmap_read(drv->regmaps[bank], regs.ways_status_reg,
238238
&err_ways);
239239
if (ret)
240240
goto clear;
@@ -295,7 +295,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl)
295295

296296
/* Iterate over the banks and look for Tag RAM or Data RAM errors */
297297
for (i = 0; i < drv->num_banks; i++) {
298-
ret = regmap_read(drv->regmaps[i], DRP_INTERRUPT_STATUS,
298+
ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->drp_interrupt_status,
299299
&drp_error);
300300

301301
if (!ret && (drp_error & SB_ECC_ERROR)) {
@@ -310,7 +310,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl)
310310
if (!ret)
311311
irq_rc = IRQ_HANDLED;
312312

313-
ret = regmap_read(drv->regmaps[i], TRP_INTERRUPT_0_STATUS,
313+
ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->trp_interrupt_0_status,
314314
&trp_error);
315315

316316
if (!ret && (trp_error & SB_ECC_ERROR)) {
@@ -342,7 +342,7 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
342342
int ecc_irq;
343343
int rc;
344344

345-
rc = qcom_llcc_core_setup(llcc_driv_data->bcast_regmap);
345+
rc = qcom_llcc_core_setup(llcc_driv_data, llcc_driv_data->bcast_regmap);
346346
if (rc)
347347
return rc;
348348

include/linux/soc/qcom/llcc-qcom.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,6 @@ struct llcc_slice_desc {
6969
/**
7070
* struct llcc_edac_reg_data - llcc edac registers data for each error type
7171
* @name: Name of the error
72-
* @synd_reg: Syndrome register address
73-
* @count_status_reg: Status register address to read the error count
74-
* @ways_status_reg: Status register address to read the error ways
7572
* @reg_cnt: Number of registers
7673
* @count_mask: Mask value to get the error count
7774
* @ways_mask: Mask value to get the error ways
@@ -80,9 +77,6 @@ struct llcc_slice_desc {
8077
*/
8178
struct llcc_edac_reg_data {
8279
char *name;
83-
u64 synd_reg;
84-
u64 count_status_reg;
85-
u64 ways_status_reg;
8680
u32 reg_cnt;
8781
u32 count_mask;
8882
u32 ways_mask;

0 commit comments

Comments
 (0)