Ejemplo n.º 1
0
/**
 * Populate platform configuration data.
 */
static int
bcm_init_platform_data(struct bcm_platform *bp)
{
	bus_addr_t		bus_addr, bus_size;
	bus_space_tag_t		erom_bst;
	bus_space_handle_t	erom_bsh;
	bool			aob, pmu;
	int			error;

	bus_addr = bcm_get_bus_addr();
	bus_size = bcm_get_bus_size();

#ifdef CFE
	/* Fetch CFE console handle (if any). Must be initialized before
	 * any calls to printf/early_putc. */
	if ((bp->cfe_console = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE)) < 0)
		bp->cfe_console = -1;

	/* Probe CFE NVRAM sources */
	bp->nvram_io = &bcm_cfe_nvram.io;
	error = bcm_nvram_find_cfedev(&bcm_cfe_nvram, &bp->nvram_cls);
	if (error) {
		bp->nvram_io = NULL;
		bp->nvram_cls = NULL;
	}
#endif /* CFE */

	/* Probe and attach device table provider, populating our
	 * chip identification */
	erom_bst = mips_bus_space_generic;
	erom_bsh = BCM_SOC_BSH(bus_addr, 0);

	error = bhnd_erom_iobus_init(&bp->erom_io, bus_addr, bus_size, erom_bst,
	    erom_bsh);
	if (error) {
		BCM_ERR("failed to initialize erom I/O callbacks: %d\n", error);
		return (error);
	}

	error = bcm_erom_probe_and_attach(&bp->erom_impl, &bp->erom_ops,
	    &bp->erom.obj, sizeof(bp->erom), &bp->erom_io.eio, &bp->cid);
	if (error) {
		BCM_ERR("error attaching erom parser: %d\n", error);
		bhnd_erom_io_fini(&bp->erom_io.eio);
		return (error);
	}

	if (bootverbose)
		bhnd_erom_dump(&bp->erom.obj);

	/* Fetch chipcommon core info */
	error = bcm_find_core(bp, bcm_chipc_cores, nitems(bcm_chipc_cores),
	    &bp->cc_id, &bp->cc_addr);
	if (error) {
		BCM_ERR("error locating chipc core: %d\n", error);
		return (error);
	}

	/* Fetch chipc capability flags */
	bp->cc_caps = BCM_SOC_READ_4(bp->cc_addr, CHIPC_CAPABILITIES);
	bp->cc_caps_ext = 0x0;	

	if (CHIPC_HWREV_HAS_CAP_EXT(bp->cc_id.hwrev))
		bp->cc_caps_ext = BCM_CHIPC_READ_4(bp, CHIPC_CAPABILITIES_EXT);

	/* Fetch PMU info */
	pmu = CHIPC_GET_FLAG(bp->cc_caps, CHIPC_CAP_PMU);
	aob = CHIPC_GET_FLAG(bp->cc_caps_ext, CHIPC_CAP2_AOB);

	if (pmu && aob) {
		/* PMU block mapped to a PMU core on the Always-on-Bus (aob) */
		error = bcm_find_core(bp, bcm_pmu_cores, nitems(bcm_pmu_cores),
		    &bp->pmu_id,  &bp->pmu_addr);
		if (error) {
			BCM_ERR("error locating pmu core: %d\n", error);
			return (error);
		}
	} else if (pmu) {
		/* PMU block mapped to chipc */
		bp->pmu_addr = bp->cc_addr;
		bp->pmu_id = bp->cc_id;
	} else {
		/* No PMU */
		bp->pmu_addr = 0x0;
		memset(&bp->pmu_id, 0, sizeof(bp->pmu_id));
	}

	/* Initialize PMU query state */
	if (pmu) {
		error = bhnd_pmu_query_init(&bp->pmu, NULL, bp->cid,
		    &bcm_pmu_soc_io, bp);
		if (error) {
			BCM_ERR("bhnd_pmu_query_init() failed: %d\n", error);
			return (error);
		}
	}

	/* Find CPU core info */
	error = bcm_find_core(bp, bcm_cpu0_cores, nitems(bcm_cpu0_cores),
	    &bp->cpu_id,  &bp->cpu_addr);
	if (error) {
		BCM_ERR("error locating CPU core: %d\n", error);
		return (error);
	}

	/* Initialize our platform service registry */
	if ((error = bhnd_service_registry_init(&bp->services))) {
		BCM_ERR("error initializing service registry: %d\n", error);
		return (error);
	}

	bcm_platform_data_avail = true;
	return (0);
}
Ejemplo n.º 2
0
/* Read and parse chipc capabilities */
static int
chipc_read_caps(struct chipc_softc *sc, struct chipc_caps *caps)
{
	uint32_t	cap_reg;
	uint32_t	cap_ext_reg;
	uint32_t	regval;

	/* Fetch cap registers */
	cap_reg = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES);
	cap_ext_reg = 0;
	if (CHIPC_QUIRK(sc, SUPPORTS_CAP_EXT))
		cap_ext_reg = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES_EXT);

	/* Extract values */
	caps->num_uarts		= CHIPC_GET_BITS(cap_reg, CHIPC_CAP_NUM_UART);
	caps->mipseb		= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_MIPSEB);
	caps->uart_gpio		= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_UARTGPIO);
	caps->uart_clock	= CHIPC_GET_BITS(cap_reg, CHIPC_CAP_UCLKSEL);

	caps->extbus_type	= CHIPC_GET_BITS(cap_reg, CHIPC_CAP_EXTBUS);
	caps->pwr_ctrl		= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_PWR_CTL);
	caps->jtag_master	= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_JTAGP);

	caps->pll_type		= CHIPC_GET_BITS(cap_reg, CHIPC_CAP_PLL);
	caps->backplane_64	= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_BKPLN64);
	caps->boot_rom		= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_ROM);
	caps->pmu		= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_PMU);
	caps->eci		= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_ECI);
	caps->sprom		= CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_SPROM);
	caps->otp_size		= CHIPC_GET_BITS(cap_reg, CHIPC_CAP_OTP_SIZE);

	caps->seci		= CHIPC_GET_FLAG(cap_ext_reg, CHIPC_CAP2_SECI);
	caps->gsio		= CHIPC_GET_FLAG(cap_ext_reg, CHIPC_CAP2_GSIO);
	caps->aob		= CHIPC_GET_FLAG(cap_ext_reg, CHIPC_CAP2_AOB);

	/* Fetch OTP size for later IPX controller revisions */
	if (CHIPC_QUIRK(sc, IPX_OTPL_SIZE)) {
		regval = bhnd_bus_read_4(sc->core, CHIPC_OTPLAYOUT);
		caps->otp_size = CHIPC_GET_BITS(regval, CHIPC_OTPL_SIZE);
	}

	/* Determine flash type and parameters */
	caps->cfi_width = 0;
	switch (CHIPC_GET_BITS(cap_reg, CHIPC_CAP_FLASH)) {
	case CHIPC_CAP_SFLASH_ST:
		caps->flash_type = CHIPC_SFLASH_ST;
		break;
	case CHIPC_CAP_SFLASH_AT:
		caps->flash_type = CHIPC_SFLASH_AT;
		break;
	case CHIPC_CAP_NFLASH:
		/* unimplemented */
		caps->flash_type = CHIPC_NFLASH;
		break;
	case CHIPC_CAP_PFLASH:
		caps->flash_type = CHIPC_PFLASH_CFI;

		/* determine cfi width */
		regval = bhnd_bus_read_4(sc->core, CHIPC_FLASH_CFG);
		if (CHIPC_GET_FLAG(regval, CHIPC_FLASH_CFG_DS))
			caps->cfi_width = 2;
		else
			caps->cfi_width = 1;

		break;
	case CHIPC_CAP_FLASH_NONE:
		caps->flash_type = CHIPC_FLASH_NONE;
		break;
			
	}

	/* Handle 4706_NFLASH fallback */
	if (CHIPC_QUIRK(sc, 4706_NFLASH) &&
	    CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_4706_NFLASH))
	{
		caps->flash_type = CHIPC_NFLASH_4706;
	}


	/* Determine NVRAM source. Must occur after the SPROM/OTP/flash
	 * capability flags have been populated. */
	caps->nvram_src = chipc_find_nvram_src(sc, caps);

	/* Determine the SPROM offset within OTP (if any). SPROM-formatted
	 * data is placed within the OTP general use region. */
	caps->sprom_offset = 0;
	if (caps->nvram_src == BHND_NVRAM_SRC_OTP) {
		CHIPC_ASSERT_QUIRK(sc, OTP_IPX);

		/* Bit offset to GUP HW subregion containing SPROM data */
		regval = bhnd_bus_read_4(sc->core, CHIPC_OTPLAYOUT);
		caps->sprom_offset = CHIPC_GET_BITS(regval, CHIPC_OTPL_GUP);

		/* Convert to bytes */
		caps->sprom_offset /= 8;
	}

	return (0);
}