FreeBSD/sys/dev/bhnd/bhndb/bhndb_pci.c
/**
 * Enable externally managed clocks, if required.
 * 
 * Some PCI chipsets (BCM4306, possibly others) chips do not support
 * the idle low-power clock. Clocking must be bootstrapped at
 * attach/resume by directly adjusting GPIO registers exposed in the
 * PCI config space, and correspondingly, explicitly shutdown at
 * detach/suspend.
 * 
 * @param sc Bridge driver state.
 */
Enable externally managed clocks, if required.

Some PCI chipsets (BCM4306, possibly others) chips do not support
the idle low-power clock. Clocking must be bootstrapped at
attach/resume by directly adjusting GPIO registers exposed in the
PCI config space, and correspondingly, explicitly shutdown at
detach/suspend.

@param sc Bridge driver state.
Enable externally managed clocks if required . Some PCI chipsets ( BCM4306 possibly others ) chips do not support the idle low - power clock . Clocking must be bootstrapped at attach / resume by directly adjusting GPIO registers exposed in the PCI config space and correspondingly explicitly shutdown at detach / suspend . @param sc Bridge driver state .
static int
bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc)
{
	uint32_t		gpio_in, gpio_out, gpio_en;
	uint32_t		gpio_flags;
	uint16_t		pci_status;
	if (sc->pci_devclass != BHND_DEVCLASS_PCI)
		return (0);
	gpio_in = pci_read_config(sc->parent, BHNDB_PCI_GPIO_IN, 4);
	if (gpio_in & BHNDB_PCI_GPIO_XTAL_ON)
		return (0); 
	gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
	gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
	gpio_flags = (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
	gpio_out |= gpio_flags;
	gpio_en |= gpio_flags;
	pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
	pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
	DELAY(1000);
	gpio_out &= ~BHNDB_PCI_GPIO_PLL_OFF;
	pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
	DELAY(5000);
	pci_status = pci_read_config(sc->parent, PCIR_STATUS, 2);
	pci_status &= ~PCIM_STATUS_STABORT;
	pci_write_config(sc->parent, PCIR_STATUS, pci_status, 2);
	return (0);
}
static int bhndb_enable_pci_clocks ( struct bhndb_pci_softc * sc ) { uint32_t gpio_in , gpio_out , gpio_en ; uint32_t gpio_flags ; uint16_t pci_status ; if ( sc -> pci_devclass != BHND_DEVCLASS_PCI ) return ( 0 ) ; gpio_in = pci_read_config ( sc -> parent , BHNDB_PCI_GPIO_IN , 4 ) ; if ( gpio_in & BHNDB_PCI_GPIO_XTAL_ON ) return ( 0 ) ; gpio_out = pci_read_config ( sc -> parent , BHNDB_PCI_GPIO_OUT , 4 ) ; gpio_en = pci_read_config ( sc -> parent , BHNDB_PCI_GPIO_OUTEN , 4 ) ; gpio_flags = ( BHNDB_PCI_GPIO_PLL_OFF | BHNDB_PCI_GPIO_XTAL_ON ) ; gpio_out |= gpio_flags ; gpio_en |= gpio_flags ; pci_write_config ( sc -> parent , BHNDB_PCI_GPIO_OUT , gpio_out , 4 ) ; pci_write_config ( sc -> parent , BHNDB_PCI_GPIO_OUTEN , gpio_en , 4 ) ; DELAY ( 1000 ) ; gpio_out &= ~ BHNDB_PCI_GPIO_PLL_OFF ; pci_write_config ( sc -> parent , BHNDB_PCI_GPIO_OUT , gpio_out , 4 ) ; DELAY ( 5000 ) ; pci_status = pci_read_config ( sc -> parent , PCIR_STATUS , 2 ) ; pci_status &= ~ PCIM_STATUS_STABORT ; pci_write_config ( sc -> parent , PCIR_STATUS , pci_status , 2 ) ; return ( 0 ) ; }
Enable externally managed clocks, if required.
Enable externally managed clocks if required .
/* Only supported and required on PCI devices */ /* Read state of XTAL pin */ /* already enabled */ /* Fetch current config */ /* Set PLL_OFF/XTAL_ON pins to HIGH and enable both pins */ /* Reset PLL_OFF */ /* Clear any PCI 'sent target-abort' flag. */