2 * Cell MIC driver for ECC counting
4 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
7 * This file may be distributed under the terms of the
8 * GNU General Public License.
12 #include <linux/edac.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/stop_machine.h>
18 #include <linux/of_address.h>
19 #include <asm/machdep.h>
20 #include <asm/cell-regs.h>
22 #include "edac_core.h"
26 struct cbe_mic_tm_regs __iomem
*regs
;
34 static void cell_edac_count_ce(struct mem_ctl_info
*mci
, int chan
, u64 ar
)
36 struct cell_edac_priv
*priv
= mci
->pvt_info
;
37 struct csrow_info
*csrow
= mci
->csrows
[0];
38 unsigned long address
, pfn
, offset
, syndrome
;
40 dev_dbg(mci
->pdev
, "ECC CE err on node %d, channel %d, ar = 0x%016llx\n",
41 priv
->node
, chan
, ar
);
43 /* Address decoding is likely a bit bogus, to dbl check */
44 address
= (ar
& 0xffffffffe0000000ul
) >> 29;
45 if (priv
->chanmask
== 0x3)
46 address
= (address
<< 1) | chan
;
47 pfn
= address
>> PAGE_SHIFT
;
48 offset
= address
& ~PAGE_MASK
;
49 syndrome
= (ar
& 0x000000001fe00000ul
) >> 21;
51 /* TODO: Decoding of the error address */
52 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED
, mci
, 1,
53 csrow
->first_page
+ pfn
, offset
, syndrome
,
57 static void cell_edac_count_ue(struct mem_ctl_info
*mci
, int chan
, u64 ar
)
59 struct cell_edac_priv
*priv
= mci
->pvt_info
;
60 struct csrow_info
*csrow
= mci
->csrows
[0];
61 unsigned long address
, pfn
, offset
;
63 dev_dbg(mci
->pdev
, "ECC UE err on node %d, channel %d, ar = 0x%016llx\n",
64 priv
->node
, chan
, ar
);
66 /* Address decoding is likely a bit bogus, to dbl check */
67 address
= (ar
& 0xffffffffe0000000ul
) >> 29;
68 if (priv
->chanmask
== 0x3)
69 address
= (address
<< 1) | chan
;
70 pfn
= address
>> PAGE_SHIFT
;
71 offset
= address
& ~PAGE_MASK
;
73 /* TODO: Decoding of the error address */
74 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED
, mci
, 1,
75 csrow
->first_page
+ pfn
, offset
, 0,
79 static void cell_edac_check(struct mem_ctl_info
*mci
)
81 struct cell_edac_priv
*priv
= mci
->pvt_info
;
82 u64 fir
, addreg
, clear
= 0;
84 fir
= in_be64(&priv
->regs
->mic_fir
);
86 if (fir
!= priv
->prev_fir
) {
87 dev_dbg(mci
->pdev
, "fir change : 0x%016lx\n", fir
);
91 if ((priv
->chanmask
& 0x1) && (fir
& CBE_MIC_FIR_ECC_SINGLE_0_ERR
)) {
92 addreg
= in_be64(&priv
->regs
->mic_df_ecc_address_0
);
93 clear
|= CBE_MIC_FIR_ECC_SINGLE_0_RESET
;
94 cell_edac_count_ce(mci
, 0, addreg
);
96 if ((priv
->chanmask
& 0x2) && (fir
& CBE_MIC_FIR_ECC_SINGLE_1_ERR
)) {
97 addreg
= in_be64(&priv
->regs
->mic_df_ecc_address_1
);
98 clear
|= CBE_MIC_FIR_ECC_SINGLE_1_RESET
;
99 cell_edac_count_ce(mci
, 1, addreg
);
101 if ((priv
->chanmask
& 0x1) && (fir
& CBE_MIC_FIR_ECC_MULTI_0_ERR
)) {
102 addreg
= in_be64(&priv
->regs
->mic_df_ecc_address_0
);
103 clear
|= CBE_MIC_FIR_ECC_MULTI_0_RESET
;
104 cell_edac_count_ue(mci
, 0, addreg
);
106 if ((priv
->chanmask
& 0x2) && (fir
& CBE_MIC_FIR_ECC_MULTI_1_ERR
)) {
107 addreg
= in_be64(&priv
->regs
->mic_df_ecc_address_1
);
108 clear
|= CBE_MIC_FIR_ECC_MULTI_1_RESET
;
109 cell_edac_count_ue(mci
, 1, addreg
);
112 /* The procedure for clearing FIR bits is a bit ... weird */
114 fir
&= ~(CBE_MIC_FIR_ECC_ERR_MASK
| CBE_MIC_FIR_ECC_SET_MASK
);
115 fir
|= CBE_MIC_FIR_ECC_RESET_MASK
;
117 out_be64(&priv
->regs
->mic_fir
, fir
);
118 (void)in_be64(&priv
->regs
->mic_fir
);
122 fir
= in_be64(&priv
->regs
->mic_fir
);
123 dev_dbg(mci
->pdev
, "fir clear : 0x%016lx\n", fir
);
128 static void cell_edac_init_csrows(struct mem_ctl_info
*mci
)
130 struct csrow_info
*csrow
= mci
->csrows
[0];
131 struct dimm_info
*dimm
;
132 struct cell_edac_priv
*priv
= mci
->pvt_info
;
133 struct device_node
*np
;
137 for_each_node_by_name(np
, "memory") {
140 /* We "know" that the Cell firmware only creates one entry
141 * in the "memory" nodes. If that changes, this code will
142 * need to be adapted.
144 if (of_address_to_resource(np
, 0, &r
))
146 if (of_node_to_nid(np
) != priv
->node
)
148 csrow
->first_page
= r
.start
>> PAGE_SHIFT
;
149 nr_pages
= resource_size(&r
) >> PAGE_SHIFT
;
150 csrow
->last_page
= csrow
->first_page
+ nr_pages
- 1;
152 for (j
= 0; j
< csrow
->nr_channels
; j
++) {
153 dimm
= csrow
->channels
[j
]->dimm
;
154 dimm
->mtype
= MEM_XDR
;
155 dimm
->edac_mode
= EDAC_SECDED
;
156 dimm
->nr_pages
= nr_pages
/ csrow
->nr_channels
;
159 "Initialized on node %d, chanmask=0x%x,"
160 " first_page=0x%lx, nr_pages=0x%x\n",
161 priv
->node
, priv
->chanmask
,
162 csrow
->first_page
, nr_pages
);
168 static int cell_edac_probe(struct platform_device
*pdev
)
170 struct cbe_mic_tm_regs __iomem
*regs
;
171 struct mem_ctl_info
*mci
;
172 struct edac_mc_layer layers
[2];
173 struct cell_edac_priv
*priv
;
175 int rc
, chanmask
, num_chans
;
177 regs
= cbe_get_cpu_mic_tm_regs(cbe_node_to_cpu(pdev
->id
));
181 edac_op_state
= EDAC_OPSTATE_POLL
;
183 /* Get channel population */
184 reg
= in_be64(®s
->mic_mnt_cfg
);
185 dev_dbg(&pdev
->dev
, "MIC_MNT_CFG = 0x%016llx\n", reg
);
187 if (reg
& CBE_MIC_MNT_CFG_CHAN_0_POP
)
189 if (reg
& CBE_MIC_MNT_CFG_CHAN_1_POP
)
193 "Yuck ! No channel populated ? Aborting !\n");
196 dev_dbg(&pdev
->dev
, "Initial FIR = 0x%016llx\n",
197 in_be64(®s
->mic_fir
));
199 /* Allocate & init EDAC MC data structure */
200 num_chans
= chanmask
== 3 ? 2 : 1;
202 layers
[0].type
= EDAC_MC_LAYER_CHIP_SELECT
;
204 layers
[0].is_virt_csrow
= true;
205 layers
[1].type
= EDAC_MC_LAYER_CHANNEL
;
206 layers
[1].size
= num_chans
;
207 layers
[1].is_virt_csrow
= false;
208 mci
= edac_mc_alloc(pdev
->id
, ARRAY_SIZE(layers
), layers
,
209 sizeof(struct cell_edac_priv
));
212 priv
= mci
->pvt_info
;
214 priv
->node
= pdev
->id
;
215 priv
->chanmask
= chanmask
;
216 mci
->pdev
= &pdev
->dev
;
217 mci
->mtype_cap
= MEM_FLAG_XDR
;
218 mci
->edac_ctl_cap
= EDAC_FLAG_NONE
| EDAC_FLAG_EC
| EDAC_FLAG_SECDED
;
219 mci
->edac_cap
= EDAC_FLAG_EC
| EDAC_FLAG_SECDED
;
220 mci
->mod_name
= "cell_edac";
221 mci
->ctl_name
= "MIC";
222 mci
->dev_name
= dev_name(&pdev
->dev
);
223 mci
->edac_check
= cell_edac_check
;
224 cell_edac_init_csrows(mci
);
226 /* Register with EDAC core */
227 rc
= edac_mc_add_mc(mci
);
229 dev_err(&pdev
->dev
, "failed to register with EDAC core\n");
237 static int cell_edac_remove(struct platform_device
*pdev
)
239 struct mem_ctl_info
*mci
= edac_mc_del_mc(&pdev
->dev
);
245 static struct platform_driver cell_edac_driver
= {
249 .probe
= cell_edac_probe
,
250 .remove
= cell_edac_remove
,
253 static int __init
cell_edac_init(void)
255 /* Sanity check registers data structure */
256 BUILD_BUG_ON(offsetof(struct cbe_mic_tm_regs
,
257 mic_df_ecc_address_0
) != 0xf8);
258 BUILD_BUG_ON(offsetof(struct cbe_mic_tm_regs
,
259 mic_df_ecc_address_1
) != 0x1b8);
260 BUILD_BUG_ON(offsetof(struct cbe_mic_tm_regs
,
261 mic_df_config
) != 0x218);
262 BUILD_BUG_ON(offsetof(struct cbe_mic_tm_regs
,
264 BUILD_BUG_ON(offsetof(struct cbe_mic_tm_regs
,
265 mic_mnt_cfg
) != 0x210);
266 BUILD_BUG_ON(offsetof(struct cbe_mic_tm_regs
,
269 return platform_driver_register(&cell_edac_driver
);
272 static void __exit
cell_edac_exit(void)
274 platform_driver_unregister(&cell_edac_driver
);
277 module_init(cell_edac_init
);
278 module_exit(cell_edac_exit
);
280 MODULE_LICENSE("GPL");
281 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
282 MODULE_DESCRIPTION("ECC counting for Cell MIC");