aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThor Thayer <tthayer@opensource.altera.com>2015-06-04 10:28:45 -0400
committerBorislav Petkov <bp@suse.de>2015-06-24 12:16:07 -0400
commitf9ae487e04370e229a96c83a8c86510299712192 (patch)
tree1f391d0be4bd1bd87ab4ec4a7dcfebaf9f2e9399
parent99e21fea47f425f65f727c96ed8b64a7ac18e5cb (diff)
EDAC, altera: Generalize driver to use DT Memory size
The Arria10 SOC uses a completely different SDRAM controller from the earlier CycloneV and ArriaV SoCs. The memory size is calculated in the bootloader and passed via the device tree. Using this device tree size is more generic than using the register fields to calculate the memory size for different SDRAM controllers. Signed-off-by: Thor Thayer <tthayer@opensource.altera.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: devicetree@vger.kernel.org Cc: dinguyen@opensource.altera.com Cc: galak@codeaurora.org Cc: grant.likely@linaro.org Cc: ijc+devicetree@hellion.org.uk Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac <linux-edac@vger.kernel.org> Cc: m.chehab@samsung.com Cc: mark.rutland@arm.com Cc: pawel.moll@arm.com Cc: robh+dt@kernel.org Cc: tthayer.linux@gmail.com Link: http://lkml.kernel.org/r/1433428128-7292-2-git-send-email-tthayer@opensource.altera.com Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r--drivers/edac/altera_edac.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 3c4929fda9d5..1d55c5b98024 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -219,36 +219,31 @@ static void altr_sdr_mc_create_debugfs_nodes(struct mem_ctl_info *mci)
219{} 219{}
220#endif 220#endif
221 221
222/* Get total memory size in bytes */ 222/* Get total memory size from Open Firmware DTB */
223static u32 altr_sdram_get_total_mem_size(struct regmap *mc_vbase) 223static unsigned long get_total_mem(void)
224{ 224{
225 u32 size, read_reg, row, bank, col, cs, width; 225 struct device_node *np = NULL;
226 226 const unsigned int *reg, *reg_end;
227 if (regmap_read(mc_vbase, DRAMADDRW_OFST, &read_reg) < 0) 227 int len, sw, aw;
228 return 0; 228 unsigned long start, size, total_mem = 0;
229 229
230 if (regmap_read(mc_vbase, DRAMIFWIDTH_OFST, &width) < 0) 230 for_each_node_by_type(np, "memory") {
231 return 0; 231 aw = of_n_addr_cells(np);
232 232 sw = of_n_size_cells(np);
233 col = (read_reg & DRAMADDRW_COLBIT_MASK) >> 233 reg = (const unsigned int *)of_get_property(np, "reg", &len);
234 DRAMADDRW_COLBIT_SHIFT; 234 reg_end = reg + (len / sizeof(u32));
235 row = (read_reg & DRAMADDRW_ROWBIT_MASK) >> 235
236 DRAMADDRW_ROWBIT_SHIFT; 236 total_mem = 0;
237 bank = (read_reg & DRAMADDRW_BANKBIT_MASK) >> 237 do {
238 DRAMADDRW_BANKBIT_SHIFT; 238 start = of_read_number(reg, aw);
239 cs = (read_reg & DRAMADDRW_CSBIT_MASK) >> 239 reg += aw;
240 DRAMADDRW_CSBIT_SHIFT; 240 size = of_read_number(reg, sw);
241 241 reg += sw;
242 /* Correct for ECC as its not addressible */ 242 total_mem += size;
243 if (width == DRAMIFWIDTH_32B_ECC) 243 } while (reg < reg_end);
244 width = 32; 244 }
245 if (width == DRAMIFWIDTH_16B_ECC) 245 edac_dbg(0, "total_mem 0x%lx\n", total_mem);
246 width = 16; 246 return total_mem;
247
248 /* calculate the SDRAM size base on this info */
249 size = 1 << (row + bank + col);
250 size = size * cs * (width / 8);
251 return size;
252} 247}
253 248
254static int altr_sdram_probe(struct platform_device *pdev) 249static int altr_sdram_probe(struct platform_device *pdev)
@@ -280,10 +275,9 @@ static int altr_sdram_probe(struct platform_device *pdev)
280 } 275 }
281 276
282 /* Grab memory size from device tree. */ 277 /* Grab memory size from device tree. */
283 mem_size = altr_sdram_get_total_mem_size(mc_vbase); 278 mem_size = get_total_mem();
284 if (!mem_size) { 279 if (!mem_size) {
285 edac_printk(KERN_ERR, EDAC_MC, 280 edac_printk(KERN_ERR, EDAC_MC, "Unable to calculate memory size\n");
286 "Unable to calculate memory size\n");
287 return -ENODEV; 281 return -ENODEV;
288 } 282 }
289 283