/**
 * Return the backplane clock speed in Hz.
 * 
 * @param sc driver instance state.
 */
uint32_t
bhnd_pwrctl_getclk_speed(struct bhnd_pwrctl_softc *sc)
{
	const struct bhnd_chipid	*cid;
	struct chipc_caps		*ccaps;
	bus_size_t			 creg;
	uint32_t 			 n, m;
	uint32_t 			 rate;

	PWRCTL_LOCK_ASSERT(sc, MA_OWNED);

	cid = bhnd_get_chipid(sc->chipc_dev);
	ccaps = BHND_CHIPC_GET_CAPS(sc->chipc_dev);

	n = bhnd_bus_read_4(sc->res, CHIPC_CLKC_N);

	/* Get M register offset */
	creg = bhnd_pwrctl_si_clkreg_m(cid, ccaps->pll_type, &rate);
	if (creg == 0) /* fixed rate */
		return (rate);

	/* calculate rate */
	m = bhnd_bus_read_4(sc->res, creg);
	return (bhnd_pwrctl_si_clock_rate(cid, ccaps->pll_type, n, m));
}
static int
chipc_sprom_attach(device_t dev)
{
	struct chipc_caps	*caps;
	device_t		 chipc;
	int			 error;

	chipc = device_get_parent(dev);
	caps = BHND_CHIPC_GET_CAPS(chipc);

	/* Request that ChipCommon enable access to SPROM hardware before
	 * delegating attachment (and SPROM parsing) to the common driver */
	if ((error = BHND_CHIPC_ENABLE_SPROM(chipc)))
		return (error);

	error = bhnd_sprom_attach(dev, caps->sprom_offset);
	BHND_CHIPC_DISABLE_SPROM(chipc);
	return (error);
}
static int
chipc_sprom_probe(device_t dev)
{
	struct chipc_caps	*caps;
	device_t		 chipc;
	int			 error;

	chipc = device_get_parent(dev);
	caps = BHND_CHIPC_GET_CAPS(chipc);

	/* Only match on SPROM/OTP devices */
	if (!CHIPC_VALID_SPROM_SRC(caps->nvram_src))
		return (ENXIO);

	/* Defer to default driver implementation */
	if ((error = bhnd_sprom_probe(dev)) > 0)
		return (error);

	return (BUS_PROBE_NOWILDCARD);
}
Beispiel #4
0
static int
bhnd_pmu_chipc_probe(device_t dev)
{
	struct bhnd_pmu_softc	*sc;
	struct chipc_caps	*ccaps;
	struct chipc_softc	*chipc_sc;
	device_t		 chipc;
	char			 desc[34];
	int			 error;
	uint32_t		 pcaps;
	uint8_t			 rev;

	sc = device_get_softc(dev);

	/* Look for chipc parent */
	chipc = device_get_parent(dev);
	if (device_get_devclass(chipc) != devclass_find("bhnd_chipc"))
		return (ENXIO);

	/* Check the chipc PMU capability flag. */
	ccaps = BHND_CHIPC_GET_CAPS(chipc);
	if (!ccaps->pmu)
		return (ENXIO);

	/* Delegate to common driver implementation */
	if ((error = bhnd_pmu_probe(dev)) > 0)
		return (error);

	/* Fetch PMU capability flags */
	chipc_sc = device_get_softc(chipc);
	pcaps = bhnd_bus_read_4(chipc_sc->core, BHND_PMU_CAP);

	/* Set description */
	rev = BHND_PMU_GET_BITS(pcaps, BHND_PMU_CAP_REV);
	snprintf(desc, sizeof(desc), "Broadcom ChipCommon PMU, rev %hhu", rev);
	device_set_desc_copy(dev, desc);

	return (BUS_PROBE_NOWILDCARD);
}
Beispiel #5
0
static void
uart_chipc_identify(driver_t *driver, device_t parent)
{
	struct chipc_caps	*caps;

	if (device_find_child(parent, "uart", -1) != NULL)
		return;

	caps = BHND_CHIPC_GET_CAPS(parent);

	if (caps == NULL) {
		device_printf(parent, "error: can't retrieve ChipCommon "
		    "capabilities\n");
		return;
	}

	if (caps->num_uarts == 0)
		return;

	/*
	 * TODO: add more than one UART
	 */
	BUS_ADD_CHILD(parent, 0, "uart", -1);
}