static u_int32_t igma_reg_read(const struct igma_chip *cd, int r) { return bus_space_read_4(cd->mmiot, cd->mmioh, r); }
static __inline uint32_t acpi_timer_read(void) { return (bus_space_read_4(acpi_timer_bst, acpi_timer_bsh, 0)); }
static void grfiv_attach(struct device *parent, struct device *self, void *aux) { struct obio_attach_args *oa = (struct obio_attach_args *)aux; struct grfbus_softc *sc; struct grfmode *gm; u_long base, length; u_int32_t vbase1, vbase2; sc = (struct grfbus_softc *)self; sc->card_id = 0; switch (current_mac_model->class) { case MACH_CLASSQ2: if (current_mac_model->machineid != MACH_MACLC575) { sc->sc_basepa = VALKYRIE_BASE; length = 0x00100000; /* 1MB */ if (sc->sc_basepa <= mac68k_video.mv_phys && mac68k_video.mv_phys < (sc->sc_basepa + length)) { sc->sc_fbofs = mac68k_video.mv_phys - sc->sc_basepa; } else { sc->sc_basepa = m68k_trunc_page(mac68k_video.mv_phys); sc->sc_fbofs = m68k_page_offset(mac68k_video.mv_phys); length = mac68k_video.mv_len + sc->sc_fbofs; } printf(" @ %lx: Valkyrie video subsystem\n", sc->sc_basepa + sc->sc_fbofs); break; } /* See note in grfiv_match() */ /*FALLTHROUGH*/ case MACH_CLASSQ: base = DAFB_CONTROL_BASE; sc->sc_tag = oa->oa_tag; if (bus_space_map(sc->sc_tag, base, 0x20, 0, &sc->sc_regh)) { printf(": failed to map DAFB register space\n"); return; } sc->sc_basepa = DAFB_BASE; length = 0x00100000; /* 1MB */ /* Compute the current frame buffer offset */ vbase1 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x0) & 0xfff; #if 1 /* * XXX The following exists because the DAFB v7 in these * systems doesn't return reasonable values to use for fbofs. * Ken'ichi Ishizaka gets credit for this hack. (sar 19990426) * (Does this get us the correct result for _all_ DAFB- * equipped systems and monitor combinations? It seems * possible, if not likely...) */ switch (current_mac_model->machineid) { case MACH_MACLC475: case MACH_MACLC475_33: case MACH_MACLC575: case MACH_MACQ605: case MACH_MACQ605_33: vbase1 &= 0x3f; break; } #endif vbase2 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x4) & 0xf; sc->sc_fbofs = (vbase1 << 9) | (vbase2 << 5); printf(" @ %lx: DAFB video subsystem, monitor sense %x\n", sc->sc_basepa + sc->sc_fbofs, (bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x1c) & 0x7)); bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x20); break; case MACH_CLASSAV: sc->sc_basepa = CIVIC_BASE; length = 0x00200000; /* 2MB */ if (mac68k_video.mv_phys >= sc->sc_basepa && mac68k_video.mv_phys < (sc->sc_basepa + length)) { sc->sc_fbofs = mac68k_video.mv_phys - sc->sc_basepa; } else { sc->sc_basepa = m68k_trunc_page(mac68k_video.mv_phys); sc->sc_fbofs = m68k_page_offset(mac68k_video.mv_phys); length = mac68k_video.mv_len + sc->sc_fbofs; } printf(" @ %lx: CIVIC video subsystem\n", sc->sc_basepa + sc->sc_fbofs); break; case MACH_CLASSIIci: case MACH_CLASSIIsi: sc->sc_basepa = m68k_trunc_page(mac68k_video.mv_phys); sc->sc_fbofs = m68k_page_offset(mac68k_video.mv_phys); length = mac68k_video.mv_len + sc->sc_fbofs; printf(" @ %lx: RBV video subsystem, ", sc->sc_basepa + sc->sc_fbofs); switch (via2_reg(rMonitor) & RBVMonitorMask) { case RBVMonIDBWP: printf("15\" monochrome portrait"); break; case RBVMonIDRGB12: printf("12\" color"); break; case RBVMonIDRGB15: printf("15\" color"); break; case RBVMonIDStd: printf("Macintosh II"); break; default: printf("unrecognized"); break; } printf(" display\n"); break; default: sc->sc_basepa = m68k_trunc_page(mac68k_video.mv_phys); sc->sc_fbofs = m68k_page_offset(mac68k_video.mv_phys); length = mac68k_video.mv_len + sc->sc_fbofs; printf(" @ %lx: On-board video\n", sc->sc_basepa + sc->sc_fbofs); break; } if (bus_space_map(sc->sc_tag, sc->sc_basepa, length, 0, &sc->sc_handle)) { printf("%s: failed to map video RAM\n", sc->sc_dev.dv_xname); return; } if (sc->sc_basepa <= mac68k_video.mv_phys && mac68k_video.mv_phys < (sc->sc_basepa + length)) { /* XXX Hack */ mac68k_video.mv_kvaddr = sc->sc_handle.base + sc->sc_fbofs; } gm = &(sc->curr_mode); gm->mode_id = 0; gm->psize = mac68k_video.mv_depth; gm->ptype = 0; gm->width = mac68k_video.mv_width; gm->height = mac68k_video.mv_height; gm->rowbytes = mac68k_video.mv_stride; gm->hres = 80; /* XXX hack */ gm->vres = 80; /* XXX hack */ gm->fbsize = gm->height * gm->rowbytes; gm->fbbase = (void *)sc->sc_handle.base; /* XXX yet another hack */ gm->fboff = sc->sc_fbofs; /* Perform common video attachment. */ grf_establish(sc, NULL, grfiv_mode); }
/* * Attach all the sub-devices we can find */ void obio_attach(struct device *parent, struct device *self, void *aux) { struct obio_softc *sc = (struct obio_softc *)self; struct pci_attach_args *pa = aux; struct confargs ca; bus_space_handle_t bsh; int node, child, namelen, error; u_int reg[20]; int intr[6], parent_intr = 0, parent_nintr = 0; char name[32]; char compat[32]; #ifdef OBIO_SPEED_CONTROL sc->sc_voltage = -1; sc->sc_busspeed = -1; #endif switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_APPLE_GC: case PCI_PRODUCT_APPLE_OHARE: case PCI_PRODUCT_APPLE_HEATHROW: case PCI_PRODUCT_APPLE_PADDINGTON: case PCI_PRODUCT_APPLE_KEYLARGO: case PCI_PRODUCT_APPLE_PANGEA_MACIO: case PCI_PRODUCT_APPLE_INTREPID: node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag); if (node == -1) node = OF_finddevice("mac-io"); if (node == -1) node = OF_finddevice("/pci/mac-io"); break; case PCI_PRODUCT_APPLE_K2: node = OF_finddevice("mac-io"); break; default: node = -1; break; } if (node == -1) panic("macio not found or unknown"); sc->sc_node = node; #if defined (PMAC_G5) if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 20) { return; } #else if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12) return; #endif /* PMAC_G5 */ /* * XXX * This relies on the primary obio always attaching first which is * true on the PowerBook 3400c and similar machines but may or may * not work on others. We can't rely on the node name since Apple * didn't follow anything remotely resembling a consistent naming * scheme. */ if (obio0 == NULL) obio0 = sc; ca.ca_baseaddr = reg[2]; ca.ca_tag = pa->pa_memt; sc->sc_tag = pa->pa_memt; error = bus_space_map (pa->pa_memt, ca.ca_baseaddr, 0x80, 0, &bsh); if (error) panic(": failed to map mac-io %#x", ca.ca_baseaddr); sc->sc_bh = bsh; printf(": addr 0x%x\n", ca.ca_baseaddr); /* Enable internal modem (KeyLargo) */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_KEYLARGO) { aprint_normal("%s: enabling KeyLargo internal modem\n", self->dv_xname); bus_space_write_4(ca.ca_tag, bsh, 0x40, bus_space_read_4(ca.ca_tag, bsh, 0x40) & ~(1<<25)); } /* Enable internal modem (Pangea) */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PANGEA_MACIO) { /* set reset */ bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x04); /* power modem on */ bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x02, 0x04); /* unset reset */ bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x05); } /* Gatwick and Paddington use same product ID */ namelen = OF_getprop(node, "compatible", compat, sizeof(compat)); if (strcmp(compat, "gatwick") == 0) { parent_nintr = OF_getprop(node, "AAPL,interrupts", intr, sizeof(intr)); parent_intr = intr[0]; } else { /* Enable CD and microphone sound input. */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PADDINGTON) bus_space_write_1(ca.ca_tag, bsh, 0x37, 0x03); } for (child = OF_child(node); child; child = OF_peer(child)) { namelen = OF_getprop(child, "name", name, sizeof(name)); if (namelen < 0) continue; if (namelen >= sizeof(name)) continue; #ifdef OBIO_SPEED_CONTROL if (strcmp(name, "gpio") == 0) { obio_setup_gpios(sc, child); continue; } #endif name[namelen] = 0; ca.ca_name = name; ca.ca_node = child; ca.ca_tag = pa->pa_memt; ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg)); if (strcmp(compat, "gatwick") != 0) { ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr, sizeof(intr)); if (ca.ca_nintr == -1) ca.ca_nintr = OF_getprop(child, "interrupts", intr, sizeof(intr)); } else { intr[0] = parent_intr; ca.ca_nintr = parent_nintr; } ca.ca_reg = reg; ca.ca_intr = intr; config_found(self, &ca, obio_print); } }
static void wi_pci_attach(device_t parent, device_t self, void *aux) { struct wi_pci_softc *psc = device_private(self); struct wi_softc *sc = &psc->psc_wi; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; const char *intrstr; const struct wi_pci_product *wpp; pci_intr_handle_t ih; bus_space_tag_t memt, iot, plxt, tmdt; bus_space_handle_t memh, ioh, plxh, tmdh; char intrbuf[PCI_INTRSTR_LEN]; sc->sc_dev = self; psc->psc_pc = pc; psc->psc_pcitag = pa->pa_tag; wpp = wi_pci_lookup(pa); #ifdef DIAGNOSTIC if (wpp == NULL) { printf("\n"); panic("wi_pci_attach: impossible"); } #endif switch (wpp->wpp_chip) { case CHIP_PLX_OTHER: case CHIP_PLX_9052: /* Map memory and I/O registers. */ if (pci_mapreg_map(pa, WI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, &memt, &memh, NULL, NULL) != 0) { aprint_error(": can't map mem space\n"); return; } if (pci_mapreg_map(pa, WI_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) != 0) { aprint_error(": can't map I/O space\n"); return; } if (wpp->wpp_chip == CHIP_PLX_OTHER) { /* The PLX 9052 doesn't have IO at 0x14. Perhaps other chips have, so we'll make this conditional. */ if (pci_mapreg_map(pa, WI_PCI_PLX_LOIO, PCI_MAPREG_TYPE_IO, 0, &plxt, &plxh, NULL, NULL) != 0) { aprint_error(": can't map PLX\n"); return; } } break; case CHIP_TMD_7160: /* Used instead of PLX on at least one revision of * the National Datacomm Corporation NCP130. Values * for registers acquired from OpenBSD, which in * turn got them from a Linux driver. */ /* Map COR and I/O registers. */ if (pci_mapreg_map(pa, WI_TMD_COR, PCI_MAPREG_TYPE_IO, 0, &tmdt, &tmdh, NULL, NULL) != 0) { aprint_error(": can't map TMD\n"); return; } if (pci_mapreg_map(pa, WI_TMD_IO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) != 0) { aprint_error(": can't map I/O space\n"); return; } break; default: if (pci_mapreg_map(pa, WI_PCI_CBMA, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &iot, &ioh, NULL, NULL) != 0) { aprint_error(": can't map mem space\n"); return; } memt = iot; memh = ioh; sc->sc_pci = 1; break; } pci_aprint_devinfo(pa, NULL); sc->sc_enabled = 1; sc->sc_enable = wi_pci_enable; sc->sc_iot = iot; sc->sc_ioh = ioh; /* Make sure interrupts are disabled. */ CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); if (wpp->wpp_chip == CHIP_PLX_OTHER) { uint32_t command; #define WI_LOCAL_INTCSR 0x4c #define WI_LOCAL_INTEN 0x40 /* poke this into INTCSR */ command = bus_space_read_4(plxt, plxh, WI_LOCAL_INTCSR); command |= WI_LOCAL_INTEN; bus_space_write_4(plxt, plxh, WI_LOCAL_INTCSR, command); } /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); psc->psc_ih = ih; sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wi_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); switch (wpp->wpp_chip) { case CHIP_PLX_OTHER: case CHIP_PLX_9052: /* * Setup the PLX chip for level interrupts and config index 1 * XXX - should really reset the PLX chip too. */ bus_space_write_1(memt, memh, WI_PLX_COR_OFFSET, WI_PLX_COR_VALUE); break; case CHIP_TMD_7160: /* Enable I/O mode and level interrupts on the embedded * card. The card's COR is the first byte of BAR 0. */ bus_space_write_1(tmdt, tmdh, 0, WI_COR_IOMODE); break; default: /* reset HFA3842 MAC core */ wi_pci_reset(sc); break; } printf("%s:", device_xname(self)); if (wi_attach(sc, 0) != 0) { aprint_error_dev(self, "failed to attach controller\n"); pci_intr_disestablish(pa->pa_pc, sc->sc_ih); return; } if (!wpp->wpp_chip) sc->sc_reset = wi_pci_reset; if (pmf_device_register(self, NULL, NULL)) pmf_class_network_register(self, &sc->sc_if); else aprint_error_dev(self, "couldn't establish power handler\n"); }
void exynos_device_register(device_t self, void *aux) { if (device_is_a(self, "armperiph") && device_is_a(device_parent(self), "mainbus")) { /* * XXX KLUDGE ALERT XXX * The iot mainbus supplies is completely wrong since it scales * addresses by 2. The simplest remedy is to replace with our * bus space used for the armcore registers (which armperiph uses). */ struct mainbus_attach_args * const mb = aux; mb->mb_iot = &armv7_generic_bs_tag; return; } if (device_is_a(self, "armgic") && device_is_a(device_parent(self), "armperiph")) { /* * The Exynos4420 armgic is located at a different location! */ extern uint32_t exynos_soc_id; switch (EXYNOS_PRODUCT_ID(exynos_soc_id)) { #ifdef EXYNOS5 case 0xe5410: /* offsets not changed on matt's request */ #if 0 mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE; mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET; mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET; #endif break; case 0xe5422: { struct mpcore_attach_args * const mpcaa = aux; mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE; mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET; mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET; break; } #endif #ifdef EXYNOS4 case 0xe4410: case 0xe4412: { struct mpcore_attach_args * const mpcaa = aux; mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE; mpcaa->mpcaa_off1 = EXYNOS4_GIC_DISTRIBUTOR_OFFSET; mpcaa->mpcaa_off2 = EXYNOS4_GIC_CNTR_OFFSET; break; } #endif default: panic("%s: unknown SoC product id %#x", __func__, (u_int)EXYNOS_PRODUCT_ID(exynos_soc_id)); } return; } if (device_is_a(self, "armgtmr") || device_is_a(self, "mct")) { #ifdef EXYNOS5 /* * The global timer is dependent on the MCT running. */ bus_size_t o = EXYNOS5_MCT_OFFSET + MCT_G_TCON; uint32_t v = bus_space_read_4(&armv7_generic_bs_tag, exynos_core_bsh, o); v |= G_TCON_START; bus_space_write_4(&armv7_generic_bs_tag, exynos_core_bsh, o, v); #endif /* * The frequencies of the timers are the reference * frequency. */ prop_dictionary_set_uint32(device_properties(self), "frequency", EXYNOS_F_IN_FREQ); return; } }
void ibm4xx_show_pci_map(void) { pci_chipset_tag_t pc = &genppc_ibm4xx_chipset; paddr_t la, lm, pl, ph; pcitag_t tag; setup_pcicfg_window(); printf("Local -> PCI map\n"); la = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM0LA); lm = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM0MA); pl = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM0PCILA); ph = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM0PCIHA); printf("0: %08lx,%08lx -> %08lx%08lx %sprefetchable, %s\n", la, lm, ph, pl, (lm & 2) ? "":"not ", (lm & 1) ? "enabled":"disabled"); la = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM1LA); lm = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM1MA); pl = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM1PCILA); ph = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM1PCIHA); printf("1: %08lx,%08lx -> %08lx%08lx %sprefetchable, %s\n", la, lm, ph, pl, (lm & 2) ? "":"not ", (lm & 1) ? "enabled":"disabled"); la = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM2LA); lm = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM2MA); pl = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM2PCILA); ph = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PMM2PCIHA); printf("2: %08lx,%08lx -> %08lx%08lx %sprefetchable, %s\n", la, lm, ph, pl, (lm & 2) ? "":"not ", (lm & 1) ? "enabled":"disabled"); printf("PCI -> Local map\n"); tag = pci_make_tag(pc, 0, 0, 0); pl = pci_conf_read(pc, tag, PCIC_PTM1BAR); la = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PTM1LA); lm = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PTM1MS); printf("1: %08lx -> %08lx,%08lx %s\n", pl, la, lm, (lm & 1)?"enabled":"disabled"); pl = pci_conf_read(pc, tag, PCIC_PTM2BAR); la = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PTM2LA); lm = bus_space_read_4(pcicfg_iot, pcicfg_ioh, PCIL_PTM2MS); printf("2: %08lx -> %08lx,%08lx %s\n", pl, la, lm, (lm & 1)?"enabled":"disabled"); }
void ohci_pci_attach(struct device *parent, struct device *self, void *aux) { struct ohci_pci_softc *sc = (struct ohci_pci_softc *)self; struct pci_attach_args *pa = (struct pci_attach_args *)aux; pci_chipset_tag_t pc = pa->pa_pc; char const *intrstr; pci_intr_handle_t ih; int s; const char *vendor; char *devname = sc->sc.sc_bus.bdev.dv_xname; /* Map I/O registers */ if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) { printf(": can't map mem space\n"); return; } /* Record what interrupts were enabled by SMM/BIOS. */ sc->sc.sc_intre = bus_space_read_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_ENABLE); /* Disable interrupts, so we don't get any spurious ones. */ bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_MIE); sc->sc_pc = pc; sc->sc.sc_bus.dmatag = pa->pa_dmat; bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_MIE); s = splusb(); /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); splx(s); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, ohci_intr, sc, devname); if (sc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); splx(s); return; } printf(": %s", intrstr); /* Figure out vendor for root hub descriptor. */ vendor = pci_findvendor(pa->pa_id); sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id); if (vendor) strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor)); else snprintf(sc->sc.sc_vendor, sizeof (sc->sc.sc_vendor), "vendor 0x%04x", PCI_VENDOR(pa->pa_id)); /* Display revision and perform legacy emulation handover. */ if (ohci_checkrev(&sc->sc) != USBD_NORMAL_COMPLETION || ohci_handover(&sc->sc) != USBD_NORMAL_COMPLETION) { bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); pci_intr_disestablish(sc->sc_pc, sc->sc_ih); splx(s); return; } /* Ignore interrupts for now */ sc->sc.sc_bus.dying = 1; config_defer(self, ohci_pci_attach_deferred); splx(s); return; }
static __inline uint32_t malo_hal_read4(struct malo_hal *mh, bus_size_t off) { return bus_space_read_4(mh->mh_iot, mh->mh_ioh, off); }
static uint32_t rex3_read(struct newport_devconfig *dc, bus_size_t rexreg) { return bus_space_read_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET + rexreg); }
static uint32_t wiibus_csr_read(struct wiibus_softc *sc, uint16_t reg) { return (bus_space_read_4(sc->sc_tag, sc->sc_handle, reg)); }
void iof_attach(struct device *parent, struct device *self, void *aux) { struct iof_softc *sc = (struct iof_softc *)self; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; bus_space_tag_t memt; bus_space_handle_t memh; bus_size_t memsize; const char *intrstr; printf(": "); if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM, 0, &memt, &memh, NULL, &memsize, 0)) { printf("can't map mem space\n"); return; } sc->sc_pc = pa->pa_pc; sc->sc_tag = pa->pa_tag; sc->sc_dmat = pa->pa_dmat; /* * Build a suitable bus_space_handle by restoring the original * non-swapped subword access methods. * * XXX This is horrible and will need to be rethought if * XXX IOC4 exist as real, removable PCI cards and * XXX we ever support them cards not plugged to xbridges. */ sc->sc_mem_bus_space = malloc(sizeof (*sc->sc_mem_bus_space), M_DEVBUF, M_NOWAIT); if (sc->sc_mem_bus_space == NULL) { printf("can't allocate bus_space\n"); goto unmap; } bcopy(memt, sc->sc_mem_bus_space, sizeof(*sc->sc_mem_bus_space)); sc->sc_mem_bus_space->_space_read_1 = xbow_read_1; sc->sc_mem_bus_space->_space_read_2 = xbow_read_2; sc->sc_mem_bus_space->_space_read_raw_2 = xbow_read_raw_2; sc->sc_mem_bus_space->_space_write_1 = xbow_write_1; sc->sc_mem_bus_space->_space_write_2 = xbow_write_2; sc->sc_mem_bus_space->_space_write_raw_2 = xbow_write_raw_2; sc->sc_memt = sc->sc_mem_bus_space; sc->sc_memh = memh; sc->sc_mcr = bus_space_read_4(sc->sc_memt, sc->sc_memh, IOC4_MCR); /* * Acknowledge all pending interrupts, and disable them. */ bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IEC, ~0x0); bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IES, 0x0); bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IR, bus_space_read_4(sc->sc_memt, sc->sc_memh, IOC4_SIO_IR)); bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IEC, ~0x0); bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IES, 0x0); bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IR, bus_space_read_4(sc->sc_memt, sc->sc_memh, IOC4_OTHER_IR)); if (pci_intr_map(pa, &ih) != 0) { printf("failed to map interrupt!\n"); goto unmap; } intrstr = pci_intr_string(sc->sc_pc, ih); sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_TTY, iof_intr, sc, self->dv_xname); if (sc->sc_ih == NULL) { printf("failed to establish interrupt at %s\n", intrstr); goto unmap; } printf("%s\n", intrstr); /* * Attach other sub-devices. */ iof_attach_child(self, "com", IOC4_UARTA_BASE, IOC4DEV_SERIAL_A); iof_attach_child(self, "com", IOC4_UARTB_BASE, IOC4DEV_SERIAL_B); iof_attach_child(self, "com", IOC4_UARTC_BASE, IOC4DEV_SERIAL_C); iof_attach_child(self, "com", IOC4_UARTD_BASE, IOC4DEV_SERIAL_D); iof_attach_child(self, "iockbc", IOC4_KBC_BASE, IOC4DEV_KBC); iof_attach_child(self, "dsrtc", IOC4_BYTEBUS_0, IOC4DEV_RTC); return; unmap: bus_space_unmap(memt, memh, memsize); }
__unused static inline uint32_t bcmccb_read_4(struct bcmccb_softc *sc, bus_size_t o) { return bus_space_read_4(sc->sc_bst, sc->sc_bsh, o); }
void imxahci_attach(struct device *parent, struct device *self, void *args) { struct armv7_attach_args *aa = args; struct imxahci_softc *imxsc = (struct imxahci_softc *) self; struct ahci_softc *sc = &imxsc->sc; uint32_t timeout = 0x100000; sc->sc_iot = aa->aa_iot; sc->sc_ios = aa->aa_dev->mem[0].size; sc->sc_dmat = aa->aa_dmat; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("imxahci_attach: bus_space_map failed!"); sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_BIO, ahci_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); goto unmap; } imxsc->sc_clk = clk_get("ahb"); if (imxsc->sc_clk == NULL) { printf(": can't get clock\n"); goto unmap; } clk_enable(imxsc->sc_clk); /* power it up */ clk_enable(clk_get("sata_ref_100m")); clk_enable(clk_get("sata")); delay(100); /* power phy up */ imxiomuxc_enable_sata(); /* setup */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR) & ~SATA_P0PHYCR_TEST_PDDQ); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_GHC, SATA_GHC_HR); while (!bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_VERSIONR)); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_CAP, bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_CAP) | SATA_CAP_SSS); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_PI, 1); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_TIMER1MS, clk_get_rate(imxsc->sc_clk)); while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0SSTS) & 0xF) && timeout--); if (ahci_attach(sc) != 0) { /* error printed by ahci_attach */ goto irq; } return; irq: arm_intr_disestablish(sc->sc_ih); unmap: bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); }
static void obiosdhc_attach(device_t parent, device_t self, void *aux) { struct obiosdhc_softc * const sc = device_private(self); struct obio_attach_args * const oa = aux; prop_dictionary_t prop = device_properties(self); uint32_t clkd, stat; int error, timo, clksft, n; bool support8bit = false; const char *transfer_mode = "PIO"; #ifdef TI_AM335X size_t i; #endif prop_dictionary_get_bool(prop, "8bit", &support8bit); sc->sc.sc_dmat = oa->obio_dmat; sc->sc.sc_dev = self; sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS; sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON; sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC; sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY; if (support8bit) sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE; #ifdef TI_AM335X sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET; sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY; #endif #if defined(OMAP_3530) sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY; #endif sc->sc.sc_host = sc->sc_hosts; sc->sc.sc_clkbase = 96000; /* 96MHZ */ if (!prop_dictionary_get_uint32(prop, "clkmask", &sc->sc.sc_clkmsk)) sc->sc.sc_clkmsk = 0x0000ffc0; sc->sc.sc_vendor_rod = obiosdhc_rod; sc->sc.sc_vendor_write_protect = obiosdhc_write_protect; sc->sc.sc_vendor_card_detect = obiosdhc_card_detect; sc->sc.sc_vendor_bus_clock = obiosdhc_bus_clock; sc->sc_bst = oa->obio_iot; clksft = ffs(sc->sc.sc_clkmsk) - 1; error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0, &sc->sc_bsh); if (error) { aprint_error_dev(self, "can't map registers: %d\n", error); return; } bus_space_subregion(sc->sc_bst, sc->sc_bsh, OMAP3_SDMMC_SDHC_OFFSET, OMAP3_SDMMC_SDHC_SIZE, &sc->sc_sdhc_bsh); #if NEDMA > 0 if (oa->obio_edmabase != -1) { cv_init(&sc->sc_edma_cv, "sdhcedma"); sc->sc_edma_fifo = oa->obio_addr + OMAP3_SDMMC_SDHC_OFFSET + SDHC_DATA; obiosdhc_edma_init(sc, oa->obio_edmabase); sc->sc.sc_flags |= SDHC_FLAG_USE_DMA; sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA; sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN; sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY; sc->sc.sc_vendor_transfer_data_dma = obiosdhc_edma_xfer_data; transfer_mode = "EDMA"; } #endif aprint_naive("\n"); aprint_normal(": SDHC controller (%s)\n", transfer_mode); #ifdef TI_AM335X /* XXX Not really AM335X-specific. */ for (i = 0; i < __arraycount(am335x_sdhc); i++) if ((oa->obio_addr == am335x_sdhc[i].as_base_addr) && (oa->obio_intr == am335x_sdhc[i].as_intr)) { prcm_module_enable(&am335x_sdhc[i].as_module); break; } KASSERT(i < __arraycount(am335x_sdhc)); #endif /* XXXXXX: Turn-on regulator via I2C. */ /* XXXXXX: And enable ICLOCK/FCLOCK. */ /* MMCHS Soft reset */ bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG, SYSCONFIG_SOFTRESET); timo = 3000000; /* XXXX 3 sec. */ while (timo--) { if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) & SYSSTATUS_RESETDONE) break; delay(1); } if (timo == 0) aprint_error_dev(self, "Soft reset timeout\n"); bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG, SYSCONFIG_ENAWAKEUP | SYSCONFIG_AUTOIDLE | SYSCONFIG_SIDLEMODE_AUTO | SYSCONFIG_CLOCKACTIVITY_FCLK | SYSCONFIG_CLOCKACTIVITY_ICLK); sc->sc_ih = intr_establish(oa->obio_intr, IPL_VM, IST_LEVEL, sdhc_intr, &sc->sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "failed to establish interrupt %d\n", oa->obio_intr); goto fail; } error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh, oa->obio_size - OMAP3_SDMMC_SDHC_OFFSET); if (error != 0) { aprint_error_dev(self, "couldn't initialize host, error=%d\n", error); goto fail; } /* Set SDVS 1.8v and DTW 1bit mode */ SDHC_WRITE(sc, SDHC_HOST_CTL, SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8)); bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_OD); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE | SDHC_SDCLK_ENABLE); SDHC_WRITE(sc, SDHC_HOST_CTL, SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft); /* * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start * from 'OMAP35x Applications Processor Technical Reference Manual'. * * During the INIT procedure, the MMCHS controller generates 80 clock * periods. In order to keep the 1ms gap, the MMCHS controller should * be configured to generate a clock whose frequency is smaller or * equal to 80 KHz. */ SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk); clkd = CLKD(80); n = 1; while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) { clkd >>= 1; n <<= 1; } SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft)); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE); bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT); for (; n > 0; n--) { SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000); timo = 3000000; /* XXXX 3 sec. */ stat = 0; while (!(stat & SDHC_COMMAND_COMPLETE)) { stat = SDHC_READ(sc, SDHC_NINTR_STATUS); if (--timo == 0) break; delay(1); } if (timo == 0) { aprint_error_dev(self, "INIT Procedure timeout\n"); break; } SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat); } bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft); SDHC_WRITE(sc, SDHC_CLOCK_CTL, SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE); return; fail: if (sc->sc_ih) { intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; } bus_space_unmap(sc->sc_bst, sc->sc_bsh, oa->obio_size); }
void omgpio_intr_level(unsigned int gpio, unsigned int level) { u_int32_t fe, re, l0, l1, bit; struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; int s; s = splhigh(); fe = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_FALLINGDETECT); re = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_RISINGDETECT); l0 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT0); l1 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT1); bit = 1 << GPIO_PIN_TO_OFFSET(gpio); switch (level) { case IST_NONE: fe &= ~bit; re &= ~bit; l0 &= ~bit; l1 &= ~bit; break; case IST_EDGE_FALLING: fe |= bit; re &= ~bit; l0 &= ~bit; l1 &= ~bit; break; case IST_EDGE_RISING: fe &= ~bit; re |= bit; l0 &= ~bit; l1 &= ~bit; break; case IST_PULSE: /* XXX */ /* FALLTHRU */ case IST_EDGE_BOTH: fe |= bit; re |= bit; l0 &= ~bit; l1 &= ~bit; break; case IST_LEVEL_LOW: fe &= ~bit; re &= ~bit; l0 |= bit; l1 &= ~bit; break; case IST_LEVEL_HIGH: fe &= ~bit; re &= ~bit; l0 &= ~bit; l1 |= bit; break; break; default: panic("omgpio_intr_level: bad level: %d", level); break; } bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_FALLINGDETECT, fe); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_RISINGDETECT, re); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT0, l0); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT1, l1); splx(s); }
void platform_mp_start_ap(void) { bus_space_handle_t scu; bus_space_handle_t src; uint32_t val; int i; if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0) panic("Couldn't map the SCU\n"); if (bus_space_map(fdtbus_bs_tag, SRC_PHYSBASE, SRC_SIZE, 0, &src) != 0) panic("Couldn't map the system reset controller (SRC)\n"); /* * Invalidate SCU cache tags. The 0x0000ffff constant invalidates all * ways on all cores 0-3. Per the ARM docs, it's harmless to write to * the bits for cores that are not present. */ bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff); /* * Erratum ARM/MP: 764369 (problems with cache maintenance). * Setting the "disable-migratory bit" in the undocumented SCU * Diagnostic Control Register helps work around the problem. */ val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL); bus_space_write_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL, val | SCU_DIAG_DISABLE_MIGBIT); /* * Enable the SCU, then clean the cache on this core. After these two * operations the cache tag ram in the SCU is coherent with the contents * of the cache on this core. The other cores aren't running yet so * their caches can't contain valid data yet, but we've initialized * their SCU tag ram above, so they will be coherent from startup. */ val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG); bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG, val | SCU_CONTROL_ENABLE); cpu_idcache_wbinv_all(); /* * For each AP core, set the entry point address and argument registers, * and set the core-enable and core-reset bits in the control register. */ val = bus_space_read_4(fdtbus_bs_tag, src, SRC_CONTROL_REG); for (i=1; i < mp_ncpus; i++) { bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR0_C1FUNC + 8*i, pmap_kextract((vm_offset_t)mpentry)); bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR1_C1ARG + 8*i, 0); val |= ((1 << (SRC_CONTROL_C1ENA_SHIFT - 1 + i )) | ( 1 << (SRC_CONTROL_C1RST_SHIFT - 1 + i))); } bus_space_write_4(fdtbus_bs_tag, src, 0, val); armv7_sev(); bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE); bus_space_unmap(fdtbus_bs_tag, src, SRC_SIZE); }
static int fimd_attach(device_t dev) { struct panel_info panel; struct fimd_softc *sc; device_t gpio_dev; int reg; sc = device_get_softc(dev); sc->dev = dev; if (bus_alloc_resources(dev, fimd_spec, sc->res)) { device_printf(dev, "could not allocate resources\n"); return (ENXIO); } /* Memory interface */ sc->bst = rman_get_bustag(sc->res[0]); sc->bsh = rman_get_bushandle(sc->res[0]); sc->bst_disp = rman_get_bustag(sc->res[1]); sc->bsh_disp = rman_get_bushandle(sc->res[1]); sc->bst_sysreg = rman_get_bustag(sc->res[2]); sc->bsh_sysreg = rman_get_bushandle(sc->res[2]); if (get_panel_info(sc, &panel)) { device_printf(dev, "Can't get panel info\n"); return (ENXIO); } panel.fixvclk = 0; panel.ivclk = 0; panel.clkval_f = 2; sc->panel = &panel; /* Get the GPIO device, we need this to give power to USB */ gpio_dev = devclass_get_device(devclass_find("gpio"), 0); if (gpio_dev == NULL) { /* TODO */ } reg = bus_space_read_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214); reg |= FIMDBYPASS_DISP1; bus_space_write_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214, reg); sc->sc_info.fb_width = panel.width; sc->sc_info.fb_height = panel.height; sc->sc_info.fb_stride = sc->sc_info.fb_width * 2; sc->sc_info.fb_bpp = sc->sc_info.fb_depth = 16; sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride; sc->sc_info.fb_vbase = (intptr_t)kmem_alloc_contig(kernel_arena, sc->sc_info.fb_size, M_ZERO, 0, ~0, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE); sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase); #if 0 printf("%dx%d [%d]\n", sc->sc_info.fb_width, sc->sc_info.fb_height, sc->sc_info.fb_stride); printf("pbase == 0x%08x\n", sc->sc_info.fb_pbase); #endif memset((int8_t *)sc->sc_info.fb_vbase, 0x0, sc->sc_info.fb_size); fimd_init(sc); sc->sc_info.fb_name = device_get_nameunit(dev); /* Ask newbus to attach framebuffer device to me. */ sc->sc_fbd = device_add_child(dev, "fbd", device_get_unit(dev)); if (sc->sc_fbd == NULL) device_printf(dev, "Can't attach fbd device\n"); if (device_probe_and_attach(sc->sc_fbd) != 0) { device_printf(sc->dev, "Failed to attach fbd device\n"); } return (0); }
static void exynos5410_usb2phy_enable(bus_space_handle_t usb2phy_bsh) { uint32_t phyhost; //, phyotg; uint32_t phyhsic; uint32_t ehcictrl, ohcictrl; /* host configuration: */ phyhost = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_CTRL0); /* host phy reference clock; assumption its 24 MHz now */ phyhost &= ~HOST_CTRL0_FSEL_MASK; phyhost |= __SHIFTIN(FSEL_CLKSEL_24M, HOST_CTRL0_FSEL_MASK); /* enable normal mode of operation */ phyhost &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP); /* host phy reset */ phyhost &= ~(HOST_CTRL0_PHY_SWRST | HOST_CTRL0_PHY_SWRST_ALL | HOST_CTRL0_SIDDQ | HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP); /* host link reset */ phyhost |= HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST | HOST_CTRL0_COMMONON_N; /* do the reset */ bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_CTRL0, phyhost); DELAY(10000); phyhost &= ~(HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST); bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_CTRL0, phyhost); /* HSIC control */ phyhsic = __SHIFTIN(HSIC_CTRL_REFCLKDIV_12, HSIC_CTRL_REFCLKDIV_MASK) | __SHIFTIN(HSIC_CTRL_REFCLKSEL_DEFAULT, HSIC_CTRL_REFCLKSEL_MASK) | HSIC_CTRL_PHY_SWRST; bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL1, phyhsic); bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL2, phyhsic); DELAY(10); phyhsic &= ~HSIC_CTRL_PHY_SWRST; bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL1, phyhsic); bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL2, phyhsic); DELAY(80); #if 0 /* otg configuration: */ phyotg = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_OTG_SYS); /* otg phy refrence clock: assumption its 24 Mhz now */ phyotg &= ~OTG_SYS_FSEL_MASK; phyotg |= __SHIFTIN(OTG_SYS_FSEL_MASK, FSEL_CLKSEL_24M); /* enable normal mode of operation */ phyotg &= ~(OTG_SYS_FORCESUSPEND | OTG_SYS_FORCESLEEP | OTG_SYS_SIDDQ_UOTG | OTG_SYS_REFCLKSEL_MASK | OTG_SYS_COMMON_ON); /* OTG phy and link reset */ phyotg |= OTG_SYS_PHY0_SWRST | OTG_SYS_PHYLINK_SWRST | OTG_SYS_OTGDISABLE | OTG_SYS_REFCLKSEL_MASK; /* do the reset */ bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_OTG_SYS, phyotg); DELAY(10000); phyotg &= ~(OTG_SYS_PHY0_SWRST | OTG_SYS_LINK_SWRST_UOTG | OTG_SYS_PHYLINK_SWRST); bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_OTG_SYS, phyotg); #endif /* enable EHCI DMA burst: */ ehcictrl = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_EHCICTRL); ehcictrl |= HOST_EHCICTRL_ENA_INCRXALIGN | HOST_EHCICTRL_ENA_INCR4 | HOST_EHCICTRL_ENA_INCR8 | HOST_EHCICTRL_ENA_INCR16; bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_EHCICTRL, ehcictrl); /* Set OHCI suspend */ ohcictrl = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_OHCICTRL); ohcictrl |= HOST_OHCICTRL_SUSPLGCY; bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_OHCICTRL, ohcictrl); }
u_int amptimer_get_timecount(struct timecounter *tc) { struct amptimer_softc *sc = amptimer_timecounter.tc_priv; return bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTIMER_CNT_LOW); }
static void sackbc_attach(device_t parent, device_t self, void *aux) { struct sackbc_softc *sc = device_private(self); struct sacc_softc *psc = device_private(parent); struct sa1111_attach_args *aa = (struct sa1111_attach_args *)aux; device_t child; uint32_t tmp, clock_bit; int intr, slot; switch (aa->sa_addr) { case SACC_KBD0: clock_bit = (1<<6); intr = 21; break; case SACC_KBD1: clock_bit = (1<<5); intr = 18; break; default: return; } if (aa->sa_size <= 0) aa->sa_size = SACCKBD_SIZE; if (aa->sa_intr == SACCCF_INTR_DEFAULT) aa->sa_intr = intr; sc->dev = self; sc->iot = psc->sc_iot; if (bus_space_subregion(psc->sc_iot, psc->sc_ioh, aa->sa_addr, aa->sa_size, &sc->ioh)) { aprint_normal(": can't map subregion\n"); return; } /* enable clock for PS/2 kbd or mouse */ tmp = bus_space_read_4(psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR); bus_space_write_4(psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR, tmp | clock_bit); sc->ih_rx = NULL; sc->intr = aa->sa_intr; sc->polling = 0; tmp = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_CR); bus_space_write_4(sc->iot, sc->ioh, SACCKBD_CR, tmp | KBDCR_ENA); /* XXX: this is necessary to get keyboard working. but I don't know why */ bus_space_write_4(sc->iot, sc->ioh, SACCKBD_CLKDIV, 2); tmp = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_STAT); if ((tmp & KBDSTAT_ENA) == 0) { printf("??? can't enable KBD controller\n"); return; } printf("\n"); sc->pt = pckbport_attach(sc, &sackbc_ops); /* * Although there is no such thing as SLOT for SA-1111 kbd * controller, pckbd and pms drivers require it. */ for (slot = PCKBPORT_KBD_SLOT; slot <= PCKBPORT_AUX_SLOT; ++slot) { child = pckbport_attach_slot(self, sc->pt, slot); if (child == NULL) continue; sc->slot = slot; rnd_attach_source(&sc->rnd_source, device_xname(child), RND_TYPE_TTY, RND_FLAG_DEFAULT|RND_FLAG_ESTIMATE_VALUE); /* only one of KBD_SLOT or AUX_SLOT is used. */ break; } }
int amptimer_intr(void *frame) { struct amptimer_softc *sc = amptimer_cd.cd_devs[0]; struct amptimer_pcpu_softc *pc = &sc->sc_pstat[CPU_INFO_UNIT(curcpu())]; uint64_t now; uint64_t nextevent; uint32_t r, reg; #if defined(USE_GTIMER_CMP) int skip = 1; #else int64_t delay; #endif int rc = 0; /* * DSR - I know that the tick timer is 64 bits, but the following * code deals with rollover, so there is no point in dealing * with the 64 bit math, just let the 32 bit rollover * do the right thing */ now = amptimer_readcnt64(sc); while (pc->pc_nexttickevent <= now) { pc->pc_nexttickevent += sc->sc_ticks_per_intr; pc->pc_ticks_err_sum += sc->sc_ticks_err_cnt; /* looping a few times is faster than divide */ while (pc->pc_ticks_err_sum > hz) { pc->pc_nexttickevent += 1; pc->pc_ticks_err_sum -= hz; } #ifdef AMPTIMER_DEBUG sc->sc_clk_count.ec_count++; #endif rc = 1; hardclock(frame); } while (pc->pc_nextstatevent <= now) { do { r = random() & (sc->sc_statvar -1); } while (r == 0); /* random == 0 not allowed */ pc->pc_nextstatevent += sc->sc_statmin + r; /* XXX - correct nextstatevent? */ #ifdef AMPTIMER_DEBUG sc->sc_stat_count.ec_count++; #endif rc = 1; statclock(frame); } if (pc->pc_nexttickevent < pc->pc_nextstatevent) nextevent = pc->pc_nexttickevent; else nextevent = pc->pc_nextstatevent; #if defined(USE_GTIMER_CMP) again: reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL); reg &= ~GTIMER_CTRL_COMP; bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_LOW, nextevent & 0xffffffff); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_HIGH, nextevent >> 32); reg |= GTIMER_CTRL_COMP; bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg); now = amptimer_readcnt64(sc); if (now >= nextevent) { nextevent = now + skip; skip += 1; goto again; } #else /* clear old status */ bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_STATUS, PTIMER_STATUS_EVENT); delay = nextevent - now; if (delay < 0) delay = 1; reg = bus_space_read_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL); if ((reg & (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN)) != (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN)) bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL, (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN)); bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_LOAD, delay); #endif return (rc); }
static __inline uint32_t RD4(struct ixpwdog_softc *sc, bus_size_t off) { return bus_space_read_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, off); }
int beinit(struct ifnet *ifp) { struct be_softc *sc = ifp->if_softc; bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t br = sc->sc_br; bus_space_handle_t cr = sc->sc_cr; struct qec_softc *qec = sc->sc_qec; uint32_t v; uint32_t qecaddr; uint8_t *ea; int rc, s; s = splnet(); qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ); bestop(ifp, 1); ea = sc->sc_enaddr; bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]); bus_space_write_4(t, br, BE_BRI_MACADDR1, (ea[2] << 8) | ea[3]); bus_space_write_4(t, br, BE_BRI_MACADDR2, (ea[4] << 8) | ea[5]); /* Clear hash table */ bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0); /* Re-initialize RX configuration */ v = BE_BR_RXCFG_FIFO; bus_space_write_4(t, br, BE_BRI_RXCFG, v); be_mcreset(sc); bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd); bus_space_write_4(t, br, BE_BRI_XIFCFG, BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV); bus_space_write_4(t, br, BE_BRI_JSIZE, 4); /* * Turn off counter expiration interrupts as well as * 'gotframe' and 'sentframe' */ bus_space_write_4(t, br, BE_BRI_IMASK, BE_BR_IMASK_GOTFRAME | BE_BR_IMASK_RCNTEXP | BE_BR_IMASK_ACNTEXP | BE_BR_IMASK_CCNTEXP | BE_BR_IMASK_LCNTEXP | BE_BR_IMASK_CVCNTEXP | BE_BR_IMASK_SENTFRAME | BE_BR_IMASK_NCNTEXP | BE_BR_IMASK_ECNTEXP | BE_BR_IMASK_LCCNTEXP | BE_BR_IMASK_FCNTEXP | BE_BR_IMASK_DTIMEXP); /* Channel registers: */ bus_space_write_4(t, cr, BE_CRI_RXDS, (uint32_t)sc->sc_rb.rb_rxddma); bus_space_write_4(t, cr, BE_CRI_TXDS, (uint32_t)sc->sc_rb.rb_txddma); qecaddr = sc->sc_channel * qec->sc_msize; bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr); bus_space_write_4(t, cr, BE_CRI_RXRBUF, qecaddr); bus_space_write_4(t, cr, BE_CRI_TXWBUF, qecaddr + qec->sc_rsize); bus_space_write_4(t, cr, BE_CRI_TXRBUF, qecaddr + qec->sc_rsize); bus_space_write_4(t, cr, BE_CRI_RIMASK, 0); bus_space_write_4(t, cr, BE_CRI_TIMASK, 0); bus_space_write_4(t, cr, BE_CRI_QMASK, 0); bus_space_write_4(t, cr, BE_CRI_BMASK, 0); bus_space_write_4(t, cr, BE_CRI_CCNT, 0); /* Set max packet length */ v = ETHER_MAX_LEN; if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) v += ETHER_VLAN_ENCAP_LEN; bus_space_write_4(t, br, BE_BRI_RXMAX, v); bus_space_write_4(t, br, BE_BRI_TXMAX, v); /* Enable transmitter */ bus_space_write_4(t, br, BE_BRI_TXCFG, BE_BR_TXCFG_FIFO | BE_BR_TXCFG_ENABLE); /* Enable receiver */ v = bus_space_read_4(t, br, BE_BRI_RXCFG); v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE; bus_space_write_4(t, br, BE_BRI_RXCFG, v); if ((rc = be_ifmedia_upd(ifp)) != 0) goto out; ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; callout_reset(&sc->sc_tick_ch, hz, be_tick, sc); return 0; out: splx(s); return rc; }
void tcpcib_attach(struct device *parent, struct device *self, void *aux) { struct tcpcib_softc *sc = (struct tcpcib_softc *)self; struct pci_attach_args *pa = aux; struct timecounter *tc = &sc->sc_hpet_timecounter; u_int32_t reg, wdtbase; sc->sc_active = 0; /* High Precision Event Timer */ sc->sc_hpet_iot = pa->pa_memt; if (bus_space_map(sc->sc_hpet_iot, E600_HPET_BASE, E600_HPET_SIZE, 0, &sc->sc_hpet_ioh) == 0) { tc->tc_get_timecount = tcpcib_hpet_get_timecount; /* XXX 64-bit counter is not supported! */ tc->tc_counter_mask = 0xffffffff; reg = bus_space_read_4(sc->sc_hpet_iot, sc->sc_hpet_ioh, E600_HPET_PERIOD); /* femtosecs -> Hz */ tc->tc_frequency = 1000000000000000ULL / reg; tc->tc_name = sc->sc_dev.dv_xname; tc->tc_quality = 2000; tc->tc_priv = sc; tc_init(tc); /* Enable counting */ bus_space_write_4(sc->sc_hpet_iot, sc->sc_hpet_ioh, E600_HPET_GC, E600_HPET_GC_ENABLE); sc->sc_active |= E600_HPET_ACTIVE; printf(": %llu Hz timer", tc->tc_frequency); } /* Map Watchdog I/O space */ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, E600_LPC_WDTBA); wdtbase = reg & 0xffff; sc->sc_wdt_iot = pa->pa_iot; if (reg & (1U << 31) && wdtbase) { if (PCI_MAPREG_IO_ADDR(wdtbase) == 0 || bus_space_map(sc->sc_wdt_iot, PCI_MAPREG_IO_ADDR(wdtbase), E600_WDT_SIZE, 0, &sc->sc_wdt_ioh)) { printf("%c can't map watchdog I/O space", sc->sc_active ? ',' : ':'); goto corepcib; } printf("%c watchdog", sc->sc_active ? ',' : ':'); /* Check for reboot on timeout */ reg = bus_space_read_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_RR1); if (reg & E600_WDT_RR1_TIMEOUT) { printf(", reboot on timeout"); /* Clear timeout bit */ tcpcib_wdt_unlock(sc); bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_RR1, E600_WDT_RR1_TIMEOUT); } /* Check it's not locked already */ reg = bus_space_read_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_WDTLR); if (reg & E600_WDT_WDTLR_LOCK) { printf(", locked"); goto corepcib; } /* Disable watchdog */ tcpcib_wdt_stop(sc); sc->sc_wdt_period = 0; sc->sc_active |= E600_WDT_ACTIVE; /* Register new watchdog */ wdog_register(tcpcib_wdt_cb, sc); } corepcib: /* Provide core pcib(4) functionality */ pcibattach(parent, self, aux); }
void be_mcreset(struct be_softc *sc) { struct ethercom *ec = &sc->sc_ethercom; struct ifnet *ifp = &sc->sc_ethercom.ec_if; bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t br = sc->sc_br; uint32_t v; uint32_t crc; uint16_t hash[4]; struct ether_multi *enm; struct ether_multistep step; if (ifp->if_flags & IFF_PROMISC) { v = bus_space_read_4(t, br, BE_BRI_RXCFG); v |= BE_BR_RXCFG_PMISC; bus_space_write_4(t, br, BE_BRI_RXCFG, v); return; } if (ifp->if_flags & IFF_ALLMULTI) { hash[3] = hash[2] = hash[1] = hash[0] = 0xffff; goto chipit; } hash[3] = hash[2] = hash[1] = hash[0] = 0; ETHER_FIRST_MULTI(step, ec, enm); while (enm != NULL) { if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { /* * We must listen to a range of multicast * addresses. For now, just accept all * multicasts, rather than trying to set only * those filter bits needed to match the range. * (At this time, the only use of address * ranges is for IP multicast routing, for * which the range is big enough to require * all bits set.) */ hash[3] = hash[2] = hash[1] = hash[0] = 0xffff; ifp->if_flags |= IFF_ALLMULTI; goto chipit; } crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); /* Just want the 6 most significant bits. */ crc >>= 26; hash[crc >> 4] |= 1 << (crc & 0xf); ETHER_NEXT_MULTI(step, enm); } ifp->if_flags &= ~IFF_ALLMULTI; chipit: /* Enable the hash filter */ bus_space_write_4(t, br, BE_BRI_HASHTAB0, hash[0]); bus_space_write_4(t, br, BE_BRI_HASHTAB1, hash[1]); bus_space_write_4(t, br, BE_BRI_HASHTAB2, hash[2]); bus_space_write_4(t, br, BE_BRI_HASHTAB3, hash[3]); v = bus_space_read_4(t, br, BE_BRI_RXCFG); v &= ~BE_BR_RXCFG_PMISC; v |= BE_BR_RXCFG_HENABLE; bus_space_write_4(t, br, BE_BRI_RXCFG, v); }
void ohci_aubus_attach(device_t parent, device_t self, void *aux) { ohci_softc_t *sc = device_private(self); void *ih; usbd_status r; uint32_t x, tmp; bus_addr_t usbh_base, usbh_enable; struct aubus_attach_args *aa = aux; r = 0; usbh_base = aa->aa_addrs[0]; usbh_enable = aa->aa_addrs[1]; sc->sc_size = aa->aa_addrs[2]; sc->iot = aa->aa_st; sc->sc_bus.dmatag = (bus_dma_tag_t)aa->aa_dt; sc->sc_dev = self; sc->sc_bus.hci_private = sc; if (bus_space_map(sc->iot, usbh_base, sc->sc_size, 0, &sc->ioh)) { aprint_error_dev(self, "unable to map USBH registers\n"); return; } /* * Enable the USB Host controller here. * As per 7.2 in the Au1500 manual: * * (1) Set CE bit to enable clocks. * (2) Set E to enable OHCI * (3) Clear HCFS in OHCI_CONTROL. * (4) Wait for RD bit to be set. */ x = bus_space_read_4(sc->iot, sc->ioh, usbh_enable); x |= UE_CE; bus_space_write_4(sc->iot, sc->ioh, usbh_enable, x); delay(10); x |= UE_E; #ifdef __MIPSEB__ x |= UE_BE; #endif bus_space_write_4(sc->iot, sc->ioh, usbh_enable, x); delay(10); x = bus_space_read_4(sc->iot, sc->ioh, OHCI_CONTROL); x &= ~(OHCI_HCFS_MASK); bus_space_write_4(sc->iot, sc->ioh, OHCI_CONTROL, x); delay(10); /* Need to read USBH_ENABLE twice in succession according to * au1500 Errata #7. */ for (x = 100; x; x--) { bus_space_read_4(sc->iot, sc->ioh, usbh_enable); tmp = bus_space_read_4(sc->iot, sc->ioh, usbh_enable); if (tmp&UE_RD) break; delay(1000); } printf(": Alchemy OHCI\n"); /* Disable OHCI interrupts */ bus_space_write_4(sc->iot, sc->ioh, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); /* hook interrupt */ ih = au_intr_establish(aa->aa_irq[0], 0, IPL_USB, IST_LEVEL_LOW, ohci_intr, sc); if (ih == NULL) { aprint_error_dev(self,"couldn't establish interrupt\n"); } sc->sc_endian = OHCI_HOST_ENDIAN; if (x) r = ohci_init(sc); if (r != USBD_NORMAL_COMPLETION) { aprint_error_dev(self, "init failed, error=%d\n", r); au_intr_disestablish(ih); return; } /* Attach USB device */ sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); }
void beattach(device_t parent, device_t self, void *aux) { struct sbus_attach_args *sa = aux; struct qec_softc *qec = device_private(parent); struct be_softc *sc = device_private(self); struct ifnet *ifp = &sc->sc_ethercom.ec_if; struct mii_data *mii = &sc->sc_mii; struct mii_softc *child; int node = sa->sa_node; bus_dma_tag_t dmatag = sa->sa_dmatag; bus_dma_segment_t seg; bus_size_t size; int instance; int rseg, error; uint32_t v; sc->sc_dev = self; if (sa->sa_nreg < 3) { printf(": only %d register sets\n", sa->sa_nreg); return; } if (bus_space_map(sa->sa_bustag, (bus_addr_t)BUS_ADDR(sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base), (bus_size_t)sa->sa_reg[0].oa_size, 0, &sc->sc_cr) != 0) { printf(": cannot map registers\n"); return; } if (bus_space_map(sa->sa_bustag, (bus_addr_t)BUS_ADDR(sa->sa_reg[1].oa_space, sa->sa_reg[1].oa_base), (bus_size_t)sa->sa_reg[1].oa_size, 0, &sc->sc_br) != 0) { printf(": cannot map registers\n"); return; } if (bus_space_map(sa->sa_bustag, (bus_addr_t)BUS_ADDR(sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base), (bus_size_t)sa->sa_reg[2].oa_size, 0, &sc->sc_tr) != 0) { printf(": cannot map registers\n"); return; } sc->sc_bustag = sa->sa_bustag; sc->sc_qec = qec; sc->sc_qr = qec->sc_regs; sc->sc_rev = prom_getpropint(node, "board-version", -1); printf(": rev %x,", sc->sc_rev); callout_init(&sc->sc_tick_ch, 0); sc->sc_channel = prom_getpropint(node, "channel#", -1); if (sc->sc_channel == -1) sc->sc_channel = 0; sc->sc_burst = prom_getpropint(node, "burst-sizes", -1); if (sc->sc_burst == -1) sc->sc_burst = qec->sc_burst; /* Clamp at parent's burst sizes */ sc->sc_burst &= qec->sc_burst; /* Establish interrupt handler */ if (sa->sa_nintr) (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET, beintr, sc); prom_getether(node, sc->sc_enaddr); printf(" address %s\n", ether_sprintf(sc->sc_enaddr)); /* * Allocate descriptor ring and buffers. */ /* for now, allocate as many bufs as there are ring descriptors */ sc->sc_rb.rb_ntbuf = QEC_XD_RING_MAXSIZE; sc->sc_rb.rb_nrbuf = QEC_XD_RING_MAXSIZE; size = QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) + QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) + sc->sc_rb.rb_ntbuf * BE_PKT_BUF_SZ + sc->sc_rb.rb_nrbuf * BE_PKT_BUF_SZ; /* Get a DMA handle */ if ((error = bus_dmamap_create(dmatag, size, 1, size, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { aprint_error_dev(self, "DMA map create error %d\n", error); return; } /* Allocate DMA buffer */ if ((error = bus_dmamem_alloc(sa->sa_dmatag, size, 0, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(self, "DMA buffer alloc error %d\n", error); return; } /* Map DMA memory in CPU addressable space */ if ((error = bus_dmamem_map(sa->sa_dmatag, &seg, rseg, size, &sc->sc_rb.rb_membase, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { aprint_error_dev(self, "DMA buffer map error %d\n", error); bus_dmamem_free(sa->sa_dmatag, &seg, rseg); return; } /* Load the buffer */ if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap, sc->sc_rb.rb_membase, size, NULL, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(self, "DMA buffer map load error %d\n", error); bus_dmamem_unmap(dmatag, sc->sc_rb.rb_membase, size); bus_dmamem_free(dmatag, &seg, rseg); return; } sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr; /* * Initialize our media structures and MII info. */ mii->mii_ifp = ifp; mii->mii_readreg = be_mii_readreg; mii->mii_writereg = be_mii_writereg; mii->mii_statchg = be_mii_statchg; ifmedia_init(&mii->mii_media, 0, be_ifmedia_upd, be_ifmedia_sts); /* * Initialize transceiver and determine which PHY connection to use. */ be_mii_sync(sc); v = bus_space_read_4(sc->sc_bustag, sc->sc_tr, BE_TRI_MGMTPAL); instance = 0; if ((v & MGMT_PAL_EXT_MDIO) != 0) { mii_attach(self, mii, 0xffffffff, BE_PHY_EXTERNAL, MII_OFFSET_ANY, 0); child = LIST_FIRST(&mii->mii_phys); if (child == NULL) { /* No PHY attached */ ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, instance), 0, NULL); ifmedia_set(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, instance)); } else { /* * Note: we support just one PHY on the external * MII connector. */ #ifdef DIAGNOSTIC if (LIST_NEXT(child, mii_list) != NULL) { aprint_error_dev(self, "spurious MII device %s attached\n", device_xname(child->mii_dev)); } #endif if (child->mii_phy != BE_PHY_EXTERNAL || child->mii_inst > 0) { aprint_error_dev(self, "cannot accommodate MII device %s" " at phy %d, instance %d\n", device_xname(child->mii_dev), child->mii_phy, child->mii_inst); } else { sc->sc_phys[instance] = child->mii_phy; } /* * XXX - we can really do the following ONLY if the * phy indeed has the auto negotiation capability!! */ ifmedia_set(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance)); /* Mark our current media setting */ be_pal_gate(sc, BE_PHY_EXTERNAL); instance++; } } if ((v & MGMT_PAL_INT_MDIO) != 0) { /* * The be internal phy looks vaguely like MII hardware, * but not enough to be able to use the MII device * layer. Hence, we have to take care of media selection * ourselves. */ sc->sc_mii_inst = instance; sc->sc_phys[instance] = BE_PHY_INTERNAL; /* Use `ifm_data' to store BMCR bits */ ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, instance), 0, NULL); ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, instance), BMCR_S100, NULL); ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance), 0, NULL); printf("on-board transceiver at %s: 10baseT, 100baseTX, auto\n", device_xname(self)); be_mii_reset(sc, BE_PHY_INTERNAL); /* Only set default medium here if there's no external PHY */ if (instance == 0) { be_pal_gate(sc, BE_PHY_INTERNAL); ifmedia_set(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance)); } else be_mii_writereg(self, BE_PHY_INTERNAL, MII_BMCR, BMCR_ISO); } memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); ifp->if_softc = sc; ifp->if_start = bestart; ifp->if_ioctl = beioctl; ifp->if_watchdog = bewatchdog; ifp->if_init = beinit; ifp->if_stop = bestop; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; IFQ_SET_READY(&ifp->if_snd); /* claim 802.1q capability */ sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; /* Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, sc->sc_enaddr); }
/* Set up data to get the interface up and running. */ int sq_init(struct ifnet *ifp) { int i; u_int32_t reg; struct sq_softc *sc = ifp->if_softc; /* Cancel any in-progress I/O */ sq_stop(ifp, 0); sc->sc_nextrx = 0; sc->sc_nfreetx = SQ_NTXDESC; sc->sc_nexttx = sc->sc_prevtx = 0; SQ_TRACE(SQ_RESET, 0, 0, sc->sc_nfreetx); /* Set into 8003 mode, bank 0 to program ethernet address */ bus_space_write_1(sc->sc_regt, sc->sc_regh, SEEQ_TXCMD, TXCMD_BANK0); /* Now write the address */ for (i = 0; i < ETHER_ADDR_LEN; i++) bus_space_write_1(sc->sc_regt, sc->sc_regh, i, sc->sc_enaddr[i]); sc->sc_rxcmd = RXCMD_IE_CRC | RXCMD_IE_DRIB | RXCMD_IE_SHORT | RXCMD_IE_END | RXCMD_IE_GOOD; /* * Set the receive filter -- this will add some bits to the * prototype RXCMD register. Do this before setting the * transmit config register, since we might need to switch * banks. */ sq_set_filter(sc); /* Set up Seeq transmit command register */ bus_space_write_1(sc->sc_regt, sc->sc_regh, SEEQ_TXCMD, TXCMD_IE_UFLOW | TXCMD_IE_COLL | TXCMD_IE_16COLL | TXCMD_IE_GOOD); /* Now write the receive command register. */ bus_space_write_1(sc->sc_regt, sc->sc_regh, SEEQ_RXCMD, sc->sc_rxcmd); /* Set up HPC ethernet DMA config */ reg = bus_space_read_4(sc->sc_hpct, sc->sc_hpch, HPC_ENETR_DMACFG); bus_space_write_4(sc->sc_hpct, sc->sc_hpch, HPC_ENETR_DMACFG, reg | ENETR_DMACFG_FIX_RXDC | ENETR_DMACFG_FIX_INTR | ENETR_DMACFG_FIX_EOP); /* Pass the start of the receive ring to the HPC */ bus_space_write_4(sc->sc_hpct, sc->sc_hpch, HPC_ENETR_NDBP, SQ_CDRXADDR(sc, 0)); /* And turn on the HPC ethernet receive channel */ bus_space_write_4(sc->sc_hpct, sc->sc_hpch, HPC_ENETR_CTL, ENETR_CTL_ACTIVE); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; return 0; }
void acpihpet_attach(struct device *parent, struct device *self, void *aux) { struct acpihpet_softc *sc = (struct acpihpet_softc *) self; struct acpi_softc *psc = (struct acpi_softc *)parent; struct acpi_attach_args *aaa = aux; struct acpi_hpet *hpet = (struct acpi_hpet *)aaa->aaa_table; u_int64_t period, freq; /* timer period in femtoseconds (10^-15) */ u_int32_t v1, v2; int timeout; if (acpi_map_address(psc, &hpet->base_address, 0, HPET_REG_SIZE, &sc->sc_ioh, &sc->sc_iot)) { printf(": can't map i/o space\n"); return; } /* * Revisions 0x30 through 0x3a of the AMD SB700, with spread * spectrum enabled, have an SMM based HPET emulation that's * subtly broken. The hardware is initialized upon first * access of the configuration register. Initialization takes * some time during which the configuration register returns * 0xffffffff. */ timeout = 1000; do { if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION) != 0xffffffff) break; } while(--timeout > 0); if (timeout == 0) { printf(": disabled\n"); return; } /* enable hpet */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 1); /* make sure hpet is working */ v1 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER); delay(1); v2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER); if (v1 == v2) { printf(": counter not incrementing\n"); bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 0); return; } period = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_CAPABILITIES + sizeof(u_int32_t)); if (period == 0) { printf(": invalid period\n"); bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 0); return; } freq = 1000000000000000ull / period; printf(": %lld Hz\n", freq); hpet_timecounter.tc_frequency = (u_int32_t)freq; hpet_timecounter.tc_priv = sc; hpet_timecounter.tc_name = sc->sc_dev.dv_xname; tc_init(&hpet_timecounter); acpihpet_attached++; }