diff options
-rw-r--r-- | sys/arch/octeon/dev/octeon_pcibus.c | 117 |
1 files changed, 112 insertions, 5 deletions
diff --git a/sys/arch/octeon/dev/octeon_pcibus.c b/sys/arch/octeon/dev/octeon_pcibus.c index 61f9c9341ea..c872b26a7b3 100644 --- a/sys/arch/octeon/dev/octeon_pcibus.c +++ b/sys/arch/octeon/dev/octeon_pcibus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: octeon_pcibus.c,v 1.17 2015/10/03 13:53:54 semarie Exp $ */ +/* $OpenBSD: octeon_pcibus.c,v 1.18 2016/10/21 07:55:48 pirofti Exp $ */ /* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */ /* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */ @@ -107,6 +107,9 @@ void *octeon_pcibus_pci_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *), void *, char *); void octeon_pcibus_pci_intr_disestablish(void *, void *); +pcireg_t octeon_pcibus_pcie_conf_read(void *, pcitag_t, int); +void octeon_pcibus_pcie_conf_write(void *, pcitag_t, int, pcireg_t); + struct machine_bus_dma_tag octeon_pcibus_bus_dma_tag = { ._cookie = NULL, @@ -133,11 +136,60 @@ int octeon_pcibus_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, int octeon_pcibus_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, bus_space_handle_t *); +#define _OCTEON_PCIBUS_PCIEIO_BASE 0x10438000 +#define _OCTEON_PCIBUS_PCIEMEM_BASE 0x00638000 + #define _OCTEON_PCIBUS_PCIIO_BASE 0x00001000 #define _OCTEON_PCIBUS_PCIIO_SIZE 0x08000000 #define _OCTEON_PCIBUS_PCIMEM_BASE 0x80000000 #define _OCTEON_PCIBUS_PCIMEM_SIZE 0x40000000 +struct mips_bus_space octeon_pcibus_pcie_io_space_tag = { + .bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIEIO_BASE, CCA_NC), + .bus_private = NULL, + ._space_read_1 = generic_space_read_1, + ._space_write_1 = generic_space_write_1, + ._space_read_2 = generic_space_read_2, + ._space_write_2 = generic_space_write_2, + ._space_read_4 = generic_space_read_4, + ._space_write_4 = generic_space_write_4, + ._space_read_8 = generic_space_read_8, + ._space_write_8 = generic_space_write_8, + ._space_read_raw_2 = generic_space_read_raw_2, + ._space_write_raw_2 = generic_space_write_raw_2, + ._space_read_raw_4 = generic_space_read_raw_4, + ._space_write_raw_4 = generic_space_write_raw_4, + ._space_read_raw_8 = generic_space_read_raw_8, + ._space_write_raw_8 = generic_space_write_raw_8, + ._space_map = octeon_pcibus_io_map, + ._space_unmap = generic_space_unmap, + ._space_subregion = generic_space_region, + ._space_vaddr = generic_space_vaddr +}; + +struct mips_bus_space octeon_pcibus_pcie_mem_space_tag = { + .bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIEMEM_BASE, CCA_NC), + .bus_private = NULL, + ._space_read_1 = generic_space_read_1, + ._space_write_1 = generic_space_write_1, + ._space_read_2 = generic_space_read_2, + ._space_write_2 = generic_space_write_2, + ._space_read_4 = generic_space_read_4, + ._space_write_4 = generic_space_write_4, + ._space_read_8 = generic_space_read_8, + ._space_write_8 = generic_space_write_8, + ._space_read_raw_2 = generic_space_read_raw_2, + ._space_write_raw_2 = generic_space_write_raw_2, + ._space_read_raw_4 = generic_space_read_raw_4, + ._space_write_raw_4 = generic_space_write_raw_4, + ._space_read_raw_8 = generic_space_read_raw_8, + ._space_write_raw_8 = generic_space_write_raw_8, + ._space_map = octeon_pcibus_mem_map, + ._space_unmap = generic_space_unmap, + ._space_subregion = generic_space_region, + ._space_vaddr = generic_space_vaddr +}; + struct mips_bus_space octeon_pcibus_pci_io_space_tag = { .bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIIO_BASE, CCA_NC), .bus_private = NULL, @@ -221,8 +273,13 @@ octeon_pcibus_attach(struct device *parent, struct device *self, void *aux) sc->sc_pc.pc_conf_v = sc; sc->sc_pc.pc_conf_size = octeon_pcibus_pci_conf_size; - sc->sc_pc.pc_conf_read = octeon_pcibus_pci_conf_read; - sc->sc_pc.pc_conf_write = octeon_pcibus_pci_conf_write; + if (1) { + sc->sc_pc.pc_conf_read = octeon_pcibus_pcie_conf_read; + sc->sc_pc.pc_conf_write = octeon_pcibus_pcie_conf_write; + } else { + sc->sc_pc.pc_conf_read = octeon_pcibus_pci_conf_read; + sc->sc_pc.pc_conf_write = octeon_pcibus_pci_conf_write; + } sc->sc_pc.pc_intr_v = sc; sc->sc_pc.pc_intr_map = octeon_pcibus_pci_intr_map; @@ -232,8 +289,14 @@ octeon_pcibus_attach(struct device *parent, struct device *self, void *aux) bzero(&pba, sizeof pba); pba.pba_busname = "pci"; - pba.pba_iot = &octeon_pcibus_pci_io_space_tag; - pba.pba_memt = &octeon_pcibus_pci_mem_space_tag; + if (1) { + pba.pba_iot = &octeon_pcibus_pcie_io_space_tag; + pba.pba_memt = &octeon_pcibus_pcie_mem_space_tag; + pba.pba_bus = 1; + } else { + pba.pba_iot = &octeon_pcibus_pci_io_space_tag; + pba.pba_memt = &octeon_pcibus_pci_mem_space_tag; + } pba.pba_dmat = &octeon_pcibus_bus_dma_tag; pba.pba_pc = &sc->sc_pc; pba.pba_domain = pci_ndomains++; @@ -361,6 +424,50 @@ octeon_pcibus_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data) REG_WRITE32(cfgoff, data); } +pcireg_t +octeon_pcibus_pcie_conf_read(void *v, pcitag_t tag, int offset) +{ + pcireg_t data; + uint64_t cfgoff; + + if (tag == 0){ + return -1; + } else { + cfgoff = tag + offset; + if (offset & 0x4) { + cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8); + } else { + cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8); + } + } + + data = REG_READ32(cfgoff); + return data; +} + +void +octeon_pcibus_pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data) +{ + uint64_t cfgoff; + + if (tag == 0){ + if (offset & 0x4){ + cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8); + } else { + cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8); + } + } else { + cfgoff = tag + offset; + if (offset & 0x4){ + cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8); + } else { + cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8); + } + } + + REG_WRITE32(cfgoff, data); +} + /* * PCI Interrupt handling |