diff options
| -rw-r--r-- | drivers/edac/synopsys_edac.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 6f445d338ece..185872f6d2ae 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -977,20 +977,6 @@ static inline enum dev_type snps_get_dtype(u32 mstr) } /** - * snps_get_memsize - Read the size of the attached memory device. - * - * Return: the memory size in bytes. - */ -static u32 snps_get_memsize(void) -{ - struct sysinfo inf; - - si_meminfo(&inf); - - return inf.totalram * inf.mem_unit; -} - -/** * snps_get_mtype - Returns controller memory type. * @mstr: Master CSR value. * @@ -1411,6 +1397,51 @@ static void snps_get_addr_map(struct snps_edac_priv *priv) } /** + * snps_get_sdram_size - Calculate SDRAM size. + * @priv: DDR memory controller private data. + * + * The total size of the attached memory is calculated based on the HIF/SDRAM + * mapping table. It can be done since the hardware reference manual demands + * that none two SDRAM bits should be mapped to the same HIF bit and that the + * unused SDRAM address bits mapping must be disabled. + * + * Return: the memory size in bytes. + */ +static u64 snps_get_sdram_size(struct snps_edac_priv *priv) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + u64 size = 0; + int i; + + for (i = 0; i < DDR_MAX_ROW_WIDTH; i++) { + if (map->row[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_COL_WIDTH; i++) { + if (map->col[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_BANK_WIDTH; i++) { + if (map->bank[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_BANKGRP_WIDTH; i++) { + if (map->bankgrp[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_RANK_WIDTH; i++) { + if (map->rank[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + return 1ULL << (size + priv->info.dq_width); +} + +/** * snps_init_csrows - Initialize the csrow data. * @mci: EDAC memory controller instance. * @@ -1422,7 +1453,8 @@ static void snps_init_csrows(struct mem_ctl_info *mci) struct snps_edac_priv *priv = mci->pvt_info; struct csrow_info *csi; struct dimm_info *dimm; - u32 size, row, width; + u32 row, width; + u64 size; int j; /* Actual SDRAM-word width for which ECC is calculated */ @@ -1430,13 +1462,13 @@ static void snps_init_csrows(struct mem_ctl_info *mci) for (row = 0; row < mci->nr_csrows; row++) { csi = mci->csrows[row]; - size = snps_get_memsize(); + size = snps_get_sdram_size(priv); for (j = 0; j < csi->nr_channels; j++) { dimm = csi->channels[j]->dimm; dimm->edac_mode = EDAC_SECDED; dimm->mtype = priv->info.sdram_mode; - dimm->nr_pages = (size >> PAGE_SHIFT) / csi->nr_channels; + dimm->nr_pages = PHYS_PFN(size) / csi->nr_channels; dimm->grain = width; dimm->dtype = priv->info.dev_cfg; } |
