예제 #1
0
int mips_cm_probe(void)
{
	phys_addr_t addr;
	u32 base_reg;
	unsigned cpu;

	/*
	 * No need to probe again if we have already been
	 * here before.
	 */
	if (mips_cm_base)
		return 0;

	addr = mips_cm_phys_base();
	BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr);
	if (!addr)
		return -ENODEV;

	mips_cm_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE);
	if (!mips_cm_base)
		return -ENXIO;

	/* sanity check that we're looking at a CM */
	base_reg = read_gcr_base();
	if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) {
		pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
		       (unsigned long)addr);
		mips_cm_base = NULL;
		return -ENODEV;
	}

	/* set default target to memory */
	base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK;
	base_reg |= CM_GCR_BASE_CMDEFTGT_MEM;
	write_gcr_base(base_reg);

	/* disable CM regions */
	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
	write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
	write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
	write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);

	/* probe for an L2-only sync region */
	mips_cm_probe_l2sync();

	/* determine register width for this CM */
	mips_cm_is64 = IS_ENABLED(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3);

	for_each_possible_cpu(cpu)
		spin_lock_init(&per_cpu(cm_core_lock, cpu));

	return 0;
}
예제 #2
0
파일: mips-cm.c 프로젝트: 1800alex/linux
int mips_cm_probe(void)
{
	phys_t addr;
	u32 base_reg;

	addr = mips_cm_phys_base();
	BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr);
	if (!addr)
		return -ENODEV;

	mips_cm_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE);
	if (!mips_cm_base)
		return -ENXIO;

	/* sanity check that we're looking at a CM */
	base_reg = read_gcr_base();
	if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) {
		pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
		       (unsigned long)addr);
		mips_cm_base = NULL;
		return -ENODEV;
	}

	/* set default target to memory */
	base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK;
	base_reg |= CM_GCR_BASE_CMDEFTGT_MEM;
	write_gcr_base(base_reg);

	/* disable CM regions */
	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
	write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
	write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
	write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
	write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);

	/* probe for an L2-only sync region */
	mips_cm_probe_l2sync();

	return 0;
}