Ejemplo n.º 1
0
static void
chipc_write_chipctrl(device_t dev, uint32_t value, uint32_t mask)
{
	struct chipc_softc	*sc;
	uint32_t		 cctrl;

	sc = device_get_softc(dev);

	CHIPC_LOCK(sc);

	cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
	cctrl = (cctrl & ~mask) | (value | mask);
	bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);

	CHIPC_UNLOCK(sc);
}
Ejemplo n.º 2
0
/**
 * If required by this device, enable access to the SPROM.
 * 
 * @param sc chipc driver state.
 */
static int
chipc_enable_sprom_pins(struct chipc_softc *sc)
{
	uint32_t		 cctrl;

	CHIPC_LOCK_ASSERT(sc, MA_OWNED);
	KASSERT(sc->sprom_refcnt == 0, ("sprom pins already enabled"));

	/* Nothing to do? */
	if (!CHIPC_QUIRK(sc, MUX_SPROM))
		return (0);

	/* Check whether bus is busy */
	if (!chipc_should_enable_muxed_sprom(sc))
		return (EBUSY);

	cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);

	/* 4331 devices */
	if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
		cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN;

		if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
			cctrl &= ~CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;

		if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
			cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN2;

		bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
		return (0);
	}

	/* 4360 devices */
	if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
		/* Unimplemented */
	}

	/* Refuse to proceed on unsupported devices with muxed SPROM pins */
	device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
	return (ENXIO);
}
Ejemplo n.º 3
0
static void
bhnd_pmu_write_4(bus_size_t reg, uint32_t val, void *ctx)
{
	struct bhnd_pmu_softc *sc = ctx;
	return (bhnd_bus_write_4(sc->res, reg, val));
}
Ejemplo n.º 4
0
/**
 * Distribute @p clock on backplane.
 * 
 * @param sc Driver instance state.
 * @param clock Clock to enable.
 * 
 * @retval 0 success
 * @retval ENODEV If @p clock is unsupported, or if the device does not
 * 		  support dynamic clock control.
 */
int
bhnd_pwrctl_setclk(struct bhnd_pwrctl_softc *sc, bhnd_clock clock)
{
	uint32_t	scc;

	PWRCTL_LOCK_ASSERT(sc, MA_OWNED);

	/* Is dynamic clock control supported? */
	if (PWRCTL_QUIRK(sc, FIXED_CLK))
		return (ENODEV);

	/* Chips with ccrev 10 are EOL and they don't have SYCC_HR used below */
	if (bhnd_get_hwrev(sc->chipc_dev) == 10)
		return (ENODEV);

	scc = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);

	switch (clock) {
	case BHND_CLOCK_HT:
		/* fast (pll) clock */
		if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
			scc &= ~(CHIPC_SCC_XC | CHIPC_SCC_FS | CHIPC_SCC_IP);
			scc |= CHIPC_SCC_IP;

			/* force xtal back on before clearing SCC_DYN_XTAL.. */
			bhnd_pwrctl_ungate_clock(sc->chipc_dev, BHND_CLOCK_HT);
		} else if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
			scc |= CHIPC_SYCC_HR;
		} else {
			return (ENODEV);
		}

		bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);
		DELAY(CHIPC_PLL_DELAY);

		break;		

	case BHND_CLOCK_DYN:
		/* enable dynamic clock control */
		if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
			scc &= ~(CHIPC_SCC_FS | CHIPC_SCC_IP | CHIPC_SCC_XC);
			if ((scc & CHIPC_SCC_SS_MASK) != CHIPC_SCC_SS_XTAL)
				scc |= CHIPC_SCC_XC;
	
			bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);

			/* for dynamic control, we have to release our xtal_pu
			 * "force on" */
			if (scc & CHIPC_SCC_XC) {
				bhnd_pwrctl_gate_clock(sc->chipc_dev,
				    BHND_CLOCK_HT);
			}
		} else if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
			/* Instaclock */
			scc &= ~CHIPC_SYCC_HR;
			bhnd_bus_write_4(sc->res, CHIPC_SYS_CLK_CTL, scc);
		} else {
			return (ENODEV);
		}

		break;

	default:
		return (ENODEV);
	}

	return (0);
}