示例#1
0
static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
			u8 dramcr)
{
	struct csrow_info *csrow;
	struct dimm_info *dimm;
	int index;
	u8 drbar;		/* SDRAM Row Boundary Address Register */
	u32 row_high_limit, row_high_limit_last;
	u32 reg_sdram, ecc_on, row_base;

	ecc_on = ecc_enabled(dramcr);
	reg_sdram = dramcr & BIT(4);
	row_high_limit_last = 0;

	for (index = 0; index < mci->nr_csrows; index++) {
		csrow = &mci->csrows[index];
		dimm = csrow->channels[0].dimm;

		/* find the DRAM Chip Select Base address and mask */
		pci_read_config_byte(pdev, R82600_DRBA + index, &drbar);

		debugf1("%s() Row=%d DRBA = %#0x\n", __func__, index, drbar);

		row_high_limit = ((u32) drbar << 24);
/*		row_high_limit = ((u32)drbar << 24) | 0xffffffUL; */

		debugf1("%s() Row=%d, Boundary Address=%#0x, Last = %#0x\n",
			__func__, index, row_high_limit, row_high_limit_last);

		/* Empty row [p.57] */
		if (row_high_limit == row_high_limit_last)
			continue;

		row_base = row_high_limit_last;

		csrow->first_page = row_base >> PAGE_SHIFT;
		csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;

		dimm->nr_pages = csrow->last_page - csrow->first_page + 1;
		/* Error address is top 19 bits - so granularity is      *
		 * 14 bits                                               */
		dimm->grain = 1 << 14;
		dimm->mtype = reg_sdram ? MEM_RDDR : MEM_DDR;
		/* FIXME - check that this is unknowable with this chipset */
		dimm->dtype = DEV_UNKNOWN;

		/* Mode is global on 82600 */
		dimm->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE;
		row_high_limit_last = row_high_limit;
	}
}
示例#2
0
static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
{
	struct mem_ctl_info *mci;
	u8 dramcr;
	u32 eapr;
	u32 scrub_disabled;
	u32 sdram_refresh_rate;
	struct r82600_error_info discard;

	debugf0("%s()\n", __func__);
	pci_read_config_byte(pdev, R82600_DRAMC, &dramcr);
	pci_read_config_dword(pdev, R82600_EAP, &eapr);
	scrub_disabled = eapr & BIT(31);
	sdram_refresh_rate = dramcr & (BIT(0) | BIT(1));
	debugf2("%s(): sdram refresh rate = %#0x\n", __func__,
		sdram_refresh_rate);
	debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr);
	mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS, 0);

	if (mci == NULL)
		return -ENOMEM;

	debugf0("%s(): mci = %p\n", __func__, mci);
	mci->dev = &pdev->dev;
	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
	/* FIXME try to work out if the chip leads have been used for COM2
	 * instead on this board? [MA6?] MAYBE:
	 */

	/* On the R82600, the pins for memory bits 72:65 - i.e. the   *
	 * EC bits are shared with the pins for COM2 (!), so if COM2  *
	 * is enabled, we assume COM2 is wired up, and thus no EDAC   *
	 * is possible.                                               */
	mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;

	if (ecc_enabled(dramcr)) {
		if (scrub_disabled)
			debugf3("%s(): mci = %p - Scrubbing disabled! EAP: "
				"%#0x\n", __func__, mci, eapr);
	} else
		mci->edac_cap = EDAC_FLAG_NONE;

	mci->mod_name = EDAC_MOD_STR;
	mci->mod_ver = R82600_REVISION;
	mci->ctl_name = "R82600";
	mci->dev_name = pci_name(pdev);
	mci->edac_check = r82600_check;
	mci->ctl_page_to_phys = NULL;
	r82600_init_csrows(mci, pdev, dramcr);
	r82600_get_error_info(mci, &discard);	/* clear counters */

	/* Here we assume that we will never see multiple instances of this
	 * type of memory controller.  The ID is therefore hardcoded to 0.
	 */
	if (edac_mc_add_mc(mci)) {
		debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
		goto fail;
	}

	/* get this far and it's successful */

	if (disable_hardware_scrub) {
		debugf3("%s(): Disabling Hardware Scrub (scrub on error)\n",
			__func__);
		pci_write_bits32(pdev, R82600_EAP, BIT(31), BIT(31));
	}

	/* allocating generic PCI control info */
	r82600_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
	if (!r82600_pci) {
		printk(KERN_WARNING
			"%s(): Unable to create PCI control\n",
			__func__);
		printk(KERN_WARNING
			"%s(): PCI error report via EDAC not setup\n",
			__func__);
	}

	debugf3("%s(): success\n", __func__);
	return 0;

fail:
	edac_mc_free(mci);
	return -ENODEV;
}