/* * i80321_attach: * * Board-independent attach routine for the i80321. */ void i80321_attach(struct i80321_softc *sc) { struct pcibus_attach_args pba; pcireg_t preg; i80321_softc = sc; /* * Slice off some useful subregion handles. */ if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_ATU_BASE, VERDE_ATU_SIZE, &sc->sc_atu_sh)) panic("%s: unable to subregion ATU registers\n", sc->sc_dev.dv_xname); /* We expect the Memory Controller to be already sliced off. */ /* * Program the Inbound windows. */ if (sc->sc_is_host) { bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START, sc->sc_iwin[0].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x04, sc->sc_iwin[0].iwin_base_hi); } bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, (0xffffffff - (sc->sc_iwin[0].iwin_size - 1)) & 0xffffffc0); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR0, sc->sc_iwin[0].iwin_xlate); if (sc->sc_is_host) { bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x08, sc->sc_iwin[1].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x0c, sc->sc_iwin[1].iwin_base_hi); } bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1, (0xffffffff - (sc->sc_iwin[1].iwin_size - 1)) & 0xffffffc0); /* no xlate for window 1 */ if (sc->sc_is_host) { bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x10, sc->sc_iwin[2].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x14, sc->sc_iwin[2].iwin_base_hi); } bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, (0xffffffff - (sc->sc_iwin[2].iwin_size - 1)) & 0xffffffc0); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR2, sc->sc_iwin[2].iwin_xlate); if (sc->sc_is_host) { bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR3, sc->sc_iwin[3].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR3, sc->sc_iwin[3].iwin_base_hi); } bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR3, (0xffffffff - (sc->sc_iwin[3].iwin_size - 1)) & 0xffffffc0); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR3, sc->sc_iwin[3].iwin_xlate); /* * Mask (disable) the ATU interrupt sources. * XXX May want to revisit this if we encounter * XXX an application that wants it. */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUIMR, ATUIMR_IMW1BU|ATUIMR_ISCEM|ATUIMR_RSCEM|ATUIMR_PST| ATUIMR_DPE|ATUIMR_P_SERR_ASRT|ATUIMR_PMA|ATUIMR_PTAM| ATUIMR_PTAT|ATUIMR_PMPE); /* * Program the outbound windows. */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOWTVR, sc->sc_ioout_xlate); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OMWTVR0, sc->sc_owin[0].owin_xlate_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR0, sc->sc_owin[0].owin_xlate_hi); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OMWTVR1, sc->sc_owin[1].owin_xlate_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR1, sc->sc_owin[1].owin_xlate_hi); /* * Set up the ATU configuration register. All we do * right now is enable Outbound Windows. */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUCR, ATUCR_OUT_EN); /* * Enable bus mastering, memory access, SERR, and parity * checking on the ATU. */ if (sc->sc_is_host) { preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCI_COMMAND_STATUS_REG); preg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE; bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_COMMAND_STATUS_REG, preg); } /* * Initialize the bus space and DMA tags and the PCI chipset tag. */ i80321_io_bs_init(&sc->sc_pci_iot, sc); i80321_mem_bs_init(&sc->sc_pci_memt, sc); i80321_pci_dma_init(&sc->sc_pci_dmat, sc); i80321_pci_init(&sc->sc_pci_chipset, sc); /* * Attach the PCI bus. */ preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); preg = PCIXSR_BUSNO(preg); if (preg == 0xff) preg = 0; pba.pba_busname = "pci"; pba.pba_iot = &sc->sc_pci_iot; pba.pba_memt = &sc->sc_pci_memt; pba.pba_dmat = &sc->sc_pci_dmat; pba.pba_pc = &sc->sc_pci_chipset; pba.pba_bus = preg; pba.pba_bridgetag = NULL; pba.pba_intrswiz = 0; /* XXX what if busno != 0? */ pba.pba_intrtag = 0; pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; (void) config_found(&sc->sc_dev, &pba, i80321_pcibus_print); }
/* * i80321_attach: * * Board-independent attach routine for the i80321. */ void i80321_attach(struct i80321_softc *sc) { struct pcibus_attach_args pba; const struct iopxs_device *id; struct iopxs_attach_args ia; pcireg_t preg; i80321_softc = sc; /* * Program the Inbound windows. */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, (0xffffffff - (sc->sc_iwin[0].iwin_size - 1)) & 0xffffffc0); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR0, sc->sc_iwin[0].iwin_xlate); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START, sc->sc_iwin[0].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x04, sc->sc_iwin[0].iwin_base_hi); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1, (0xffffffff - (sc->sc_iwin[1].iwin_size - 1)) & 0xffffffc0); /* no xlate for window 1 */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x08, sc->sc_iwin[1].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x0c, sc->sc_iwin[1].iwin_base_hi); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, (0xffffffff - (sc->sc_iwin[2].iwin_size - 1)) & 0xffffffc0); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR2, sc->sc_iwin[2].iwin_xlate); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x10, sc->sc_iwin[2].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_MAPREG_START + 0x14, sc->sc_iwin[2].iwin_base_hi); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR3, (0xffffffff - (sc->sc_iwin[3].iwin_size - 1)) & 0xffffffc0); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR3, sc->sc_iwin[3].iwin_xlate); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR3, sc->sc_iwin[3].iwin_base_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR3, sc->sc_iwin[3].iwin_base_hi); /* * Mask (disable) the ATU interrupt sources. * XXX May want to revisit this if we encounter * XXX an application that wants it. */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUIMR, ATUIMR_IMW1BU|ATUIMR_ISCEM|ATUIMR_RSCEM|ATUIMR_PST| ATUIMR_DPE|ATUIMR_P_SERR_ASRT|ATUIMR_PMA|ATUIMR_PTAM| ATUIMR_PTAT|ATUIMR_PMPE); /* * Program the outbound windows. */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOWTVR, sc->sc_ioout_xlate); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OMWTVR0, sc->sc_owin[0].owin_xlate_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR0, sc->sc_owin[0].owin_xlate_hi); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OMWTVR1, sc->sc_owin[1].owin_xlate_lo); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR1, sc->sc_owin[1].owin_xlate_hi); /* * Set up the ATU configuration register. All we do * right now is enable Outbound Windows. */ bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUCR, ATUCR_OUT_EN); /* * Enable bus mastering, memory access, SERR, and parity * checking on the ATU. */ preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCI_COMMAND_STATUS_REG); preg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE; bus_space_write_4(sc->sc_st, sc->sc_atu_sh, PCI_COMMAND_STATUS_REG, preg); /* Initialize the bus space tags. */ i80321_io_bs_init(&sc->sc_pci_iot, sc); i80321_mem_bs_init(&sc->sc_pci_memt, sc); /* Initialize the DMA tags. */ i80321_pci_dma_init(sc); i80321_local_dma_init(sc); /* * Attach all the IOP built-ins. */ for (id = iopxs_devices; id->id_name != NULL; id++) { ia.ia_name = id->id_name; ia.ia_st = sc->sc_st; ia.ia_sh = sc->sc_sh; ia.ia_dmat = &sc->sc_local_dmat; ia.ia_offset = id->id_offset; ia.ia_size = id->id_size; config_found(&sc->sc_dev, &ia, i80321_iopxs_print); } /* * Attach the PCI bus. */ preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); preg = PCIXSR_BUSNO(preg); if (preg == 0xff) preg = 0; pba.pba_busname = "pci"; pba.pba_iot = &sc->sc_pci_iot; pba.pba_memt = &sc->sc_pci_memt; pba.pba_dmat = &sc->sc_pci_dmat; pba.pba_pc = &sc->sc_pci_chipset; pba.pba_domain = pci_ndomains++; pba.pba_bus = preg; pba.pba_bridgetag = NULL; pba.pba_intrswiz = 0; /* XXX what if busno != 0? */ pba.pba_intrtag = 0; config_found((struct device *)sc, &pba, i80321_iopxs_print); }