Esempio n. 1
0
void
rtw_cardbus_setup(struct rtw_cardbus_softc *csc)
{
	struct rtw_softc *sc = &csc->sc_rtw;
	cardbus_devfunc_t ct = csc->sc_ct;
	cardbus_chipset_tag_t cc = ct->ct_cc;
	cardbus_function_tag_t cf = ct->ct_cf;
	pcireg_t reg;
	int pmreg;

	if (cardbus_get_capability(cc, cf, csc->sc_tag,
	    PCI_CAP_PWRMGMT, &pmreg, 0)) {
		reg = cardbus_conf_read(cc, cf, csc->sc_tag, pmreg + 4) & 0x03;
#if 1 /* XXX Probably not right for CardBus. */
		if (reg == 3) {
			/*
			 * The card has lost all configuration data in
			 * this state, so punt.
			 */
			printf("%s: unable to wake up from power state D3\n",
			    sc->sc_dev.dv_xname);
			return;
		}
#endif
		if (reg != 0) {
			printf("%s: waking up from power state D%d\n",
			    sc->sc_dev.dv_xname, reg);
			cardbus_conf_write(cc, cf, csc->sc_tag,
			    pmreg + 4, 0);
		}
	}

	/* Program the BAR. */
	cardbus_conf_write(cc, cf, csc->sc_tag, csc->sc_bar_reg,
	    csc->sc_bar_val);

	/* Make sure the right access type is on the CardBus bridge. */
	(*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cben);
	(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);

	/* Enable the appropriate bits in the PCI CSR. */
	reg = cardbus_conf_read(cc, cf, csc->sc_tag,
	    CARDBUS_COMMAND_STATUS_REG);
	reg &= ~(CARDBUS_COMMAND_IO_ENABLE|CARDBUS_COMMAND_MEM_ENABLE);
	reg |= csc->sc_csr;
	cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG,
	    reg);

	/*
	 * Make sure the latency timer is set to some reasonable
	 * value.
	 */
	reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG);
	if (CARDBUS_LATTIMER(reg) < 0x20) {
		reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
		reg |= (0x20 << CARDBUS_LATTIMER_SHIFT);
		cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG, reg);
	}
}
Esempio n. 2
0
void
re_cardbus_setup(struct re_cardbus_softc *csc)
{
	struct rtk_softc *sc = &csc->sc_rtk;
	cardbus_devfunc_t ct = csc->sc_ct;
	cardbus_chipset_tag_t cc = ct->ct_cc;
	cardbus_function_tag_t cf = ct->ct_cf;
	pcireg_t reg, command;
	int pmreg;

	/*
	 * Handle power management nonsense.
	 */
	if (cardbus_get_capability(cc, cf, csc->sc_tag,
	    PCI_CAP_PWRMGMT, &pmreg, 0)) {
		command = cardbus_conf_read(cc, cf, csc->sc_tag,
		    pmreg + PCI_PMCSR);
		if (command & PCI_PMCSR_STATE_MASK) {
			pcireg_t iobase, membase, irq;

			/* Save important PCI config data. */
			iobase = cardbus_conf_read(cc, cf, csc->sc_tag,
			    RTK_PCI_LOIO);
			membase = cardbus_conf_read(cc, cf,csc->sc_tag,
			    RTK_PCI_LOMEM);
			irq = cardbus_conf_read(cc, cf,csc->sc_tag,
			    CARDBUS_INTERRUPT_REG);

			/* Reset the power state. */
			aprint_normal_dev(sc->sc_dev,
			    "chip is in D%d power mode -- setting to D0\n",
			    command & PCI_PMCSR_STATE_MASK);
			command &= ~PCI_PMCSR_STATE_MASK;
			cardbus_conf_write(cc, cf, csc->sc_tag,
			    pmreg + PCI_PMCSR, command);

			/* Restore PCI config data. */
			cardbus_conf_write(cc, cf, csc->sc_tag,
			    RTK_PCI_LOIO, iobase);
			cardbus_conf_write(cc, cf, csc->sc_tag,
			    RTK_PCI_LOMEM, membase);
			cardbus_conf_write(cc, cf, csc->sc_tag,
			    CARDBUS_INTERRUPT_REG, irq);
		}
	}

	/* Program the BAR */
	cardbus_conf_write(cc, cf, csc->sc_tag,
		csc->sc_bar_reg, csc->sc_bar_val);

	/* Make sure the right access type is on the CardBus bridge. */
	(*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cben);
	(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);

	/* Enable the appropriate bits in the CARDBUS CSR. */
	reg = cardbus_conf_read(cc, cf, csc->sc_tag,
	    CARDBUS_COMMAND_STATUS_REG);
	reg &= ~(CARDBUS_COMMAND_IO_ENABLE|CARDBUS_COMMAND_MEM_ENABLE);
	reg |= csc->sc_csr;
	cardbus_conf_write(cc, cf, csc->sc_tag,
	    CARDBUS_COMMAND_STATUS_REG, reg);

	/*
	 * Make sure the latency timer is set to some reasonable
	 * value.
	 */
	reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG);
	if (CARDBUS_LATTIMER(reg) < 0x40) {
		reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
		reg |= (0x40 << CARDBUS_LATTIMER_SHIFT);
		cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG, reg);
	}
}
Esempio n. 3
0
void
puc_cardbus_attach(struct device *parent, struct device *self, void *aux)
{
	struct puc_cardbus_softc *csc = (struct puc_cardbus_softc *)self;
	struct puc_softc *sc = &csc->sc_psc;
	struct cardbus_attach_args *ca = aux;
	struct cardbus_devfunc *ct = ca->ca_ct;
	cardbus_chipset_tag_t cc = ct->ct_cc;
	cardbus_function_tag_t cf = ct->ct_cf;
	struct puc_attach_args paa;
	cardbusreg_t reg;
	int i;

	Cardbus_function_enable(ct);

	csc->ct = ct;

	reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_SUBSYS_ID_REG);
	sc->sc_desc = puc_find_description(PCI_VENDOR(ca->ca_id),
	    PCI_PRODUCT(ca->ca_id), PCI_VENDOR(reg), PCI_PRODUCT(reg));

	puc_print_ports(sc->sc_desc);

	/* the fifth one is some memory we dunno */
	for (i = 0; i < PUC_NBARS; i++) {
		cardbusreg_t type;
		int bar;

		sc->sc_bar_mappings[i].mapped = 0;
		bar = PCI_MAPREG_START + 4 * i;
		if (!cardbus_mapreg_probe(cc, cf, ca->ca_tag, bar, &type))
			continue;

		if (!(sc->sc_bar_mappings[i].mapped = !Cardbus_mapreg_map(ct,
		    bar, type, 0,
		    &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
		    &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s)))
			printf("%s: couldn't map BAR at offset 0x%lx\n",
			    sc->sc_dev.dv_xname, (long)bar);
		sc->sc_bar_mappings[i].type = type;
	}

	csc->intrline = ca->ca_intrline;

	if (cardbus_get_capability(cc, cf, ca->ca_tag, PCI_CAP_PWRMGMT, &reg,
	    0)) {
		reg = cardbus_conf_read(cc, cf, ca->ca_tag, reg + 4) & 3;
		if (reg) {
			printf("%s: awakening from state D%d\n",
			    sc->sc_dev.dv_xname, reg);
			cardbus_conf_write(cc, cf, ca->ca_tag, reg + 4, 0);
		}
	}

	(*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
	(*cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
	(*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);

	paa.puc = sc;
	paa.hwtype = COM_UART_OX16C950;		/* XXX */
	paa.intr_string = &puc_cardbus_intr_string;
	paa.intr_establish = &puc_cardbus_intr_establish;
	puc_common_attach(sc, &paa);
}