Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd63312d authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

edac: Move grain/dtype/edac_type calculus to be out of channel loop



The 3e7bddc changeset (edac: move dimm properties to struct memset_info)
moved the calculus inside a loop. However, at those stuff are common to
all channels, on several drivers, it is better to put the calculus
outside the loop, to optimize the code.

Reported-by: default avatarAristeu Rozanski Filho <arozansk@redhat.com>
Reviewed-by: default avatarAristeu Rozanski <arozansk@redhat.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michal Marek <mmarek@suse.cz>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 452a6bf9
Loading
Loading
Loading
Loading
+27 −27
Original line number Diff line number Diff line
@@ -330,8 +330,9 @@ static void cpc925_init_csrows(struct mem_ctl_info *mci)
	struct cpc925_mc_pdata *pdata = mci->pvt_info;
	struct csrow_info *csrow;
	struct dimm_info *dimm;
	enum dev_type dtype;
	int index, j;
	u32 mbmr, mbbar, bba;
	u32 mbmr, mbbar, bba, grain;
	unsigned long row_size, nr_pages, last_nr_pages = 0;

	get_total_mem(pdata);
@@ -355,37 +356,36 @@ static void cpc925_init_csrows(struct mem_ctl_info *mci)
		csrow->last_page = csrow->first_page + nr_pages - 1;
		last_nr_pages = csrow->last_page + 1;

		for (j = 0; j < csrow->nr_channels; j++) {
			dimm = csrow->channels[j].dimm;

			dimm->nr_pages = nr_pages / csrow->nr_channels;
			dimm->mtype = MEM_RDDR;
			dimm->edac_mode = EDAC_SECDED;

		switch (csrow->nr_channels) {
		case 1: /* Single channel */
				dimm->grain = 32; /* four-beat burst of 32 bytes */
			grain = 32; /* four-beat burst of 32 bytes */
			break;
		case 2: /* Dual channel */
		default:
				dimm->grain = 64; /* four-beat burst of 64 bytes */
			grain = 64; /* four-beat burst of 64 bytes */
			break;
		}

		switch ((mbmr & MBMR_MODE_MASK) >> MBMR_MODE_SHIFT) {
		case 6: /* 0110, no way to differentiate X8 VS X16 */
		case 5:	/* 0101 */
		case 8: /* 1000 */
				dimm->dtype = DEV_X16;
			dtype = DEV_X16;
			break;
		case 7: /* 0111 */
		case 9: /* 1001 */
				dimm->dtype = DEV_X8;
			dtype = DEV_X8;
			break;
		default:
				dimm->dtype = DEV_UNKNOWN;
			dtype = DEV_UNKNOWN;
		break;
		}
		for (j = 0; j < csrow->nr_channels; j++) {
			dimm = csrow->channels[j].dimm;
			dimm->nr_pages = nr_pages / csrow->nr_channels;
			dimm->mtype = MEM_RDDR;
			dimm->edac_mode = EDAC_SECDED;
			dimm->grain = grain;
			dimm->dtype = dtype;
		}
	}
}
+16 −15
Original line number Diff line number Diff line
@@ -1069,6 +1069,7 @@ static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
			u16 ddrcsr)
{
	struct csrow_info *csrow;
	enum edac_type edac_mode;
	unsigned long last_cumul_size;
	int index, mem_dev, drc_chan;
	int drc_drbg;		/* DRB granularity 0=64mb, 1=128mb */
@@ -1111,29 +1112,29 @@ static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
		nr_pages = cumul_size - last_cumul_size;
		last_cumul_size = cumul_size;

		for (i = 0; i < csrow->nr_channels; i++) {
			struct dimm_info *dimm = csrow->channels[i].dimm;

			debugf3("Initializing rank at (%i,%i)\n", index, i);
			dimm->nr_pages = nr_pages / csrow->nr_channels;
			dimm->grain = 1 << 12;	/* 4KiB - resolution of CELOG */
			dimm->mtype = MEM_RDDR;	/* only one type supported */
			dimm->dtype = mem_dev ? DEV_X4 : DEV_X8;

		/*
		* if single channel or x8 devices then SECDED
		* if dual channel and x4 then S4ECD4ED
		*/
		if (drc_ddim) {
			if (drc_chan && mem_dev) {
					dimm->edac_mode = EDAC_S4ECD4ED;
				edac_mode = EDAC_S4ECD4ED;
				mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
			} else {
					dimm->edac_mode = EDAC_SECDED;
				edac_mode = EDAC_SECDED;
				mci->edac_cap |= EDAC_FLAG_SECDED;
			}
		} else
				dimm->edac_mode = EDAC_NONE;
			edac_mode = EDAC_NONE;
		for (i = 0; i < csrow->nr_channels; i++) {
			struct dimm_info *dimm = csrow->channels[i].dimm;

			debugf3("Initializing rank at (%i,%i)\n", index, i);
			dimm->nr_pages = nr_pages / csrow->nr_channels;
			dimm->grain = 1 << 12;	/* 4KiB - resolution of CELOG */
			dimm->mtype = MEM_RDDR;	/* only one type supported */
			dimm->dtype = mem_dev ? DEV_X4 : DEV_X8;
			dimm->edac_mode = edac_mode;
		}
	}
}
+17 −15
Original line number Diff line number Diff line
@@ -362,6 +362,7 @@ static void e7xxx_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
	int drc_chan, drc_drbg, drc_ddim, mem_dev;
	struct csrow_info *csrow;
	struct dimm_info *dimm;
	enum edac_type edac_mode;

	pci_read_config_dword(pdev, E7XXX_DRA, &dra);
	drc_chan = dual_channel_active(drc, dev_idx);
@@ -392,28 +393,29 @@ static void e7xxx_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
		nr_pages = cumul_size - last_cumul_size;
		last_cumul_size = cumul_size;

		for (j = 0; j < drc_chan + 1; j++) {
			dimm = csrow->channels[j].dimm;

			dimm->nr_pages = nr_pages / (drc_chan + 1);
			dimm->grain = 1 << 12;	/* 4KiB - resolution of CELOG */
			dimm->mtype = MEM_RDDR;	/* only one type supported */
			dimm->dtype = mem_dev ? DEV_X4 : DEV_X8;

		/*
		* if single channel or x8 devices then SECDED
		* if dual channel and x4 then S4ECD4ED
		*/
		if (drc_ddim) {
			if (drc_chan && mem_dev) {
					dimm->edac_mode = EDAC_S4ECD4ED;
				edac_mode = EDAC_S4ECD4ED;
				mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
			} else {
					dimm->edac_mode = EDAC_SECDED;
				edac_mode = EDAC_SECDED;
				mci->edac_cap |= EDAC_FLAG_SECDED;
			}
		} else
				dimm->edac_mode = EDAC_NONE;
			edac_mode = EDAC_NONE;

		for (j = 0; j < drc_chan + 1; j++) {
			dimm = csrow->channels[j].dimm;

			dimm->nr_pages = nr_pages / (drc_chan + 1);
			dimm->grain = 1 << 12;	/* 4KiB - resolution of CELOG */
			dimm->mtype = MEM_RDDR;	/* only one type supported */
			dimm->dtype = mem_dev ? DEV_X4 : DEV_X8;
			dimm->edac_mode = edac_mode;
		}
	}
}