void omapmputmr_attach(device_t parent, device_t self, void *aux) { struct omapmputmr_softc *sc = device_private(self); struct tipb_attach_args *tipb = aux; int ints_per_sec; sc->sc_iot = tipb->tipb_iot; sc->sc_intr = tipb->tipb_intr; if (bus_space_map(tipb->tipb_iot, tipb->tipb_addr, tipb->tipb_size, 0, &sc->sc_ioh)) panic("%s: Cannot map registers", device_xname(self)); switch (device_unit(self)) { case 0: clock_sc = sc; ints_per_sec = hz; break; case 1: stat_sc = sc; ints_per_sec = profhz = stathz = STATHZ; break; case 2: ref_sc = sc; ints_per_sec = hz; /* Same rate as clock */ break; default: ints_per_sec = hz; /* Better value? */ break; } aprint_normal(": OMAP MPU Timer\n"); aprint_naive("\n"); /* Stop the timer from counting, but keep the timer module working. */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER, MPU_CLOCK_ENABLE); timer_factors tf; calc_timer_factors(ints_per_sec, &tf); switch (device_unit(self)) { case 0: counts_per_hz = tf.reload + 1; counts_per_usec = tf.counts_per_usec; break; case 2: /* * The microtime reference clock for all practical purposes * just wraps around as an unsigned int. */ tf.reload = 0xffffffff; break; default: break; } /* Set the reload value. */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_LOAD_TIMER, tf.reload); /* Set the PTV and the other required bits and pieces. */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, MPU_CNTL_TIMER, ( MPU_CLOCK_ENABLE | (tf.ptv << MPU_PTV_SHIFT) | MPU_AR | MPU_ST)); /* The clock is now running, but is not generating interrupts. */ }
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 __inline void WR4(struct ixpwdog_softc *sc, bus_size_t off, uint32_t val) { bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, off, val); }
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); }
static void giopci_attach(struct device *parent, struct device *self, void *aux) { struct giopci_softc *sc = (void *)self; pci_chipset_tag_t pc = &sc->sc_pc; struct gio_attach_args *ga = aux; uint32_t pci_off, pci_len, arb; struct pcibus_attach_args pba; u_long m_start, m_end; #ifdef PCI_NETBSD_CONFIGURE extern int pci_conf_debug; pci_conf_debug = giopci_debug; #endif sc->sc_iot = ga->ga_iot; sc->sc_slot = ga->ga_slot; sc->sc_gprid = GIO_PRODUCT_PRODUCTID(ga->ga_product); if (mach_type == MACH_SGI_IP22 && mach_subtype == MACH_SGI_IP22_FULLHOUSE) arb = GIO_ARB_RT | GIO_ARB_MST | GIO_ARB_PIPE; else arb = GIO_ARB_RT | GIO_ARB_MST; if (gio_arb_config(ga->ga_slot, arb)) { printf(": failed to configure GIO bus arbiter\n"); return; } #if (NIMC > 0) imc_disable_sysad_parity(); #endif switch (sc->sc_gprid) { case PHOBOS_G100: case PHOBOS_G130: case PHOBOS_G160: pci_off = PHOBOS_PCI_OFFSET; pci_len = PHOBOS_PCI_LENGTH; m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_START); m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_END); break; case SETENG_GFE: /* * NB: The SetEng board does not allow the ThunderLAN's DMA * engine to properly transfer segments that span page * boundaries. See sgimips/autoconf.c where we catch a * tl(4) device attachment and create an appropriate * proplib entry to enable the workaround. */ pci_off = SETENG_PCI_OFFSET; pci_len = SETENG_PCI_LENGTH; m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_START); m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_END); bus_space_write_4(ga->ga_iot, ga->ga_ioh, SETENG_MAGIC_OFFSET, SETENG_MAGIC_VALUE); break; default: panic("giopci_attach: unsupported GIO product id 0x%02x", sc->sc_gprid); } if (bus_space_subregion(ga->ga_iot, ga->ga_ioh, pci_off, pci_len, &sc->sc_ioh)) { printf("%s: unable to map PCI registers\n",sc->sc_dev.dv_xname); return; } sc->sc_pci_len = pci_len; pc->pc_bus_maxdevs = giopci_bus_maxdevs; pc->pc_conf_read = giopci_conf_read; pc->pc_conf_write = giopci_conf_write; pc->pc_conf_hook = giopci_conf_hook; pc->pc_intr_map = giopci_intr_map; pc->pc_intr_string = giopci_intr_string; pc->intr_establish = giopci_intr_establish; pc->intr_disestablish = giopci_intr_disestablish; pc->iot = ga->ga_iot; pc->ioh = ga->ga_ioh; pc->cookie = sc; printf(": %s\n", gio_product_string(sc->sc_gprid)); #ifdef PCI_NETBSD_CONFIGURE pc->pc_memext = extent_create("giopcimem", m_start, m_end, M_DEVBUF, NULL, 0, EX_NOWAIT); pci_configure_bus(pc, NULL, pc->pc_memext, NULL, 0, mips_dcache_align); #endif memset(&pba, 0, sizeof(pba)); pba.pba_memt = SGIMIPS_BUS_SPACE_MEM; pba.pba_dmat = ga->ga_dmat; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_MEM_ENABLED; /* NB: do not set PCI_FLAGS_{MRL,MRM,MWI}_OKAY -- true ?! */ config_found_ia(self, "pcibus", &pba, pcibusprint); }
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); }
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 int lbc_banks_enable(struct lbc_softc *sc) { uint32_t size; uint32_t regval; int error, i; for (i = 0; i < LBC_DEV_MAX; i++) { size = sc->sc_banks[i].size; if (size == 0) continue; /* * Compute and program BR value. */ regval = sc->sc_banks[i].addr; switch (sc->sc_banks[i].width) { case 8: regval |= (1 << 11); break; case 16: regval |= (2 << 11); break; case 32: regval |= (3 << 11); break; default: error = EINVAL; goto fail; } regval |= (sc->sc_banks[i].decc << 9); regval |= (sc->sc_banks[i].wp << 8); regval |= (sc->sc_banks[i].msel << 5); regval |= (sc->sc_banks[i].atom << 2); regval |= 1; bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_BR(i), regval); /* * Compute and program OR value. */ regval = lbc_address_mask(size); switch (sc->sc_banks[i].msel) { case LBCRES_MSEL_GPCM: /* TODO Add flag support for option registers */ regval |= 0x0ff7; break; case LBCRES_MSEL_FCM: /* TODO Add flag support for options register */ regval |= 0x0796; break; case LBCRES_MSEL_UPMA: case LBCRES_MSEL_UPMB: case LBCRES_MSEL_UPMC: printf("UPM mode not supported yet!"); error = ENOSYS; goto fail; } bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_OR(i), regval); } return (0); fail: lbc_banks_unmap(sc); return (error); }
static int lbc_attach(device_t dev) { struct lbc_softc *sc; struct lbc_devinfo *di; struct rman *rm; uintmax_t offset, size; vm_paddr_t start; device_t cdev; phandle_t node, child; pcell_t *ranges, *rangesptr; int tuple_size, tuples; int par_addr_cells; int bank, error, i, j; sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_mrid = 0; sc->sc_mres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_mrid, RF_ACTIVE); if (sc->sc_mres == NULL) return (ENXIO); sc->sc_bst = rman_get_bustag(sc->sc_mres); sc->sc_bsh = rman_get_bushandle(sc->sc_mres); for (bank = 0; bank < LBC_DEV_MAX; bank++) { bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_BR(bank), 0); bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_OR(bank), 0); } /* * Initialize configuration register: * - enable Local Bus * - set data buffer control signal function * - disable parity byte select * - set ECC parity type * - set bus monitor timing and timer prescale */ bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LBCR, 0); /* * Initialize clock ratio register: * - disable PLL bypass mode * - configure LCLK delay cycles for the assertion of LALE * - set system clock divider */ bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LCRR, 0x00030008); bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LTEDR, 0); bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LTESR, ~0); bus_space_write_4(sc->sc_bst, sc->sc_bsh, LBC85XX_LTEIR, 0x64080001); sc->sc_irid = 0; sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE); if (sc->sc_ires != NULL) { error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_MISC | INTR_MPSAFE, NULL, lbc_intr, sc, &sc->sc_icookie); if (error) { device_printf(dev, "could not activate interrupt\n"); bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, sc->sc_ires); sc->sc_ires = NULL; } } sc->sc_ltesr = ~0; rangesptr = NULL; rm = &sc->sc_rman; rm->rm_type = RMAN_ARRAY; rm->rm_descr = "Local Bus Space"; error = rman_init(rm); if (error) goto fail; error = rman_manage_region(rm, rm->rm_start, rm->rm_end); if (error) { rman_fini(rm); goto fail; } /* * Process 'ranges' property. */ node = ofw_bus_get_node(dev); if ((fdt_addrsize_cells(node, &sc->sc_addr_cells, &sc->sc_size_cells)) != 0) { error = ENXIO; goto fail; } par_addr_cells = fdt_parent_addr_cells(node); if (par_addr_cells > 2) { device_printf(dev, "unsupported parent #addr-cells\n"); error = ERANGE; goto fail; } tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + par_addr_cells + sc->sc_size_cells); tuples = OF_getencprop_alloc_multi(node, "ranges", tuple_size, (void **)&ranges); if (tuples < 0) { device_printf(dev, "could not retrieve 'ranges' property\n"); error = ENXIO; goto fail; } rangesptr = ranges; debugf("par addr_cells = %d, addr_cells = %d, size_cells = %d, " "tuple_size = %d, tuples = %d\n", par_addr_cells, sc->sc_addr_cells, sc->sc_size_cells, tuple_size, tuples); start = 0; size = 0; for (i = 0; i < tuples; i++) { /* The first cell is the bank (chip select) number. */ bank = fdt_data_get(ranges, 1); if (bank < 0 || bank > LBC_DEV_MAX) { device_printf(dev, "bank out of range: %d\n", bank); error = ERANGE; goto fail; } ranges += 1; /* * Remaining cells of the child address define offset into * this CS. */ offset = 0; for (j = 0; j < sc->sc_addr_cells - 1; j++) { offset <<= sizeof(pcell_t) * 8; offset |= *ranges; ranges++; } /* Parent bus start address of this bank. */ start = 0; for (j = 0; j < par_addr_cells; j++) { start <<= sizeof(pcell_t) * 8; start |= *ranges; ranges++; } size = fdt_data_get((void *)ranges, sc->sc_size_cells); ranges += sc->sc_size_cells; debugf("bank = %d, start = %jx, size = %jx\n", bank, (uintmax_t)start, size); sc->sc_banks[bank].addr = start + offset; sc->sc_banks[bank].size = size; /* * Attributes for the bank. * * XXX Note there are no DT bindings defined for them at the * moment, so we need to provide some defaults. */ sc->sc_banks[bank].width = 16; sc->sc_banks[bank].msel = LBCRES_MSEL_GPCM; sc->sc_banks[bank].decc = LBCRES_DECC_DISABLED; sc->sc_banks[bank].atom = LBCRES_ATOM_DISABLED; sc->sc_banks[bank].wp = 0; } /* * Initialize mem-mappings for the LBC banks (i.e. chip selects). */ error = lbc_banks_map(sc); if (error) goto fail; /* * Walk the localbus and add direct subordinates as our children. */ for (child = OF_child(node); child != 0; child = OF_peer(child)) { di = malloc(sizeof(*di), M_LBC, M_WAITOK | M_ZERO); if (ofw_bus_gen_setup_devinfo(&di->di_ofw, child) != 0) { free(di, M_LBC); device_printf(dev, "could not set up devinfo\n"); continue; } resource_list_init(&di->di_res); if (fdt_lbc_reg_decode(child, sc, di)) { device_printf(dev, "could not process 'reg' " "property\n"); ofw_bus_gen_destroy_devinfo(&di->di_ofw); free(di, M_LBC); continue; } fdt_lbc_fixup(child, sc, di); /* Add newbus device for this FDT node */ cdev = device_add_child(dev, NULL, -1); if (cdev == NULL) { device_printf(dev, "could not add child: %s\n", di->di_ofw.obd_name); resource_list_free(&di->di_res); ofw_bus_gen_destroy_devinfo(&di->di_ofw); free(di, M_LBC); continue; } debugf("added child name='%s', node=%x\n", di->di_ofw.obd_name, child); device_set_ivars(cdev, di); } /* * Enable the LBC. */ lbc_banks_enable(sc); OF_prop_free(rangesptr); return (bus_generic_attach(dev)); fail: OF_prop_free(rangesptr); bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mrid, sc->sc_mres); return (error); }
static void igma_reg_write(const struct igma_chip *cd, int r, u_int32_t v) { bus_space_write_4(cd->mmiot, cd->mmioh, r, v); }
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); }
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++; }
static int ptx_detach (device_t device) { struct ptx_softc *scp = (struct ptx_softc *) device_get_softc(device); uint32_t val; int lp; if (scp->cardtype == PT3) { pt3_exit(scp); if (scp->res_memory) { bus_release_resource(device, SYS_RES_MEMORY, scp->rid_memory, scp->res_memory); scp->res_memory = 0; } if (scp->pt3_res_memory) { bus_release_resource(device, SYS_RES_MEMORY, scp->pt3_rid_memory, scp->pt3_res_memory); scp->pt3_res_memory = 0; } if (scp->dmat) { bus_dma_tag_destroy(scp->dmat); } if (scp->pt3_dmat) { bus_dma_tag_destroy(scp->pt3_dmat); } return 0; } if (scp->ptxdaemon) { ptx_proc_stop(scp); } // DMA終了 if (scp->bh) { bus_space_write_4(scp->bt, scp->bh, 0x0, 0x08080000); for (lp = 0; lp < 10; lp++){ val = bus_space_read_4(scp->bt, scp->bh, 0x0); if (!(val & (1 << 6))) { break; } ptx_pause("ptxdet", MSTOTICK(1)); } } ptx_dma_free(scp); for (lp = 0; lp < MAX_STREAM; ++lp) { struct ptx_stream *s = &scp->stream[lp]; if (mtx_initialized(&s->lock)) { mtx_destroy(&s->lock); cv_destroy(&s->not_full); cv_destroy(&s->not_empty); } if (s->buf != NULL) { free(s->buf, M_DEVBUF); s->buf = NULL; } if (scp->dev[lp]) { destroy_dev(scp->dev[lp]); } } if (scp->bh) { bus_space_write_4(scp->bt, scp->bh, 0x0, 0xb0b0000); bus_space_write_4(scp->bt, scp->bh, CFG_REGS_ADDR, 0x0); } settuner_reset(scp, LNB_OFF, TUNER_POWER_OFF); if (scp->dmat) { bus_dma_tag_destroy(scp->dmat); } if (mtx_initialized(&scp->lock)) { mtx_destroy(&scp->lock); } if (scp->res_memory) { bus_release_resource(device, SYS_RES_MEMORY, scp->rid_memory, scp->res_memory); scp->res_memory = 0; } return 0; }
static void npe_reg_write(struct ixpnpe_softc *sc, bus_size_t off, uint32_t val) { DPRINTFn(9, sc->sc_dev, "%s(0x%lx, 0x%x)\n", __func__, off, val); bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val); }
static __inline void malo_hal_write4(struct malo_hal *mh, bus_size_t off, uint32_t val) { bus_space_write_4(mh->mh_iot, mh->mh_ioh, off, val); }
__unused static inline void bcmccb_write_4(struct bcmccb_softc *sc, bus_size_t o, uint32_t v) { return bus_space_write_4(sc->sc_bst, sc->sc_bsh, o, v); }
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 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); }
void amptimer_attach(struct device *parent, struct device *self, void *args) { struct amptimer_softc *sc = (struct amptimer_softc *)self; struct cortex_attach_args *ia = args; bus_space_handle_t ioh, pioh; sc->sc_iot = ia->ca_iot; if (bus_space_map(sc->sc_iot, ia->ca_periphbase + GTIMER_ADDR, GTIMER_SIZE, 0, &ioh)) panic("amptimer_attach: bus_space_map global timer failed!"); if (bus_space_map(sc->sc_iot, ia->ca_periphbase + PTIMER_ADDR, PTIMER_SIZE, 0, &pioh)) panic("amptimer_attach: bus_space_map priv timer failed!"); sc->sc_ticks_per_second = amptimer_frequency; printf(": tick rate %d KHz\n", sc->sc_ticks_per_second /1000); sc->sc_ioh = ioh; sc->sc_pioh = pioh; /* disable global timer */ bus_space_write_4(sc->sc_iot, ioh, GTIMER_CTRL, 0); /* XXX ??? reset counters to 0 - gives us uptime in the counter */ bus_space_write_4(sc->sc_iot, ioh, GTIMER_CNT_LOW, 0); bus_space_write_4(sc->sc_iot, ioh, GTIMER_CNT_HIGH, 0); /* enable global timer */ bus_space_write_4(sc->sc_iot, ioh, GTIMER_CTRL, GTIMER_CTRL_TIMER); #if defined(USE_GTIMER_CMP) /* clear event */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_STATUS, 1); #else bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL, 0); bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_STATUS, PTIMER_STATUS_EVENT); #endif #ifdef AMPTIMER_DEBUG evcount_attach(&sc->sc_clk_count, "clock", NULL); evcount_attach(&sc->sc_stat_count, "stat", NULL); #endif /* * private timer and interrupts not enabled until * timer configures */ arm_clock_register(amptimer_cpu_initclocks, amptimer_delay, amptimer_setstatclockrate, amptimer_startclock); amptimer_timecounter.tc_frequency = sc->sc_ticks_per_second; amptimer_timecounter.tc_priv = sc; tc_init(&timer_timecounter); }
static int at91_attach(device_t dev) { struct at91_softc *sc = device_get_softc(dev); int i; at91_softc = sc; sc->sc_st = &at91_bs_tag; sc->sc_sh = AT91RM92_BASE; sc->dev = dev; if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE, AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0) panic("Enable to map IRQ registers"); sc->sc_irq_rman.rm_type = RMAN_ARRAY; sc->sc_irq_rman.rm_descr = "AT91 IRQs"; sc->sc_mem_rman.rm_type = RMAN_ARRAY; sc->sc_mem_rman.rm_descr = "AT91 Memory"; #if 0 sc->sc_usbmem_rman.rm_type = RMAN_ARRAY; sc->sc_usbmem_rman.rm_descr = "AT91RM9200 USB Memory-mapped regs"; #endif if (rman_init(&sc->sc_irq_rman) != 0 || rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0) panic("at91_attach: failed to set up IRQ rman"); if (rman_init(&sc->sc_mem_rman) != 0 || rman_manage_region(&sc->sc_mem_rman, 0xdff00000ul, 0xdffffffful) != 0) panic("at91_attach: failed to set up memory rman"); if (rman_manage_region(&sc->sc_mem_rman, AT91RM92_OHCI_BASE, AT91RM92_OHCI_BASE + AT91RM92_OHCI_SIZE - 1) != 0) panic("at91_attach: failed to set up ohci memory"); for (i = 0; i < 32; i++) { bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SVR + i * 4, i); /* Priority. */ bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SMR + i * 4, irq_prio[i]); if (i < 8) bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_EOICR, 1); } bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SPU, 32); /* No debug. */ bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_DCR, 0); /* Disable and clear all interrupts. */ bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR, 0xffffffff); bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_ICCR, 0xffffffff); /* XXX */ /* Disable all interrupts for RTC (0xe24 == RTC_IDR) */ bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff); /* DIsable all interrupts for DBGU */ bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0x20c, 0xffffffff); /* Disable all interrupts for the SDRAM controller */ bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff); at91_cpu_add_builtin_children(dev, sc); bus_generic_probe(dev); bus_generic_attach(dev); enable_interrupts(I32_bit | F32_bit); return (0); }
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; }
/**** Low-level hardware register groveling functions ****/ static void rex3_write(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val) { bus_space_write_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET + rexreg, val); }
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 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 int ohci_ec_attach(device_t dev) { struct ec_ohci_softc *sc = device_get_softc(dev); bus_space_handle_t bsh; int err; int rid; /* initialise some bus fields */ sc->sc_ohci.sc_bus.parent = dev; sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices; sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES; /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus, USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) { return (ENOMEM); } sc->sc_ohci.sc_dev = dev; rid = MEM_RID; sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!(sc->sc_ohci.sc_io_res)) { err = ENOMEM; goto error; } sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res); bsh = rman_get_bushandle(sc->sc_ohci.sc_io_res); /* Undocumented magic initialization */ bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x04, 0x146); bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x44, 0x0200); DELAY(1000); sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res); if (bus_space_subregion(sc->sc_ohci.sc_io_tag, bsh, 0x4000000, sc->sc_ohci.sc_io_size, &sc->sc_ohci.sc_io_hdl) != 0) panic("%s: unable to subregion USB host registers", device_get_name(dev)); rid = 0; sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!(sc->sc_ohci.sc_irq_res)) { goto error; } sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1); if (!(sc->sc_ohci.sc_bus.bdev)) { goto error; } device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); strlcpy(sc->sc_ohci.sc_vendor, "Cavium", sizeof(sc->sc_ohci.sc_vendor)); #if (__FreeBSD_version >= 700031) err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl); #else err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl); #endif if (err) { sc->sc_ohci.sc_intr_hdl = NULL; goto error; } bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, OHCI_CONTROL, 0); err = ohci_init(&sc->sc_ohci); if (!err) { err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); } if (err) { goto error; } return (0); error: ohci_ec_detach(dev); return (ENXIO); }
void imxenet_chip_init(struct imxenet_softc *sc) { struct device *dev = (struct device *) sc; int phy = 0; uint32_t reg; uint32_t rate = clk_get_rate(clk_get("enet_ref")); bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MSCR, (((rate + (ENET_MII_CLK << 2) - 1) / (ENET_MII_CLK << 2)) << 1) | 0x100); switch (board_id) { case BOARD_ID_IMX6_HUMMINGBOARD: phy = ENET_HUMMINGBOARD_PHY; break; case BOARD_ID_IMX6_SABRELITE: phy = ENET_SABRELITE_PHY; break; case BOARD_ID_IMX6_UDOO: phy = ENET_UDOO_PHY; break; case BOARD_ID_IMX6_UTILITE: phy = ENET_UTILITE_PHY; break; case BOARD_ID_IMX6_WANDBOARD: phy = ENET_WANDBOARD_PHY; break; } switch (board_id) { case BOARD_ID_IMX6_UDOO: /* Micrel KSZ9031 */ case BOARD_ID_IMX6_SABRELITE: /* Micrel KSZ9021 */ /* prefer master mode */ imxenet_miibus_writereg(dev, phy, 0x9, 0x1f00); /* min rx data delay */ imxenet_miibus_writereg(dev, phy, 0x0b, 0x8105); imxenet_miibus_writereg(dev, phy, 0x0c, 0x0000); /* min tx data delay */ imxenet_miibus_writereg(dev, phy, 0x0b, 0x8106); imxenet_miibus_writereg(dev, phy, 0x0c, 0x0000); /* max rx/tx clock delay, min rx/tx control delay */ imxenet_miibus_writereg(dev, phy, 0x0b, 0x8104); imxenet_miibus_writereg(dev, phy, 0x0c, 0xf0f0); imxenet_miibus_writereg(dev, phy, 0x0b, 0x104); /* enable all interrupts */ imxenet_miibus_writereg(dev, phy, 0x1b, 0xff00); break; case BOARD_ID_IMX6_HUMMINGBOARD: /* AR8035 */ case BOARD_ID_IMX6_UTILITE: case BOARD_ID_IMX6_WANDBOARD: /* AR8031 */ /* disable SmartEEE */ imxenet_miibus_writereg(dev, phy, 0x0d, 0x0003); imxenet_miibus_writereg(dev, phy, 0x0e, 0x805d); imxenet_miibus_writereg(dev, phy, 0x0d, 0x4003); reg = imxenet_miibus_readreg(dev, phy, 0x0e); imxenet_miibus_writereg(dev, phy, 0x0e, reg & ~0x0100); /* enable 125MHz clk output */ imxenet_miibus_writereg(dev, phy, 0x0d, 0x0007); imxenet_miibus_writereg(dev, phy, 0x0e, 0x8016); imxenet_miibus_writereg(dev, phy, 0x0d, 0x4007); reg = imxenet_miibus_readreg(dev, phy, 0x0e) & 0xffe3; imxenet_miibus_writereg(dev, phy, 0x0e, reg | 0x18); /* tx clock delay */ imxenet_miibus_writereg(dev, phy, 0x1d, 0x0005); reg = imxenet_miibus_readreg(dev, phy, 0x1e); imxenet_miibus_writereg(dev, phy, 0x1e, reg | 0x0100); /* phy power */ reg = imxenet_miibus_readreg(dev, phy, 0x00); if (reg & 0x0800) imxenet_miibus_writereg(dev, phy, 0x00, reg & ~0x0800); break; } }
static void tegra_ahcisata_init(struct tegra_ahcisata_softc *sc) { bus_space_tag_t bst = sc->sc_bst; bus_space_handle_t bsh = sc->sc_bsh; const u_int gen1_tx_amp = 0x18; const u_int gen1_tx_peak = 0x04; const u_int gen2_tx_amp = 0x18; const u_int gen2_tx_peak = 0x0a; /* Enable IFPS device block */ tegra_reg_set_clear(bst, bsh, TEGRA_SATA_CONFIGURATION_REG, TEGRA_SATA_CONFIGURATION_EN_FPCI, 0); /* PHY config */ bus_space_write_4(bst, bsh, TEGRA_T_SATA0_INDEX_REG, TEGRA_T_SATA0_INDEX_CH1); tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_REG, __SHIFTIN(gen1_tx_amp, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP) | __SHIFTIN(gen1_tx_peak, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK), TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP | TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK); tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_REG, __SHIFTIN(gen2_tx_amp, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP) | __SHIFTIN(gen2_tx_peak, TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK), TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP | TEGRA_T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK); bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL11_REG, __SHIFTIN(0x2800, TEGRA_T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ)); bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CHX_PHY_CTRL2_REG, __SHIFTIN(0x23, TEGRA_T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1)); bus_space_write_4(bst, bsh, TEGRA_T_SATA0_INDEX_REG, 0); /* Backdoor update the programming interface field and class code */ tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CFG_SATA_REG, TEGRA_T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN, 0); bus_space_write_4(bst, bsh, TEGRA_T_SATA0_BKDOOR_CC_REG, __SHIFTIN(0x1016, TEGRA_T_SATA0_BKDOOR_CC_CLASS_CODE) | __SHIFTIN(0x1, TEGRA_T_SATA0_BKDOOR_CC_PROG_IF)); tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CFG_SATA_REG, 0, TEGRA_T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN); /* Enable access and bus mastering */ tegra_reg_set_clear(bst, bsh, TEGRA_T_SATA0_CFG1_REG, TEGRA_T_SATA0_CFG1_SERR | TEGRA_T_SATA0_CFG1_BUS_MASTER | TEGRA_T_SATA0_CFG1_MEM_SPACE | TEGRA_T_SATA0_CFG1_IO_SPACE, 0); /* MMIO setup */ bus_space_write_4(bst, bsh, TEGRA_SATA_FPCI_BAR5_REG, __SHIFTIN(0x10000, TEGRA_SATA_FPCI_BAR_START)); bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CFG9_REG, __SHIFTIN(0x8000, TEGRA_T_SATA0_CFG9_BASE_ADDRESS)); /* Enable interrupts */ tegra_reg_set_clear(bst, bsh, TEGRA_SATA_INTR_MASK_REG, TEGRA_SATA_INTR_MASK_IP_INT, 0); }
void imxenet_init(struct imxenet_softc *sc) { struct ifnet *ifp = &sc->sc_ac.ac_if; int speed = 0; uint32_t rate = clk_get_rate(clk_get("enet_ref")); /* reset the controller */ HWRITE4(sc, ENET_ECR, ENET_ECR_RESET); while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET); /* set hw address */ HWRITE4(sc, ENET_PALR, (sc->sc_ac.ac_enaddr[0] << 24) | (sc->sc_ac.ac_enaddr[1] << 16) | (sc->sc_ac.ac_enaddr[2] << 8) | sc->sc_ac.ac_enaddr[3]); HWRITE4(sc, ENET_PAUR, (sc->sc_ac.ac_enaddr[4] << 24) | (sc->sc_ac.ac_enaddr[5] << 16)); /* clear outstanding interrupts */ HWRITE4(sc, ENET_EIR, 0xffffffff); /* set address filter */ HWRITE4(sc, ENET_GAUR, 0); HWRITE4(sc, ENET_GALR, 0); /* set max receive buffer size, 3-0 bits always zero for alignment */ HWRITE4(sc, ENET_MRBR, ENET_MAX_PKT_SIZE); /* init descriptor */ imxenet_init_txd(sc); imxenet_init_rxd(sc); /* set descriptor */ HWRITE4(sc, ENET_TDSR, sc->txdma.dma_paddr); HWRITE4(sc, ENET_RDSR, sc->rxdma.dma_paddr); /* set it to full-duplex */ HWRITE4(sc, ENET_TCR, ENET_TCR_FDEN); /* * Set max frame length to 1518 or 1522 with VLANs, * pause frames and promisc mode. * XXX: RGMII mode - phy dependant */ HWRITE4(sc, ENET_RCR, ENET_RCR_MAX_FL(1522) | ENET_RCR_RGMII_MODE | ENET_RCR_MII_MODE | ENET_RCR_FCE); bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MSCR, (((rate + (ENET_MII_CLK << 2) - 1) / (ENET_MII_CLK << 2)) << 1) | 0x100); /* RX FIFO treshold and pause */ HWRITE4(sc, ENET_RSEM, 0x84); HWRITE4(sc, ENET_RSFL, 16); HWRITE4(sc, ENET_RAEM, 8); HWRITE4(sc, ENET_RAFL, 8); HWRITE4(sc, ENET_OPD, 0xFFF0); /* do store and forward, only i.MX6, needs to be set correctly else */ HWRITE4(sc, ENET_TFWR, ENET_TFWR_STRFWD); /* enable gigabit-ethernet and set it to support little-endian */ switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { case IFM_1000_T: /* Gigabit */ speed |= ENET_ECR_SPEED; break; default: speed &= ~ENET_ECR_SPEED; break; } HWRITE4(sc, ENET_ECR, ENET_ECR_ETHEREN | speed | ENET_ECR_DBSWP); #ifdef ENET_ENHANCED_BD HSET4(sc, ENET_ECR, ENET_ECR_EN1588); #endif /* rx descriptors are ready */ HWRITE4(sc, ENET_RDAR, ENET_RDAR_RDAR); /* Indicate we are up and running. */ ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; /* enable interrupts for tx/rx */ HWRITE4(sc, ENET_EIMR, ENET_EIR_TXF | ENET_EIR_RXF); HWRITE4(sc, ENET_EIMR, 0xffffffff); imxenet_start(ifp); }
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; } }
static void wi_pci_attach(struct device *parent, struct device *self, void *aux) { struct wi_pci_softc *psc = (struct wi_pci_softc *)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; 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) { printf(": 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) { printf(": 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) { printf(": 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) { printf(": can't map TMD\n"); return; } if (pci_mapreg_map(pa, WI_TMD_IO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) != 0) { printf(": 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) { printf(": can't map mem space\n"); return; } memt = iot; memh = ioh; sc->sc_pci = 1; break; } { char devinfo[256]; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); } sc->sc_enabled = 1; sc->sc_enable = wi_pci_enable; sc->sc_disable = wi_pci_disable; 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); 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) printf(" at %s", intrstr); printf("\n"); return; } printf("%s: interrupting at %s\n", device_xname(self), 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)) aprint_error_dev(self, "couldn't establish power handler\n"); else pmf_class_network_register(self, &sc->sc_if); }