예제 #1
0
int
law_enable(int trgt, u_long addr, u_long size)
{
	uint32_t bar, sr;
	int i, law_max;

	if (size == 0)
		return (0);

	law_max = law_getmax();
	bar = _LAW_BAR(addr);
	sr = _LAW_SR(trgt, size);

	/* Bail if already programmed. */
	for (i = 0; i < law_max; i++)
		if (sr == ccsr_read4(OCP85XX_LAWSR(i)) &&
		    bar == ccsr_read4(OCP85XX_LAWBAR(i)))
			return (0);

	/* Find an unused access window. */
	for (i = 0; i < law_max; i++)
		if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0)
			break;

	if (i == law_max)
		return (ENOSPC);

	ccsr_write4(OCP85XX_LAWBAR(i), bar);
	ccsr_write4(OCP85XX_LAWSR(i), sr);
	return (0);
}
예제 #2
0
static int
bare_probe(platform_t plat)
{
	phandle_t cpus, child;
	uint32_t sr;
	int i, law_max, tgt;

	if ((cpus = OF_finddevice("/cpus")) != 0) {
		for (maxcpu = 0, child = OF_child(cpus); child != 0;
		    child = OF_peer(child), maxcpu++)
			;
	} else
		maxcpu = 1;

	/*
	 * Clear local access windows. Skip DRAM entries, so we don't shoot
	 * ourselves in the foot.
	 */
	law_max = law_getmax();
	for (i = 0; i < law_max; i++) {
		sr = ccsr_read4(OCP85XX_LAWSR(i));
		if ((sr & 0x80000000) == 0)
			continue;
		tgt = (sr & 0x01f00000) >> 20;
		if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
		    tgt == OCP85XX_TGTIF_RAM_INTL)
			continue;

		ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff);
	}

	return (BUS_PROBE_GENERIC);
}
예제 #3
0
int
law_disable(int trgt, u_long addr, u_long size)
{
	uint32_t bar, sr;
	int i, law_max;

	law_max = law_getmax();
	bar = _LAW_BAR(addr);
	sr = _LAW_SR(trgt, size);

	/* Find and disable requested LAW. */
	for (i = 0; i < law_max; i++)
		if (sr == ccsr_read4(OCP85XX_LAWSR(i)) &&
		    bar == ccsr_read4(OCP85XX_LAWBAR(i))) {
			ccsr_write4(OCP85XX_LAWBAR(i), 0);
			ccsr_write4(OCP85XX_LAWSR(i), 0);
			return (0);
		}

	return (ENOENT);
}
예제 #4
0
static void
mpc85xx_jog_set_int(void *arg)
{
	struct jog_rv_args *args = arg;
	uint32_t reg;

	if (PCPU_GET(cpuid) == args->cpu) {
		reg = ccsr_read4(GUTS_PMJCR);
		reg &= ~PMJCR_CORE_MULT(PMJCR_RATIO_M, args->cpu);
		reg |= PMJCR_CORE_MULT(args->mult, args->cpu);
		if (args->slow)
			reg &= ~(1 << (12 + args->cpu));
		else
			reg |= (1 << (12 + args->cpu));

		ccsr_write4(GUTS_PMJCR, reg);

		reg = ccsr_read4(GUTS_POWMGTCSR);
		reg |= POWMGTCSR_JOG | POWMGTCSR_INT_MASK;
		ccsr_write4(GUTS_POWMGTCSR, reg);

		/* Wait for completion */
		do {
			DELAY(100);
			reg = ccsr_read4(GUTS_POWMGTCSR);
		} while (reg & POWMGTCSR_JOG);

		reg = ccsr_read4(GUTS_POWMGTCSR);
		ccsr_write4(GUTS_POWMGTCSR, reg & ~POWMGTCSR_INT_MASK);
		ccsr_read4(GUTS_POWMGTCSR);

		args->inprogress = 0;
	} else {
		while (args->inprogress)
			cpu_spinwait();
	}
}
예제 #5
0
static int
bare_probe(platform_t plat)
{
	uint32_t ver, sr;
	int i, law_max, tgt;

	ver = SVR_VER(mfspr(SPR_SVR));
	switch (ver & ~0x0008) {	/* Mask Security Enabled bit */
	case SVR_P4080:
		maxcpu = 8;
		break;
	case SVR_P4040:
		maxcpu = 4;
		break;
	case SVR_MPC8572:
	case SVR_P1020:
	case SVR_P2020:
		maxcpu = 2;
		break;
	default:
		maxcpu = 1;
		break;
	}

	/*
	 * Clear local access windows. Skip DRAM entries, so we don't shoot
	 * ourselves in the foot.
	 */
	law_max = law_getmax();
	for (i = 0; i < law_max; i++) {
		sr = ccsr_read4(OCP85XX_LAWSR(i));
		if ((sr & 0x80000000) == 0)
			continue;
		tgt = (sr & 0x01f00000) >> 20;
		if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
		    tgt == OCP85XX_TGTIF_RAM_INTL)
			continue;

		ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff);
	}

	return (BUS_PROBE_GENERIC);
}
예제 #6
0
static int
mpc85xx_jog_get(device_t dev, struct cf_setting *set)
{
	struct mpc85xx_jog_softc *sc;
	uint32_t pmjcr;
	uint32_t freq;

	if (set == NULL)
		return (EINVAL);

	sc = device_get_softc(dev);
	memset(set, CPUFREQ_VAL_UNKNOWN, sizeof(*set));

	pmjcr = ccsr_read4(GUTS_PORPLLSR);
	freq = PMJCR_GET_CORE_MULT(pmjcr, sc->cpu);
	freq *= mpc85xx_get_system_clock();
	freq /= MHZ;
	
	set->freq = freq;
	set->dev = dev;

	return (0);
}
예제 #7
0
static int
mpc85xx_jog_attach(device_t dev)
{
	struct ofw_compat_data *compat;
	struct mpc85xx_jog_softc *sc;
	struct mpc85xx_constraints *constraints;
	phandle_t cpu;
	uint32_t reg;

	sc = device_get_softc(dev);
	sc->dev = dev;

	compat = mpc85xx_jog_devcompat();
	constraints = (struct mpc85xx_constraints *)compat->ocd_data;
	cpu = ofw_bus_get_node(device_get_parent(dev));

	if (cpu <= 0) {
		device_printf(dev,"No CPU device tree node!\n");
		return (ENXIO);
	}

	OF_getencprop(cpu, "reg", &sc->cpu, sizeof(sc->cpu));

	reg = ccsr_read4(GUTS_PORPLLSR);
	
	/*
	 * Assume power-on PLL is the highest PLL config supported on the
	 * board.
	 */
	sc->high = PMJCR_GET_CORE_MULT(reg, sc->cpu);
	sc->min_freq = constraints->threshold;
	sc->low = constraints->min_mult;

	cpufreq_register(dev);
	return (0);
}
예제 #8
0
static int
ocpbus_attach(device_t dev)
{
	struct ocpbus_softc *sc;
	int error, i, tgt, law_max;
	uint32_t sr;
	u_long start, end;

	sc = device_get_softc(dev);

	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_I2C, 0);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_I2C, 1);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_UART, 0);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_UART, 1);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_LBC, 0);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 0);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 1);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PCIB, 2);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 0);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 1);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 2);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_TSEC, 3);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_PIC, 0);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_QUICC, 0);
	ocpbus_mk_child(dev, OCPBUS_DEVTYPE_SEC, 0);

	/* Set up IRQ rman */
	start = 0;
	end = INTR_VECTORS - 1;
	sc->sc_irq.rm_start = start;
	sc->sc_irq.rm_end = end;
	sc->sc_irq.rm_type = RMAN_ARRAY;
	sc->sc_irq.rm_descr = "Interrupt request lines";
	if (rman_init(&sc->sc_irq) ||
	    rman_manage_region(&sc->sc_irq, start, end))
		panic("ocpbus_attach IRQ rman");

	/* Set up I/O mem rman */
	sc->sc_mem.rm_type = RMAN_ARRAY;
	sc->sc_mem.rm_descr = "OCPBus Device Memory";
	error = rman_init(&sc->sc_mem);
	if (error) {
		device_printf(dev, "rman_init() failed. error = %d\n", error);
		return (error);
	}

	error = rman_manage_region(&sc->sc_mem, CCSRBAR_VA,
	    CCSRBAR_VA + CCSRBAR_SIZE - 1);
	if (error) {
		device_printf(dev, "rman_manage_region() failed. error = %d\n",
		    error);
		return (error);
	}

	/*
	 * Clear local access windows. Skip DRAM entries, so we don't shoot
	 * ourselves in the foot.
	 */
	law_max = law_getmax();
	for (i = 0; i < law_max; i++) {
		sr = ccsr_read4(OCP85XX_LAWSR(i));
		if ((sr & 0x80000000) == 0)
			continue;
		tgt = (sr & 0x01f00000) >> 20;
		if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
		    tgt == OCP85XX_TGTIF_RAM_INTL)
			continue;

		ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff);
	}

	if (bootverbose)
		device_printf(dev, "PORDEVSR=%08x, PORDEVSR2=%08x\n",
		    ccsr_read4(OCP85XX_PORDEVSR),
		    ccsr_read4(OCP85XX_PORDEVSR2));

	for (i = PIC_IRQ_START; i < PIC_IRQ_START + 4; i++)
		powerpc_config_intr(i, INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);

	return (bus_generic_attach(dev));
}