Ejemplo n.º 1
0
void
amdpm_attach(struct device *parent, struct device *self, void *aux)
{
	struct amdpm_softc *sc = (struct amdpm_softc *) self;
	struct pci_attach_args *pa = aux;
	struct i2cbus_attach_args iba;
	pcireg_t cfg_reg, reg;
	int i;

	sc->sc_pc = pa->pa_pc;
	sc->sc_tag = pa->pa_tag;
	sc->sc_iot = pa->pa_iot;
	sc->sc_poll = 1; /* XXX */

	
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD)  {
		cfg_reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_CONFREG);
		if ((cfg_reg & AMDPM_PMIOEN) == 0) {
			printf(": PMxx space isn't enabled\n");
			return;
		}

		reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_PMPTR);
		if (AMDPM_PMBASE(reg) == 0 ||
		    bus_space_map(sc->sc_iot, AMDPM_PMBASE(reg), AMDPM_PMSIZE,
		    0, &sc->sc_ioh)) {
			printf("\n");
			return;
		}
		if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, AMDPM_SMB_REGS,
		    AMDPM_SMB_SIZE, &sc->sc_i2c_ioh)) {
			printf(": failed to map I2C subregion\n");
			return;	
		}

		if ((cfg_reg & AMDPM_TMRRST) == 0 &&
		    (cfg_reg & AMDPM_STOPTMR) == 0 &&
		    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC768_PMC ||
		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_8111_PMC)) {
			printf(": %d-bit timer at %lluHz",
			    (cfg_reg & AMDPM_TMR32) ? 32 : 24,
			    amdpm_timecounter.tc_frequency);

			amdpm_timecounter.tc_priv = sc;
			if (cfg_reg & AMDPM_TMR32)
				amdpm_timecounter.tc_counter_mask = 0xffffffffu;
			tc_init(&amdpm_timecounter);
		}	
		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC768_PMC ||
		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_8111_PMC) {
			if ((cfg_reg & AMDPM_RNGEN) ==0) {
				pci_conf_write(pa->pa_pc, pa->pa_tag, 
				    AMDPM_CONFREG, cfg_reg | AMDPM_RNGEN);
				cfg_reg = pci_conf_read(pa->pa_pc, pa->pa_tag,
				    AMDPM_CONFREG);
			}
			if (cfg_reg & AMDPM_RNGEN) {
			/* Check to see if we can read data from the RNG. */
				(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh,
				    AMDPM_RNGDATA);
				for (i = 1000; i--; ) {
					if (bus_space_read_1(sc->sc_iot, 
					    sc->sc_ioh, AMDPM_RNGSTAT) & 
					    AMDPM_RNGDONE)
						break;
					DELAY(10);
				}
				if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
				    AMDPM_RNGSTAT) & AMDPM_RNGDONE) {
					printf(": rng active");
					timeout_set(&sc->sc_rnd_ch, 
					    amdpm_rnd_callout, sc);
					amdpm_rnd_callout(sc);
				}
			}
		}
	} else if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NVIDIA) {
		reg = pci_conf_read(pa->pa_pc, pa->pa_tag, NFPM_PMPTR);
		if (AMDPM_PMBASE(reg) == 0 ||
		    bus_space_map(sc->sc_iot, AMDPM_PMBASE(reg), AMDPM_SMB_SIZE, 0,
		    &sc->sc_i2c_ioh)) {
			printf(": failed to map I2C subregion\n");
			return;
		}
	}
	printf("\n");

	/* Attach I2C bus */
	rw_init(&sc->sc_i2c_lock, "iiclk");
	sc->sc_i2c_tag.ic_cookie = sc;
	sc->sc_i2c_tag.ic_acquire_bus = amdpm_i2c_acquire_bus;
	sc->sc_i2c_tag.ic_release_bus = amdpm_i2c_release_bus;
	sc->sc_i2c_tag.ic_exec = amdpm_i2c_exec;

	bzero(&iba, sizeof(iba));
	iba.iba_name = "iic";
	iba.iba_tag = &sc->sc_i2c_tag;
	config_found(self, &iba, iicbus_print);
}
Ejemplo n.º 2
0
Archivo: amdpm.c Proyecto: MarginC/kame
void
amdpm_attach(struct device *parent, struct device *self, void *aux)
{
	struct amdpm_softc *sc = (struct amdpm_softc *) self;
	struct pci_attach_args *pa = aux;
	struct timeval tv1, tv2;
	pcireg_t reg;
	int i;

	sc->sc_pc = pa->pa_pc;
	sc->sc_tag = pa->pa_tag;
	sc->sc_iot = pa->pa_iot;

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_CONFREG);
	if ((reg & AMDPM_PMIOEN) == 0) {
		printf(": PMxx space isn't enabled\n");
		return;
	}
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_PMPTR);
	if (bus_space_map(sc->sc_iot, AMDPM_PMBASE(reg), AMDPM_PMSIZE,
	    0, &sc->sc_ioh)) {
		printf(": failed to map PMxx space\n");
		return;
	}

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMDPM_CONFREG);
	if (reg & AMDPM_RNGEN) {
		/* Check to see if we can read data from the RNG. */
		(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh,
		    AMDPM_RNGDATA);
		/* benchmark the RNG */
		microtime(&tv1);
		for (i = 2 * 1024; i--; ) {
			while(!(bus_space_read_1(sc->sc_iot, sc->sc_ioh,
			    AMDPM_RNGSTAT) & AMDPM_RNGDONE))
				;
			(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh,
			    AMDPM_RNGDATA);
		}
		microtime(&tv2);

		timersub(&tv2, &tv1, &tv1);
		if (tv1.tv_sec)
			tv1.tv_usec += 1000000 * tv1.tv_sec;
		printf(": rng active, %dKb/sec", 8 * 1000000 / tv1.tv_usec);

#ifdef AMDPM_RND_COUNTERS
			evcnt_attach_dynamic(&sc->sc_rnd_hits, EVCNT_TYPE_MISC,
			    NULL, sc->sc_dev.dv_xname, "rnd hits");
			evcnt_attach_dynamic(&sc->sc_rnd_miss, EVCNT_TYPE_MISC,
			    NULL, sc->sc_dev.dv_xname, "rnd miss");
			for (i = 0; i < 256; i++) {
				evcnt_attach_dynamic(&sc->sc_rnd_data[i],
				    EVCNT_TYPE_MISC, NULL, sc->sc_dev.dv_xname,
				    "rnd data");
			}
#endif
		timeout_set(&sc->sc_rnd_ch, amdpm_rnd_callout, sc);
		amdpm_rnd_callout(sc);
	}
}