4747#define MLXBF_EDAC_MAX_DIMM_PER_MC 2
4848#define MLXBF_EDAC_ERROR_GRAIN 8
4949
50+ #define MLXBF_WRITE_REG_32 (0x82000009)
51+ #define MLXBF_READ_REG_32 (0x8200000A)
52+ #define MLXBF_SIP_SVC_VERSION (0x8200ff03)
53+
54+ #define MLXBF_SMCCC_ACCESS_VIOLATION (-4)
55+
56+ #define MLXBF_SVC_REQ_MAJOR 0
57+ #define MLXBF_SVC_REQ_MINOR 3
58+
5059/*
51- * Request MLNX_SIP_GET_DIMM_INFO
60+ * Request MLXBF_SIP_GET_DIMM_INFO
5261 *
5362 * Retrieve information about DIMM on a certain slot.
5463 *
5564 * Call register usage:
56- * a0: MLNX_SIP_GET_DIMM_INFO
65+ * a0: MLXBF_SIP_GET_DIMM_INFO
5766 * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
5867 * a2-7: not used.
5968 *
6069 * Return status:
6170 * a0: MLXBF_DIMM_INFO defined below describing the DIMM.
6271 * a1-3: not used.
6372 */
64- #define MLNX_SIP_GET_DIMM_INFO 0x82000008
73+ #define MLXBF_SIP_GET_DIMM_INFO 0x82000008
6574
6675/* Format for the SMC response about the memory information */
6776#define MLXBF_DIMM_INFO__SIZE_GB GENMASK_ULL(15, 0)
7281#define MLXBF_DIMM_INFO__PACKAGE_X GENMASK_ULL(31, 24)
7382
7483struct bluefield_edac_priv {
84+ /* pointer to device structure */
85+ struct device * dev ;
7586 int dimm_ranks [MLXBF_EDAC_MAX_DIMM_PER_MC ];
7687 void __iomem * emi_base ;
7788 int dimm_per_mc ;
89+ /* access to secure regs supported */
90+ bool svc_sreg_support ;
91+ /* SMC table# for secure regs access */
92+ u32 sreg_tbl ;
7893};
7994
8095static u64 smc_call1 (u64 smc_op , u64 smc_arg )
@@ -86,6 +101,71 @@ static u64 smc_call1(u64 smc_op, u64 smc_arg)
86101 return res .a0 ;
87102}
88103
104+ static int secure_readl (void __iomem * addr , u32 * result , u32 sreg_tbl )
105+ {
106+ struct arm_smccc_res res ;
107+ int status ;
108+
109+ arm_smccc_smc (MLXBF_READ_REG_32 , sreg_tbl , (uintptr_t )addr ,
110+ 0 , 0 , 0 , 0 , 0 , & res );
111+
112+ status = res .a0 ;
113+
114+ if (status == SMCCC_RET_NOT_SUPPORTED ||
115+ status == MLXBF_SMCCC_ACCESS_VIOLATION )
116+ return -1 ;
117+
118+ * result = (u32 )res .a1 ;
119+ return 0 ;
120+ }
121+
122+ static int secure_writel (void __iomem * addr , u32 data , u32 sreg_tbl )
123+ {
124+ struct arm_smccc_res res ;
125+ int status ;
126+
127+ arm_smccc_smc (MLXBF_WRITE_REG_32 , sreg_tbl , data , (uintptr_t )addr ,
128+ 0 , 0 , 0 , 0 , & res );
129+
130+ status = res .a0 ;
131+
132+ if (status == SMCCC_RET_NOT_SUPPORTED ||
133+ status == MLXBF_SMCCC_ACCESS_VIOLATION )
134+ return -1 ;
135+ else
136+ return 0 ;
137+ }
138+
139+ static int bluefield_edac_readl (struct bluefield_edac_priv * priv , u32 offset , u32 * result )
140+ {
141+ void __iomem * addr ;
142+ int err = 0 ;
143+
144+ addr = priv -> emi_base + offset ;
145+
146+ if (priv -> svc_sreg_support )
147+ err = secure_readl (addr , result , priv -> sreg_tbl );
148+ else
149+ * result = readl (addr );
150+
151+ return err ;
152+ }
153+
154+ static int bluefield_edac_writel (struct bluefield_edac_priv * priv , u32 offset , u32 data )
155+ {
156+ void __iomem * addr ;
157+ int err = 0 ;
158+
159+ addr = priv -> emi_base + offset ;
160+
161+ if (priv -> svc_sreg_support )
162+ err = secure_writel (addr , data , priv -> sreg_tbl );
163+ else
164+ writel (data , addr );
165+
166+ return err ;
167+ }
168+
89169/*
90170 * Gather the ECC information from the External Memory Interface registers
91171 * and report it to the edac handler.
@@ -99,7 +179,7 @@ static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
99179 u32 ecc_latch_select , dram_syndrom , serr , derr , syndrom ;
100180 enum hw_event_mc_err_type ecc_type ;
101181 u64 ecc_dimm_addr ;
102- int ecc_dimm ;
182+ int ecc_dimm , err ;
103183
104184 ecc_type = is_single_ecc ? HW_EVENT_ERR_CORRECTED :
105185 HW_EVENT_ERR_UNCORRECTED ;
@@ -109,14 +189,19 @@ static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
109189 * registers with information about the last ECC error occurrence.
110190 */
111191 ecc_latch_select = MLXBF_ECC_LATCH_SEL__START ;
112- writel (ecc_latch_select , priv -> emi_base + MLXBF_ECC_LATCH_SEL );
192+ err = bluefield_edac_writel (priv , MLXBF_ECC_LATCH_SEL , ecc_latch_select );
193+ if (err )
194+ dev_err (priv -> dev , "ECC latch select write failed.\n" );
113195
114196 /*
115197 * Verify that the ECC reported info in the registers is of the
116198 * same type as the one asked to report. If not, just report the
117199 * error without the detailed information.
118200 */
119- dram_syndrom = readl (priv -> emi_base + MLXBF_SYNDROM );
201+ err = bluefield_edac_readl (priv , MLXBF_SYNDROM , & dram_syndrom );
202+ if (err )
203+ dev_err (priv -> dev , "DRAM syndrom read failed.\n" );
204+
120205 serr = FIELD_GET (MLXBF_SYNDROM__SERR , dram_syndrom );
121206 derr = FIELD_GET (MLXBF_SYNDROM__DERR , dram_syndrom );
122207 syndrom = FIELD_GET (MLXBF_SYNDROM__SYN , dram_syndrom );
@@ -127,13 +212,21 @@ static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
127212 return ;
128213 }
129214
130- dram_additional_info = readl (priv -> emi_base + MLXBF_ADD_INFO );
215+ err = bluefield_edac_readl (priv , MLXBF_ADD_INFO , & dram_additional_info );
216+ if (err )
217+ dev_err (priv -> dev , "DRAM additional info read failed.\n" );
218+
131219 err_prank = FIELD_GET (MLXBF_ADD_INFO__ERR_PRANK , dram_additional_info );
132220
133221 ecc_dimm = (err_prank >= 2 && priv -> dimm_ranks [0 ] <= 2 ) ? 1 : 0 ;
134222
135- edea0 = readl (priv -> emi_base + MLXBF_ERR_ADDR_0 );
136- edea1 = readl (priv -> emi_base + MLXBF_ERR_ADDR_1 );
223+ err = bluefield_edac_readl (priv , MLXBF_ERR_ADDR_0 , & edea0 );
224+ if (err )
225+ dev_err (priv -> dev , "Error addr 0 read failed.\n" );
226+
227+ err = bluefield_edac_readl (priv , MLXBF_ERR_ADDR_1 , & edea1 );
228+ if (err )
229+ dev_err (priv -> dev , "Error addr 1 read failed.\n" );
137230
138231 ecc_dimm_addr = ((u64 )edea1 << 32 ) | edea0 ;
139232
@@ -147,6 +240,7 @@ static void bluefield_edac_check(struct mem_ctl_info *mci)
147240{
148241 struct bluefield_edac_priv * priv = mci -> pvt_info ;
149242 u32 ecc_count , single_error_count , double_error_count , ecc_error = 0 ;
243+ int err ;
150244
151245 /*
152246 * The memory controller might not be initialized by the firmware
@@ -155,7 +249,10 @@ static void bluefield_edac_check(struct mem_ctl_info *mci)
155249 if (mci -> edac_cap == EDAC_FLAG_NONE )
156250 return ;
157251
158- ecc_count = readl (priv -> emi_base + MLXBF_ECC_CNT );
252+ err = bluefield_edac_readl (priv , MLXBF_ECC_CNT , & ecc_count );
253+ if (err )
254+ dev_err (priv -> dev , "ECC count read failed.\n" );
255+
159256 single_error_count = FIELD_GET (MLXBF_ECC_CNT__SERR_CNT , ecc_count );
160257 double_error_count = FIELD_GET (MLXBF_ECC_CNT__DERR_CNT , ecc_count );
161258
@@ -172,8 +269,11 @@ static void bluefield_edac_check(struct mem_ctl_info *mci)
172269 }
173270
174271 /* Write to clear reported errors. */
175- if (ecc_count )
176- writel (ecc_error , priv -> emi_base + MLXBF_ECC_ERR );
272+ if (ecc_count ) {
273+ err = bluefield_edac_writel (priv , MLXBF_ECC_ERR , ecc_error );
274+ if (err )
275+ dev_err (priv -> dev , "ECC Error write failed.\n" );
276+ }
177277}
178278
179279/* Initialize the DIMMs information for the given memory controller. */
@@ -189,7 +289,7 @@ static void bluefield_edac_init_dimms(struct mem_ctl_info *mci)
189289 dimm = mci -> dimms [i ];
190290
191291 smc_arg = mem_ctrl_idx << 16 | i ;
192- smc_info = smc_call1 (MLNX_SIP_GET_DIMM_INFO , smc_arg );
292+ smc_info = smc_call1 (MLXBF_SIP_GET_DIMM_INFO , smc_arg );
193293
194294 if (!FIELD_GET (MLXBF_DIMM_INFO__SIZE_GB , smc_info )) {
195295 dimm -> mtype = MEM_EMPTY ;
@@ -244,6 +344,7 @@ static int bluefield_edac_mc_probe(struct platform_device *pdev)
244344 struct bluefield_edac_priv * priv ;
245345 struct device * dev = & pdev -> dev ;
246346 struct edac_mc_layer layers [1 ];
347+ struct arm_smccc_res res ;
247348 struct mem_ctl_info * mci ;
248349 struct resource * emi_res ;
249350 unsigned int mc_idx , dimm_count ;
@@ -279,13 +380,43 @@ static int bluefield_edac_mc_probe(struct platform_device *pdev)
279380 return - ENOMEM ;
280381
281382 priv = mci -> pvt_info ;
383+ priv -> dev = dev ;
384+
385+ /*
386+ * The "sec_reg_block" property in the ACPI table determines the method
387+ * the driver uses to access the EMI registers:
388+ * a) property is not present - directly access registers via readl/writel
389+ * b) property is present - indirectly access registers via SMC calls
390+ * (assuming required Silicon Provider service version found)
391+ */
392+ if (device_property_read_u32 (dev , "sec_reg_block" , & priv -> sreg_tbl )) {
393+ priv -> svc_sreg_support = false;
394+ } else {
395+ /*
396+ * Check for minimum required Arm Silicon Provider (SiP) service
397+ * version, ensuring support of required SMC function IDs.
398+ */
399+ arm_smccc_smc (MLXBF_SIP_SVC_VERSION , 0 , 0 , 0 , 0 , 0 , 0 , 0 , & res );
400+ if (res .a0 == MLXBF_SVC_REQ_MAJOR &&
401+ res .a1 >= MLXBF_SVC_REQ_MINOR ) {
402+ priv -> svc_sreg_support = true;
403+ } else {
404+ dev_err (dev , "Required SMCs are not supported.\n" );
405+ ret = - EINVAL ;
406+ goto err ;
407+ }
408+ }
282409
283410 priv -> dimm_per_mc = dimm_count ;
284- priv -> emi_base = devm_ioremap_resource (dev , emi_res );
285- if (IS_ERR (priv -> emi_base )) {
286- dev_err (dev , "failed to map EMI IO resource\n" );
287- ret = PTR_ERR (priv -> emi_base );
288- goto err ;
411+ if (!priv -> svc_sreg_support ) {
412+ priv -> emi_base = devm_ioremap_resource (dev , emi_res );
413+ if (IS_ERR (priv -> emi_base )) {
414+ dev_err (dev , "failed to map EMI IO resource\n" );
415+ ret = PTR_ERR (priv -> emi_base );
416+ goto err ;
417+ }
418+ } else {
419+ priv -> emi_base = (void __iomem * )emi_res -> start ;
289420 }
290421
291422 mci -> pdev = dev ;
@@ -320,7 +451,6 @@ static int bluefield_edac_mc_probe(struct platform_device *pdev)
320451 edac_mc_free (mci );
321452
322453 return ret ;
323-
324454}
325455
326456static void bluefield_edac_mc_remove (struct platform_device * pdev )
0 commit comments