Beispiel #1
0
static int
lbc_banks_enable(struct lbc_softc *sc)
{
	u_long size;
	uint32_t regval;
	int error, i;

	for (i = 0; i < LBC_DEV_MAX; i++) {
		size = sc->sc_banks[i].size;
		if (size == 0) {
			bus_space_write_4(sc->sc_bst, sc->sc_bsh,
			    LBC85XX_BR(i), 0);
			bus_space_write_4(sc->sc_bst, sc->sc_bsh,
			    LBC85XX_OR(i), 0);
			continue;
		}

		/*
		 * Compute and program BR value.
		 */
		regval = sc->sc_banks[i].addr;
		switch (sc->sc_banks[i].width) {
		case 8:
			regval |= (1 << 11);
			break;
		case 16:
			regval |= (2 << 11);
			break;
		case 32:
			regval |= (3 << 11);
			break;
		default:
			error = EINVAL;
			goto fail;
		}
		regval |= (sc->sc_banks[i].decc << 9);
		regval |= (sc->sc_banks[i].wp << 8);
		regval |= (sc->sc_banks[i].msel << 5);
		regval |= (sc->sc_banks[i].atom << 2);
		regval |= 1;
		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
		    LBC85XX_BR(i), regval);

		/*
		 * Compute and program OR value.
		 */
		regval = lbc_address_mask(size);
		switch (sc->sc_banks[i].msel) {
		case LBCRES_MSEL_GPCM:
			/* TODO Add flag support for option registers */
			regval |= 0x0ff7;
			break;
		case LBCRES_MSEL_FCM:
			/* TODO Add flag support for options register */
			regval |= 0x0796;
			break;
		case LBCRES_MSEL_UPMA:
		case LBCRES_MSEL_UPMB:
		case LBCRES_MSEL_UPMC:
			printf("UPM mode not supported yet!");
			error = ENOSYS;
			goto fail;
		}
		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
		    LBC85XX_OR(i), regval);
	}

	/*
	 * Initialize configuration register:
	 * - enable Local Bus
	 * - set data buffer control signal function
	 * - disable parity byte select
	 * - set ECC parity type
	 * - set bus monitor timing and timer prescale
	 */
	bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LBCR, 0);

	/*
	 * Initialize clock ratio register:
	 * - disable PLL bypass mode
	 * - configure LCLK delay cycles for the assertion of LALE
	 * - set system clock divider
	 */
	bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LCRR, 0x00030008);
	return (0);

fail:
	lbc_banks_unmap(sc);
	return (error);
}
Beispiel #2
0
static int
lbc_banks_enable(struct lbc_softc *sc)
{
	u_long size;
	uint32_t regval;
	int error, i;

	for (i = 0; i < LBC_DEV_MAX; i++) {
		size = sc->sc_banks[i].size;
		if (size == 0)
			continue;

		/*
		 * Compute and program BR value.
		 */
		regval = sc->sc_banks[i].addr;
		switch (sc->sc_banks[i].width) {
		case 8:
			regval |= (1 << 11);
			break;
		case 16:
			regval |= (2 << 11);
			break;
		case 32:
			regval |= (3 << 11);
			break;
		default:
			error = EINVAL;
			goto fail;
		}
		regval |= (sc->sc_banks[i].decc << 9);
		regval |= (sc->sc_banks[i].wp << 8);
		regval |= (sc->sc_banks[i].msel << 5);
		regval |= (sc->sc_banks[i].atom << 2);
		regval |= 1;
		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
		    LBC85XX_BR(i), regval);

		/*
		 * Compute and program OR value.
		 */
		regval = lbc_address_mask(size);
		switch (sc->sc_banks[i].msel) {
		case LBCRES_MSEL_GPCM:
			/* TODO Add flag support for option registers */
			regval |= 0x0ff7;
			break;
		case LBCRES_MSEL_FCM:
			/* TODO Add flag support for options register */
			regval |= 0x0796;
			break;
		case LBCRES_MSEL_UPMA:
		case LBCRES_MSEL_UPMB:
		case LBCRES_MSEL_UPMC:
			printf("UPM mode not supported yet!");
			error = ENOSYS;
			goto fail;
		}
		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
		    LBC85XX_OR(i), regval);
	}

	return (0);

fail:
	lbc_banks_unmap(sc);
	return (error);
}
Beispiel #3
0
static int
lbc_init_child(device_t dev, device_t child)
{
	struct lbc_softc *sc;
	struct lbc_devinfo *dinfo;
	const struct lbc_resource *res;
	u_long start, size;
	uint32_t regbuff;
	int error, unit;

	sc = device_get_softc(dev);
	dinfo = device_get_ivars(child);

	res = mpc85xx_lbc_resources;

	regbuff = 0;
	unit = -1;
	for (; res->lbr_devtype; res++) {
		if (res->lbr_unit != dinfo->lbc_unit)
			continue;

		start = res->lbr_base_addr;
		size = res->lbr_size;
		unit = res->lbr_unit;

		/*
		 * Configure LAW for this LBC device and map its physical
		 * memory region into KVA
		 */
		error = law_enable(OCP85XX_TGTIF_LBC, start, size);
		if (error)
			return (error);

		sc->sc_kva[unit] = (vm_offset_t)pmap_mapdev(start, size);
		if (sc->sc_kva[unit] == 0) {
			law_disable(OCP85XX_TGTIF_LBC, start, size);
			return (ENOSPC);
		}

		/*
		 * Compute and program BR value
		 */
		regbuff |= start;

		switch (res->lbr_port_size) {
		case 8:
			regbuff |= (1 << 11);
			break;
		case 16:
			regbuff |= (2 << 11);
			break;
		case 32:
			regbuff |= (3 << 11);
			break;
		default:
			error = EINVAL;
			goto fail;
		}
		regbuff |= (res->lbr_decc << 9);
		regbuff |= (res->lbr_wp << 8);
		regbuff |= (res->lbr_msel << 5);
		regbuff |= (res->lbr_atom << 2);
		regbuff |= 1;

		lbc_write_reg(sc, LBC85XX_BR(unit), regbuff);

		/*
		 * Compute and program OR value
		 */
		regbuff = 0;
		regbuff |= lbc_address_mask(size);

		switch (res->lbr_msel) {
		case LBCRES_MSEL_GPCM:
			/* TODO Add flag support for option registers */
			regbuff |= 0x00000ff7;
			break;
		case LBCRES_MSEL_FCM:
			printf("FCM mode not supported yet!");
			error = ENOSYS;
			goto fail;
		case LBCRES_MSEL_UPMA:
		case LBCRES_MSEL_UPMB:
		case LBCRES_MSEL_UPMC:
			printf("UPM mode not supported yet!");
			error = ENOSYS;
			goto fail;
		}

		lbc_write_reg(sc, LBC85XX_OR(unit), regbuff);

		return (0);
	}
fail:
	if (unit != -1) {
		law_disable(OCP85XX_TGTIF_LBC, start, size);
		pmap_unmapdev(sc->sc_kva[unit], size);
		return (error);
	} else
		return (ENOENT);
}