xref: /openbsd-src/sys/arch/octeon/dev/octeon_pcibus.c (revision b711551f3ad0c8a480c9d1297568b8616c06bdec)
1*b711551fSvisa /*	$OpenBSD: octeon_pcibus.c,v 1.23 2021/03/04 16:44:07 visa Exp $	*/
262023fb5Ssyuu /*	$NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $	*/
362023fb5Ssyuu /*	$NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $	*/
462023fb5Ssyuu 
562023fb5Ssyuu /*
662023fb5Ssyuu  * Copyright (c) 2009, 2010 Miodrag Vallat.
762023fb5Ssyuu  *
862023fb5Ssyuu  * Permission to use, copy, modify, and distribute this software for any
962023fb5Ssyuu  * purpose with or without fee is hereby granted, provided that the above
1062023fb5Ssyuu  * copyright notice and this permission notice appear in all copies.
1162023fb5Ssyuu  *
1262023fb5Ssyuu  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1362023fb5Ssyuu  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1462023fb5Ssyuu  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1562023fb5Ssyuu  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1662023fb5Ssyuu  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1762023fb5Ssyuu  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1862023fb5Ssyuu  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1962023fb5Ssyuu  */
2062023fb5Ssyuu /*-
2162023fb5Ssyuu  * Copyright (c) 2001 The NetBSD Foundation, Inc.
2262023fb5Ssyuu  * All rights reserved.
2362023fb5Ssyuu  *
2462023fb5Ssyuu  * This code is derived from software contributed to The NetBSD Foundation
2562023fb5Ssyuu  * by Jason R. Thorpe.
2662023fb5Ssyuu  *
2762023fb5Ssyuu  * Redistribution and use in source and binary forms, with or without
2862023fb5Ssyuu  * modification, are permitted provided that the following conditions
2962023fb5Ssyuu  * are met:
3062023fb5Ssyuu  * 1. Redistributions of source code must retain the above copyright
3162023fb5Ssyuu  *    notice, this list of conditions and the following disclaimer.
3262023fb5Ssyuu  * 2. Redistributions in binary form must reproduce the above copyright
3362023fb5Ssyuu  *    notice, this list of conditions and the following disclaimer in the
3462023fb5Ssyuu  *    documentation and/or other materials provided with the distribution.
3562023fb5Ssyuu  *
3662023fb5Ssyuu  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
3762023fb5Ssyuu  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
3862023fb5Ssyuu  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3962023fb5Ssyuu  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
4062023fb5Ssyuu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4162023fb5Ssyuu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4262023fb5Ssyuu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4362023fb5Ssyuu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
4462023fb5Ssyuu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4562023fb5Ssyuu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4662023fb5Ssyuu  * POSSIBILITY OF SUCH DAMAGE.
4762023fb5Ssyuu  */
4862023fb5Ssyuu 
4962023fb5Ssyuu #include <sys/param.h>
5062023fb5Ssyuu #include <sys/systm.h>
5162023fb5Ssyuu #include <sys/device.h>
5262023fb5Ssyuu #include <sys/extent.h>
5362023fb5Ssyuu #include <sys/malloc.h>
5462023fb5Ssyuu 
5562023fb5Ssyuu #include <machine/autoconf.h>
5662023fb5Ssyuu #include <machine/bus.h>
5762023fb5Ssyuu #include <machine/intr.h>
581f975194Sjasper #include <machine/octeonvar.h>
5962023fb5Ssyuu 
6062023fb5Ssyuu #include <dev/pci/pcidevs.h>
6162023fb5Ssyuu #include <dev/pci/pcireg.h>
6262023fb5Ssyuu #include <dev/pci/pcivar.h>
6362023fb5Ssyuu #include <dev/pci/ppbreg.h>
6462023fb5Ssyuu 
6561e15267Ssyuu #include <octeon/dev/iobusvar.h>
6662023fb5Ssyuu #include <octeon/dev/octeon_pcibus.h>
6762023fb5Ssyuu 
6862023fb5Ssyuu #include <uvm/uvm_extern.h>
6962023fb5Ssyuu 
703e193585Sjasper #ifdef DEBUG
713e193585Sjasper #define OCTEON_PCIDEBUG(p) printf p
7262023fb5Ssyuu #else
733e193585Sjasper #define OCTEON_PCIDEBUG(p)
7462023fb5Ssyuu #endif
7562023fb5Ssyuu 
7662023fb5Ssyuu #define REG_READ32(addr)	(*(volatile uint32_t *)(addr))
7762023fb5Ssyuu #define REG_WRITE32(addr, data)	(*(volatile uint32_t *)(addr) = (uint32_t)(data))
7862023fb5Ssyuu 
790e777491Svisa struct octeon_pcibus_softc {
800e777491Svisa 	struct device sc_dev;
810e777491Svisa 	struct mips_pci_chipset sc_pc;
820e777491Svisa 	struct iobus_attach_args *sc_aa;
830e777491Svisa };
840e777491Svisa 
8562023fb5Ssyuu int	octeon_pcibus_match(struct device *, void *, void *);
8662023fb5Ssyuu void	octeon_pcibus_attach(struct device *, struct device *, void *);
870e777491Svisa int	octeon_pcibus_print(void *, const char *);
8862023fb5Ssyuu 
8962023fb5Ssyuu const struct cfattach pcibus_ca = {
9062023fb5Ssyuu 	sizeof(struct octeon_pcibus_softc),
9162023fb5Ssyuu 	octeon_pcibus_match, octeon_pcibus_attach
9262023fb5Ssyuu };
9362023fb5Ssyuu 
9462023fb5Ssyuu struct cfdriver pcibus_cd = {
9562023fb5Ssyuu 	NULL, "pcibus", DV_DULL
9662023fb5Ssyuu };
9762023fb5Ssyuu 
9862023fb5Ssyuu bus_addr_t octeon_pcibus_pa_to_device(paddr_t);
9962023fb5Ssyuu paddr_t	octeon_pcibus_device_to_pa(bus_addr_t);
10062023fb5Ssyuu void	octeon_pcibus_attach_hook(struct device *, struct device *,
10162023fb5Ssyuu 	    struct pcibus_attach_args *);
10262023fb5Ssyuu int	octeon_pcibus_bus_maxdevs(void *, int);
10362023fb5Ssyuu pcitag_t octeon_pcibus_make_tag(void *, int, int, int);
10462023fb5Ssyuu void	octeon_pcibus_decompose_tag(void *, pcitag_t, int *, int *, int *);
105b1926db3Smiod int	octeon_pcibus_pci_conf_size(void *, pcitag_t);
10662023fb5Ssyuu pcireg_t octeon_pcibus_pci_conf_read(void *, pcitag_t, int);
10762023fb5Ssyuu void	octeon_pcibus_pci_conf_write(void *, pcitag_t, int, pcireg_t);
10862023fb5Ssyuu int	octeon_pcibus_pci_intr_map(struct pci_attach_args *,
10962023fb5Ssyuu 	    pci_intr_handle_t *);
11062023fb5Ssyuu const char *octeon_pcibus_pci_intr_string(void *, pci_intr_handle_t);
11162023fb5Ssyuu void	*octeon_pcibus_pci_intr_establish(void *, pci_intr_handle_t, int,
11262023fb5Ssyuu 	    int (*)(void *), void *, char *);
11362023fb5Ssyuu void	octeon_pcibus_pci_intr_disestablish(void *, void *);
114*b711551fSvisa int	octeon_pcibus_intr_map(int dev, int fn, int pin);
115*b711551fSvisa int	octeon_pcibus_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
116*b711551fSvisa 	    bus_space_handle_t *);
117*b711551fSvisa int	octeon_pcibus_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
118*b711551fSvisa 	    bus_space_handle_t *);
1190e777491Svisa struct extent *octeon_pcibus_get_resource_extent(pci_chipset_tag_t, int);
12062023fb5Ssyuu 
12162023fb5Ssyuu struct machine_bus_dma_tag octeon_pcibus_bus_dma_tag = {
12262023fb5Ssyuu 	._cookie = NULL,
12362023fb5Ssyuu 	._dmamap_create =	_dmamap_create,
12462023fb5Ssyuu 	._dmamap_destroy =	_dmamap_destroy,
12562023fb5Ssyuu 	._dmamap_load =		_dmamap_load,
12662023fb5Ssyuu 	._dmamap_load_mbuf =	_dmamap_load_mbuf,
12762023fb5Ssyuu 	._dmamap_load_uio =	_dmamap_load_uio,
12862023fb5Ssyuu 	._dmamap_load_raw =	_dmamap_load_raw,
12962023fb5Ssyuu 	._dmamap_load_buffer =	_dmamap_load_buffer,
13062023fb5Ssyuu 	._dmamap_unload =	_dmamap_unload,
13162023fb5Ssyuu 	._dmamap_sync =		_dmamap_sync,
13262023fb5Ssyuu 	._dmamem_alloc =	_dmamem_alloc,
13362023fb5Ssyuu 	._dmamem_free =		_dmamem_free,
13462023fb5Ssyuu 	._dmamem_map =		_dmamem_map,
13562023fb5Ssyuu 	._dmamem_unmap =	_dmamem_unmap,
13662023fb5Ssyuu 	._dmamem_mmap =		_dmamem_mmap,
13762023fb5Ssyuu 	._pa_to_device =	octeon_pcibus_pa_to_device,
13862023fb5Ssyuu 	._device_to_pa =	octeon_pcibus_device_to_pa
13962023fb5Ssyuu };
14062023fb5Ssyuu 
14162023fb5Ssyuu #define _OCTEON_PCIBUS_PCIIO_BASE	0x00001000
14262023fb5Ssyuu #define _OCTEON_PCIBUS_PCIIO_SIZE	0x08000000
14362023fb5Ssyuu #define _OCTEON_PCIBUS_PCIMEM_BASE	0x80000000
14462023fb5Ssyuu #define _OCTEON_PCIBUS_PCIMEM_SIZE	0x40000000
14562023fb5Ssyuu 
146b1926db3Smiod struct mips_bus_space octeon_pcibus_pci_io_space_tag = {
14762023fb5Ssyuu 	.bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIIO_BASE, CCA_NC),
14862023fb5Ssyuu 	.bus_private = NULL,
14962023fb5Ssyuu 	._space_read_1 =	generic_space_read_1,
15062023fb5Ssyuu 	._space_write_1 =	generic_space_write_1,
15162023fb5Ssyuu 	._space_read_2 =	generic_space_read_2,
15262023fb5Ssyuu 	._space_write_2 =	generic_space_write_2,
15362023fb5Ssyuu 	._space_read_4 =	generic_space_read_4,
15462023fb5Ssyuu 	._space_write_4 =	generic_space_write_4,
15562023fb5Ssyuu 	._space_read_8 =	generic_space_read_8,
15662023fb5Ssyuu 	._space_write_8 =	generic_space_write_8,
15762023fb5Ssyuu 	._space_read_raw_2 =	generic_space_read_raw_2,
15862023fb5Ssyuu 	._space_write_raw_2 =	generic_space_write_raw_2,
15962023fb5Ssyuu 	._space_read_raw_4 =	generic_space_read_raw_4,
16062023fb5Ssyuu 	._space_write_raw_4 =	generic_space_write_raw_4,
16162023fb5Ssyuu 	._space_read_raw_8 =	generic_space_read_raw_8,
16262023fb5Ssyuu 	._space_write_raw_8 =	generic_space_write_raw_8,
16362023fb5Ssyuu 	._space_map =		octeon_pcibus_io_map,
16462023fb5Ssyuu 	._space_unmap =		generic_space_unmap,
16562023fb5Ssyuu 	._space_subregion =	generic_space_region,
16662023fb5Ssyuu 	._space_vaddr =		generic_space_vaddr
16762023fb5Ssyuu };
16862023fb5Ssyuu 
169b1926db3Smiod struct mips_bus_space octeon_pcibus_pci_mem_space_tag = {
17062023fb5Ssyuu 	.bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIMEM_BASE, CCA_NC),
17162023fb5Ssyuu 	.bus_private = NULL,
17262023fb5Ssyuu 	._space_read_1 =	generic_space_read_1,
17362023fb5Ssyuu 	._space_write_1 =	generic_space_write_1,
17462023fb5Ssyuu 	._space_read_2 =	generic_space_read_2,
17562023fb5Ssyuu 	._space_write_2 =	generic_space_write_2,
17662023fb5Ssyuu 	._space_read_4 =	generic_space_read_4,
17762023fb5Ssyuu 	._space_write_4 =	generic_space_write_4,
17862023fb5Ssyuu 	._space_read_8 =	generic_space_read_8,
17962023fb5Ssyuu 	._space_write_8 =	generic_space_write_8,
18062023fb5Ssyuu 	._space_read_raw_2 =	generic_space_read_raw_2,
18162023fb5Ssyuu 	._space_write_raw_2 =	generic_space_write_raw_2,
18262023fb5Ssyuu 	._space_read_raw_4 =	generic_space_read_raw_4,
18362023fb5Ssyuu 	._space_write_raw_4 =	generic_space_write_raw_4,
18462023fb5Ssyuu 	._space_read_raw_8 =	generic_space_read_raw_8,
18562023fb5Ssyuu 	._space_write_raw_8 =	generic_space_write_raw_8,
18662023fb5Ssyuu 	._space_map =		octeon_pcibus_mem_map,
18762023fb5Ssyuu 	._space_unmap =		generic_space_unmap,
18862023fb5Ssyuu 	._space_subregion =	generic_space_region,
18962023fb5Ssyuu 	._space_vaddr =		generic_space_vaddr
19062023fb5Ssyuu };
19162023fb5Ssyuu 
19262023fb5Ssyuu int
octeon_pcibus_match(struct device * parent,void * vcf,void * aux)19362023fb5Ssyuu octeon_pcibus_match(struct device *parent, void *vcf, void *aux)
19462023fb5Ssyuu {
19561e15267Ssyuu 	struct iobus_attach_args *aa = aux;
19662023fb5Ssyuu 
1971f975194Sjasper 	if ((octeon_boot_info->config_flags & BOOTINFO_CFG_FLAG_PCI_HOST) == 0) {
1983e193585Sjasper 		OCTEON_PCIDEBUG(("%s, no PCI host function detected.\n", __func__));
1991f975194Sjasper 		return 0;
2001f975194Sjasper 	}
20107ef387cSjasper 
20261e15267Ssyuu 	if (strcmp(aa->aa_name, pcibus_cd.cd_name) == 0)
20362023fb5Ssyuu 		return 1;
20462023fb5Ssyuu 
20562023fb5Ssyuu 	return 0;
20662023fb5Ssyuu }
20762023fb5Ssyuu 
20862023fb5Ssyuu void
octeon_pcibus_attach(struct device * parent,struct device * self,void * aux)20962023fb5Ssyuu octeon_pcibus_attach(struct device *parent, struct device *self, void *aux)
21062023fb5Ssyuu {
21162023fb5Ssyuu 	struct octeon_pcibus_softc *sc;
21262023fb5Ssyuu 	struct pcibus_attach_args pba;
21362023fb5Ssyuu 
21462023fb5Ssyuu 	sc = (struct octeon_pcibus_softc *)self;
215e43065ceSpirofti 	sc->sc_aa = aux;
21662023fb5Ssyuu 
217ce65887aSpirofti 	printf("\n");
218ce65887aSpirofti 
21962023fb5Ssyuu 	/*
22062023fb5Ssyuu 	 * Attach PCI bus.
22162023fb5Ssyuu 	 */
22262023fb5Ssyuu 	sc->sc_pc.pc_attach_hook = octeon_pcibus_attach_hook;
22362023fb5Ssyuu 	sc->sc_pc.pc_bus_maxdevs = octeon_pcibus_bus_maxdevs;
22462023fb5Ssyuu 	sc->sc_pc.pc_make_tag = octeon_pcibus_make_tag;
22562023fb5Ssyuu 	sc->sc_pc.pc_decompose_tag = octeon_pcibus_decompose_tag;
22662023fb5Ssyuu 
22762023fb5Ssyuu 	sc->sc_pc.pc_conf_v = sc;
228b1926db3Smiod 	sc->sc_pc.pc_conf_size = octeon_pcibus_pci_conf_size;
22962023fb5Ssyuu 	sc->sc_pc.pc_conf_read = octeon_pcibus_pci_conf_read;
23062023fb5Ssyuu 	sc->sc_pc.pc_conf_write = octeon_pcibus_pci_conf_write;
23162023fb5Ssyuu 
23262023fb5Ssyuu 	sc->sc_pc.pc_intr_v = sc;
23362023fb5Ssyuu 	sc->sc_pc.pc_intr_map = octeon_pcibus_pci_intr_map;
23462023fb5Ssyuu 	sc->sc_pc.pc_intr_string = octeon_pcibus_pci_intr_string;
23562023fb5Ssyuu 	sc->sc_pc.pc_intr_establish = octeon_pcibus_pci_intr_establish;
23662023fb5Ssyuu 	sc->sc_pc.pc_intr_disestablish = octeon_pcibus_pci_intr_disestablish;
23762023fb5Ssyuu 
23862023fb5Ssyuu 	bzero(&pba, sizeof pba);
23962023fb5Ssyuu 	pba.pba_busname = "pci";
24062023fb5Ssyuu 	pba.pba_iot = &octeon_pcibus_pci_io_space_tag;
24162023fb5Ssyuu 	pba.pba_memt = &octeon_pcibus_pci_mem_space_tag;
24262023fb5Ssyuu 	pba.pba_dmat = &octeon_pcibus_bus_dma_tag;
24362023fb5Ssyuu 	pba.pba_pc = &sc->sc_pc;
24462023fb5Ssyuu 	pba.pba_domain = pci_ndomains++;
24562023fb5Ssyuu 	pba.pba_bus = 0;
24662023fb5Ssyuu 	pba.pba_ioex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 1);
24762023fb5Ssyuu 	pba.pba_memex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 0);
24862023fb5Ssyuu 
24962023fb5Ssyuu 	config_found(&sc->sc_dev, &pba, octeon_pcibus_print);
25062023fb5Ssyuu }
25162023fb5Ssyuu 
25262023fb5Ssyuu bus_addr_t
octeon_pcibus_pa_to_device(paddr_t pa)25362023fb5Ssyuu octeon_pcibus_pa_to_device(paddr_t pa)
25462023fb5Ssyuu {
255212e7310Sjasper 	OCTEON_PCIDEBUG(("%s:%d: pa=%p\n", __func__, __LINE__, (void *)pa));
25662023fb5Ssyuu 
25762023fb5Ssyuu 	return pa & 0x1ffffffffffffUL;
25862023fb5Ssyuu }
25962023fb5Ssyuu 
26062023fb5Ssyuu paddr_t
octeon_pcibus_device_to_pa(bus_addr_t addr)26162023fb5Ssyuu octeon_pcibus_device_to_pa(bus_addr_t addr)
26262023fb5Ssyuu {
263212e7310Sjasper 	OCTEON_PCIDEBUG(("%s:%d: addr=%lx\n", __func__, __LINE__, addr));
26462023fb5Ssyuu 
26562023fb5Ssyuu 	return PHYS_TO_XKPHYS(addr, CCA_NC);
26662023fb5Ssyuu }
26762023fb5Ssyuu 
26862023fb5Ssyuu int
octeon_pcibus_print(void * aux,const char * pnp)26962023fb5Ssyuu octeon_pcibus_print(void *aux, const char *pnp)
27062023fb5Ssyuu {
27162023fb5Ssyuu 	struct pcibus_attach_args *pba = aux;
27262023fb5Ssyuu 
27362023fb5Ssyuu 	if (pnp)
27462023fb5Ssyuu 		printf("%s at %s", pba->pba_busname, pnp);
27562023fb5Ssyuu 	printf(" bus %d", pba->pba_bus);
27662023fb5Ssyuu 
27762023fb5Ssyuu 	return UNCONF;
27862023fb5Ssyuu }
27962023fb5Ssyuu 
28062023fb5Ssyuu /*
28162023fb5Ssyuu  * various PCI helpers
28262023fb5Ssyuu  */
28362023fb5Ssyuu void
octeon_pcibus_attach_hook(struct device * parent,struct device * self,struct pcibus_attach_args * pba)28462023fb5Ssyuu octeon_pcibus_attach_hook(struct device *parent, struct device *self,
28562023fb5Ssyuu     struct pcibus_attach_args *pba)
28662023fb5Ssyuu {
28762023fb5Ssyuu }
28862023fb5Ssyuu 
28962023fb5Ssyuu /*
29062023fb5Ssyuu  * PCI configuration space access routines
29162023fb5Ssyuu  */
29262023fb5Ssyuu int
octeon_pcibus_bus_maxdevs(void * v,int busno)29362023fb5Ssyuu octeon_pcibus_bus_maxdevs(void *v, int busno)
29462023fb5Ssyuu {
29507ef387cSjasper 	return (32);
29662023fb5Ssyuu }
29762023fb5Ssyuu 
29862023fb5Ssyuu pcitag_t
octeon_pcibus_make_tag(void * unused,int b,int d,int f)29962023fb5Ssyuu octeon_pcibus_make_tag(void *unused, int b, int d, int f)
30062023fb5Ssyuu {
30162023fb5Ssyuu 	return (b << 16) | (d << 11) | (f << 8);
30262023fb5Ssyuu }
30362023fb5Ssyuu 
30462023fb5Ssyuu void
octeon_pcibus_decompose_tag(void * unused,pcitag_t tag,int * bp,int * dp,int * fp)30562023fb5Ssyuu octeon_pcibus_decompose_tag(void *unused, pcitag_t tag, int *bp, int *dp, int *fp)
30662023fb5Ssyuu {
30762023fb5Ssyuu 	if (bp != NULL)
30862023fb5Ssyuu 		*bp = (tag >> 16) & 0xff;
30962023fb5Ssyuu 	if (dp != NULL)
31062023fb5Ssyuu 		*dp = (tag >> 11) & 0x1f;
31162023fb5Ssyuu 	if (fp != NULL)
31262023fb5Ssyuu 		*fp = (tag >> 8) & 0x7;
31362023fb5Ssyuu }
31462023fb5Ssyuu 
315b1926db3Smiod int
octeon_pcibus_pci_conf_size(void * v,pcitag_t tag)316b1926db3Smiod octeon_pcibus_pci_conf_size(void *v, pcitag_t tag)
317b1926db3Smiod {
31846e69387Ssyuu 	return PCI_CONFIG_SPACE_SIZE;
319b1926db3Smiod }
320b1926db3Smiod 
32162023fb5Ssyuu pcireg_t
octeon_pcibus_pci_conf_read(void * v,pcitag_t tag,int offset)32262023fb5Ssyuu octeon_pcibus_pci_conf_read(void *v, pcitag_t tag, int offset)
32362023fb5Ssyuu {
32462023fb5Ssyuu 	pcireg_t data;
32562023fb5Ssyuu 	uint64_t cfgoff;
32662023fb5Ssyuu 
32762023fb5Ssyuu 	if (tag == 0){
32862023fb5Ssyuu 		if (offset & 0x4){
32962023fb5Ssyuu 			cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
33062023fb5Ssyuu 		} else {
33162023fb5Ssyuu 			cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
33262023fb5Ssyuu 		}
33362023fb5Ssyuu 	} else {
33462023fb5Ssyuu 		cfgoff = tag + offset;
33562023fb5Ssyuu 		if (offset & 0x4) {
33662023fb5Ssyuu 			cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
33762023fb5Ssyuu 		} else {
33862023fb5Ssyuu 			cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
33962023fb5Ssyuu 		}
34062023fb5Ssyuu 	}
34162023fb5Ssyuu 
34262023fb5Ssyuu 	data = REG_READ32(cfgoff);
34362023fb5Ssyuu 	return data;
34462023fb5Ssyuu }
34562023fb5Ssyuu 
34662023fb5Ssyuu void
octeon_pcibus_pci_conf_write(void * v,pcitag_t tag,int offset,pcireg_t data)34762023fb5Ssyuu octeon_pcibus_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
34862023fb5Ssyuu {
34962023fb5Ssyuu 	uint64_t cfgoff;
35062023fb5Ssyuu 
35162023fb5Ssyuu 	if (tag == 0){
35262023fb5Ssyuu 		if (offset & 0x4){
35362023fb5Ssyuu 			cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
35462023fb5Ssyuu 		} else {
35562023fb5Ssyuu 			cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
35662023fb5Ssyuu 		}
35762023fb5Ssyuu 	} else {
35862023fb5Ssyuu 		cfgoff = tag + offset;
35962023fb5Ssyuu 		if (offset & 0x4){
36062023fb5Ssyuu 			cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
36162023fb5Ssyuu 		} else {
36262023fb5Ssyuu 			cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
36362023fb5Ssyuu 		}
36462023fb5Ssyuu 	}
36562023fb5Ssyuu 
36662023fb5Ssyuu 	REG_WRITE32(cfgoff, data);
36762023fb5Ssyuu }
36862023fb5Ssyuu 
36962023fb5Ssyuu 
37062023fb5Ssyuu /*
37162023fb5Ssyuu  * PCI Interrupt handling
37262023fb5Ssyuu  */
37362023fb5Ssyuu int
octeon_pcibus_pci_intr_map(struct pci_attach_args * pa,pci_intr_handle_t * ihp)37462023fb5Ssyuu octeon_pcibus_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
37562023fb5Ssyuu {
37662023fb5Ssyuu #if 0
37762023fb5Ssyuu 	struct octeon_pcibus_softc *sc = pa->pa_pc->pc_intr_v;
37862023fb5Ssyuu #endif
37962023fb5Ssyuu 	int bus, dev, fn, pin;
38062023fb5Ssyuu 
38162023fb5Ssyuu 	*ihp = (pci_intr_handle_t)-1;
38262023fb5Ssyuu 
38362023fb5Ssyuu 	if (pa->pa_intrpin == 0)	/* no interrupt needed */
38462023fb5Ssyuu 		return 1;
38562023fb5Ssyuu 
38662023fb5Ssyuu #ifdef DIAGNOSTIC
38762023fb5Ssyuu 	if (pa->pa_intrpin > 4) {
38862023fb5Ssyuu 		printf("%s: bad interrupt pin %d\n", __func__, pa->pa_intrpin);
38962023fb5Ssyuu 		return 1;
39062023fb5Ssyuu 	}
39162023fb5Ssyuu #endif
39262023fb5Ssyuu 
39362023fb5Ssyuu 	pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &fn);
39462023fb5Ssyuu 	if (pa->pa_bridgetag) {
39562023fb5Ssyuu 		pin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev);
39662023fb5Ssyuu 		*ihp = pa->pa_bridgeih[pin - 1];
39762023fb5Ssyuu 	} else {
39862023fb5Ssyuu 		if (bus == 0)
39962023fb5Ssyuu 			*ihp = octeon_pcibus_intr_map(dev, fn, pa->pa_intrpin);
40062023fb5Ssyuu 
40162023fb5Ssyuu 		if (*ihp == (pci_intr_handle_t)-1)
40262023fb5Ssyuu 			return 1;
40362023fb5Ssyuu 	}
40462023fb5Ssyuu 
40562023fb5Ssyuu 	return 0;
40662023fb5Ssyuu }
40762023fb5Ssyuu 
40862023fb5Ssyuu const char *
octeon_pcibus_pci_intr_string(void * cookie,pci_intr_handle_t ih)40962023fb5Ssyuu octeon_pcibus_pci_intr_string(void *cookie, pci_intr_handle_t ih)
41062023fb5Ssyuu {
41162023fb5Ssyuu 	static char irqstr[sizeof("irq 0123456789")];
41262023fb5Ssyuu 
413f47f0c33Sjasper 	snprintf(irqstr, sizeof irqstr, "irq %ld", ih);
41462023fb5Ssyuu 	return irqstr;
41562023fb5Ssyuu }
41662023fb5Ssyuu 
41762023fb5Ssyuu void *
octeon_pcibus_pci_intr_establish(void * cookie,pci_intr_handle_t ih,int level,int (* cb)(void *),void * cbarg,char * name)41862023fb5Ssyuu octeon_pcibus_pci_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
41962023fb5Ssyuu     int (*cb)(void *), void *cbarg, char *name)
42062023fb5Ssyuu {
42161e15267Ssyuu 	return octeon_intr_establish(ih, level, cb, cbarg, name);
42262023fb5Ssyuu }
42362023fb5Ssyuu 
42462023fb5Ssyuu void
octeon_pcibus_pci_intr_disestablish(void * cookie,void * ihp)42562023fb5Ssyuu octeon_pcibus_pci_intr_disestablish(void *cookie, void *ihp)
42662023fb5Ssyuu {
427391405f4Svisa 	octeon_intr_disestablish(ihp);
42862023fb5Ssyuu }
42962023fb5Ssyuu 
43062023fb5Ssyuu /*
43162023fb5Ssyuu  * bus_space mapping routines.
43262023fb5Ssyuu  */
43362023fb5Ssyuu int
octeon_pcibus_io_map(bus_space_tag_t t,bus_addr_t offs,bus_size_t size,int flags,bus_space_handle_t * bshp)43462023fb5Ssyuu octeon_pcibus_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
43562023fb5Ssyuu     bus_space_handle_t *bshp)
43662023fb5Ssyuu {
43762023fb5Ssyuu 	if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
43862023fb5Ssyuu 		offs +=
43962023fb5Ssyuu 		    PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
44062023fb5Ssyuu 	}
44162023fb5Ssyuu 	*bshp = t->bus_base + offs;
44262023fb5Ssyuu 	return 0;
44362023fb5Ssyuu }
44462023fb5Ssyuu 
44562023fb5Ssyuu int
octeon_pcibus_mem_map(bus_space_tag_t t,bus_addr_t offs,bus_size_t size,int flags,bus_space_handle_t * bshp)44662023fb5Ssyuu octeon_pcibus_mem_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
44762023fb5Ssyuu     bus_space_handle_t *bshp)
44862023fb5Ssyuu {
44962023fb5Ssyuu 	if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
45062023fb5Ssyuu 		offs +=
45162023fb5Ssyuu 		    PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
45262023fb5Ssyuu 	}
45362023fb5Ssyuu 	*bshp = t->bus_base + offs;
45462023fb5Ssyuu 	return 0;
45562023fb5Ssyuu }
45662023fb5Ssyuu 
45762023fb5Ssyuu /*
45862023fb5Ssyuu  * PCI resource handling
45962023fb5Ssyuu  */
46062023fb5Ssyuu struct extent *
octeon_pcibus_get_resource_extent(pci_chipset_tag_t pc,int io)46162023fb5Ssyuu octeon_pcibus_get_resource_extent(pci_chipset_tag_t pc, int io)
46262023fb5Ssyuu {
46362023fb5Ssyuu 	struct octeon_pcibus_softc *sc = pc->pc_conf_v;
46462023fb5Ssyuu 	struct extent *ex;
46562023fb5Ssyuu 	char *exname;
46662023fb5Ssyuu 	int exnamesz;
46762023fb5Ssyuu 
46862023fb5Ssyuu 	exnamesz = 1 + 16 + 4;
469a17ffb77Ssemarie 	exname = malloc(exnamesz, M_DEVBUF, M_NOWAIT);
47062023fb5Ssyuu 	if (exname == NULL)
47162023fb5Ssyuu 		return NULL;
47262023fb5Ssyuu 	snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname,
47362023fb5Ssyuu 	    io ? "_io" : "_mem");
47462023fb5Ssyuu 
47562023fb5Ssyuu 	ex = extent_create(exname, 0, 0xffffffffffffffff, M_DEVBUF, NULL, 0,
47662023fb5Ssyuu 	    EX_NOWAIT | EX_FILLED);
47762023fb5Ssyuu 	if (ex == NULL)
478a17ffb77Ssemarie 		goto error;
47962023fb5Ssyuu 
48062023fb5Ssyuu 	if (io) {
481a17ffb77Ssemarie 		if (extent_free(ex, _OCTEON_PCIBUS_PCIIO_BASE,
482a17ffb77Ssemarie 		    _OCTEON_PCIBUS_PCIIO_SIZE, EX_NOWAIT) != 0)
483a17ffb77Ssemarie 			goto error;
48462023fb5Ssyuu 	} else {
485a17ffb77Ssemarie 		if (extent_free(ex, _OCTEON_PCIBUS_PCIMEM_BASE,
486a17ffb77Ssemarie 		    _OCTEON_PCIBUS_PCIMEM_SIZE, EX_NOWAIT) != 0)
487a17ffb77Ssemarie 			goto error;
48862023fb5Ssyuu 	}
48962023fb5Ssyuu 
49070123da1Svisa #if defined(DEBUG) && defined(DIAGNOSTIC)
49162023fb5Ssyuu 	extent_print(ex);
49262023fb5Ssyuu #endif
49362023fb5Ssyuu 	return ex;
494a17ffb77Ssemarie 
495a17ffb77Ssemarie error:
496a17ffb77Ssemarie 	if (ex != NULL)
497a17ffb77Ssemarie 		extent_destroy(ex);
498a17ffb77Ssemarie 	free(exname, M_DEVBUF, exnamesz);
499a17ffb77Ssemarie 	return NULL;
50062023fb5Ssyuu }
50162023fb5Ssyuu 
50262023fb5Ssyuu /*
50362023fb5Ssyuu  * PCI model specific routines
50462023fb5Ssyuu  */
50562023fb5Ssyuu 
50662023fb5Ssyuu int
octeon_pcibus_intr_map(int dev,int fn,int pin)50762023fb5Ssyuu octeon_pcibus_intr_map(int dev, int fn, int pin)
50862023fb5Ssyuu {
50962023fb5Ssyuu 	return CIU_INT_PCI_INTA + ((pin - 1) & 3);
51062023fb5Ssyuu }
511