2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
13 * Tilera-specific EDAC driver.
15 * This source code is derived from the following driver:
17 * Cell MIC driver for ECC counting
19 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
20 * <benh@kernel.crashing.org>
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/platform_device.h>
28 #include <linux/uaccess.h>
29 #include <linux/edac.h>
30 #include <hv/hypervisor.h>
31 #include <hv/drv_mshim_intf.h>
33 #include "edac_core.h"
35 #define DRV_NAME "tile-edac"
37 /* Number of cs_rows needed per memory controller on TILEPro. */
38 #define TILE_EDAC_NR_CSROWS 1
40 /* Number of channels per memory controller on TILEPro. */
41 #define TILE_EDAC_NR_CHANS 1
43 /* Granularity of reported error in bytes on TILEPro. */
44 #define TILE_EDAC_ERROR_GRAIN 8
46 /* TILE processor has multiple independent memory controllers. */
47 struct platform_device
*mshim_pdev
[TILE_MAX_MSHIMS
];
49 struct tile_edac_priv
{
50 int hv_devhdl
; /* Hypervisor device handle. */
51 int node
; /* Memory controller instance #. */
52 unsigned int ce_count
; /*
53 * Correctable-error counter
58 static void tile_edac_check(struct mem_ctl_info
*mci
)
60 struct tile_edac_priv
*priv
= mci
->pvt_info
;
61 struct mshim_mem_error mem_error
;
63 if (hv_dev_pread(priv
->hv_devhdl
, 0, (HV_VirtAddr
)&mem_error
,
64 sizeof(struct mshim_mem_error
), MSHIM_MEM_ERROR_OFF
) !=
65 sizeof(struct mshim_mem_error
)) {
66 pr_err(DRV_NAME
": MSHIM_MEM_ERROR_OFF pread failure.\n");
70 /* Check if the current error count is different from the saved one. */
71 if (mem_error
.sbe_count
!= priv
->ce_count
) {
72 dev_dbg(mci
->pdev
, "ECC CE err on node %d\n", priv
->node
);
73 priv
->ce_count
= mem_error
.sbe_count
;
74 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED
, mci
, 1,
82 * Initialize the 'csrows' table within the mci control structure with the
83 * addressing of memory.
85 static int __devinit
tile_edac_init_csrows(struct mem_ctl_info
*mci
)
87 struct csrow_info
*csrow
= mci
->csrows
[0];
88 struct tile_edac_priv
*priv
= mci
->pvt_info
;
89 struct mshim_mem_info mem_info
;
90 struct dimm_info
*dimm
= csrow
->channels
[0]->dimm
;
92 if (hv_dev_pread(priv
->hv_devhdl
, 0, (HV_VirtAddr
)&mem_info
,
93 sizeof(struct mshim_mem_info
), MSHIM_MEM_INFO_OFF
) !=
94 sizeof(struct mshim_mem_info
)) {
95 pr_err(DRV_NAME
": MSHIM_MEM_INFO_OFF pread failure.\n");
100 dimm
->edac_mode
= EDAC_SECDED
;
102 dimm
->edac_mode
= EDAC_NONE
;
103 switch (mem_info
.mem_type
) {
105 dimm
->mtype
= MEM_DDR2
;
109 dimm
->mtype
= MEM_DDR3
;
116 dimm
->nr_pages
= mem_info
.mem_size
>> PAGE_SHIFT
;
117 dimm
->grain
= TILE_EDAC_ERROR_GRAIN
;
118 dimm
->dtype
= DEV_UNKNOWN
;
123 static int __devinit
tile_edac_mc_probe(struct platform_device
*pdev
)
127 struct mem_ctl_info
*mci
;
128 struct edac_mc_layer layers
[2];
129 struct tile_edac_priv
*priv
;
132 sprintf(hv_file
, "mshim/%d", pdev
->id
);
133 hv_devhdl
= hv_dev_open((HV_VirtAddr
)hv_file
, 0);
137 /* A TILE MC has a single channel and one chip-select row. */
138 layers
[0].type
= EDAC_MC_LAYER_CHIP_SELECT
;
139 layers
[0].size
= TILE_EDAC_NR_CSROWS
;
140 layers
[0].is_virt_csrow
= true;
141 layers
[1].type
= EDAC_MC_LAYER_CHANNEL
;
142 layers
[1].size
= TILE_EDAC_NR_CHANS
;
143 layers
[1].is_virt_csrow
= false;
144 mci
= edac_mc_alloc(pdev
->id
, ARRAY_SIZE(layers
), layers
,
145 sizeof(struct tile_edac_priv
));
148 priv
= mci
->pvt_info
;
149 priv
->node
= pdev
->id
;
150 priv
->hv_devhdl
= hv_devhdl
;
152 mci
->pdev
= &pdev
->dev
;
153 mci
->mtype_cap
= MEM_FLAG_DDR2
;
154 mci
->edac_ctl_cap
= EDAC_FLAG_SECDED
;
156 mci
->mod_name
= DRV_NAME
;
158 mci
->ctl_name
= "TILEGx_Memory_Controller";
160 mci
->ctl_name
= "TILEPro_Memory_Controller";
162 mci
->dev_name
= dev_name(&pdev
->dev
);
163 mci
->edac_check
= tile_edac_check
;
166 * Initialize the MC control structure 'csrows' table
167 * with the mapping and control information.
169 if (tile_edac_init_csrows(mci
)) {
170 /* No csrows found. */
171 mci
->edac_cap
= EDAC_FLAG_NONE
;
173 mci
->edac_cap
= EDAC_FLAG_SECDED
;
176 platform_set_drvdata(pdev
, mci
);
178 /* Register with EDAC core */
179 rc
= edac_mc_add_mc(mci
);
181 dev_err(&pdev
->dev
, "failed to register with EDAC core\n");
189 static int __devexit
tile_edac_mc_remove(struct platform_device
*pdev
)
191 struct mem_ctl_info
*mci
= platform_get_drvdata(pdev
);
193 edac_mc_del_mc(&pdev
->dev
);
199 static struct platform_driver tile_edac_mc_driver
= {
202 .owner
= THIS_MODULE
,
204 .probe
= tile_edac_mc_probe
,
205 .remove
= __devexit_p(tile_edac_mc_remove
),
209 * Driver init routine.
211 static int __init
tile_edac_init(void)
214 struct platform_device
*pdev
;
217 /* Only support POLL mode. */
218 edac_op_state
= EDAC_OPSTATE_POLL
;
220 err
= platform_driver_register(&tile_edac_mc_driver
);
224 for (i
= 0; i
< TILE_MAX_MSHIMS
; i
++) {
226 * Not all memory controllers are configured such as in the
227 * case of a simulator. So we register only those mshims
228 * that are configured by the hypervisor.
230 sprintf(hv_file
, "mshim/%d", i
);
231 if (hv_dev_open((HV_VirtAddr
)hv_file
, 0) < 0)
234 pdev
= platform_device_register_simple(DRV_NAME
, i
, NULL
, 0);
237 mshim_pdev
[i
] = pdev
;
242 platform_driver_unregister(&tile_edac_mc_driver
);
249 * Driver cleanup routine.
251 static void __exit
tile_edac_exit(void)
255 for (i
= 0; i
< TILE_MAX_MSHIMS
; i
++) {
256 struct platform_device
*pdev
= mshim_pdev
[i
];
260 platform_set_drvdata(pdev
, NULL
);
261 platform_device_unregister(pdev
);
263 platform_driver_unregister(&tile_edac_mc_driver
);
266 module_init(tile_edac_init
);
267 module_exit(tile_edac_exit
);