xref: /netbsd-src/sys/arch/arm/ixp12x0/ixp12x0.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*	$NetBSD: ixp12x0.c,v 1.21 2021/08/07 16:18:44 thorpej Exp $ */
27374c0afSichiro /*
34b8928adSichiro  * Copyright (c) 2002, 2003
47374c0afSichiro  *	Ichiro FUKUHARA <ichiro@ichiro.org>.
57374c0afSichiro  * All rights reserved.
67374c0afSichiro  *
77374c0afSichiro  * Redistribution and use in source and binary forms, with or without
87374c0afSichiro  * modification, are permitted provided that the following conditions
97374c0afSichiro  * are met:
107374c0afSichiro  * 1. Redistributions of source code must retain the above copyright
117374c0afSichiro  *    notice, this list of conditions and the following disclaimer.
127374c0afSichiro  * 2. Redistributions in binary form must reproduce the above copyright
137374c0afSichiro  *    notice, this list of conditions and the following disclaimer in the
147374c0afSichiro  *    documentation and/or other materials provided with the distribution.
157374c0afSichiro  *
167374c0afSichiro  * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
177374c0afSichiro  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
187374c0afSichiro  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
197374c0afSichiro  * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
207374c0afSichiro  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
217374c0afSichiro  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
227374c0afSichiro  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
237374c0afSichiro  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
247374c0afSichiro  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
257374c0afSichiro  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
267374c0afSichiro  * SUCH DAMAGE.
277374c0afSichiro  */
287374c0afSichiro 
294691b478Sigy #include <sys/cdefs.h>
30*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: ixp12x0.c,v 1.21 2021/08/07 16:18:44 thorpej Exp $");
314691b478Sigy 
327374c0afSichiro #include <sys/param.h>
337374c0afSichiro #include <sys/systm.h>
347374c0afSichiro #include <sys/device.h>
357374c0afSichiro #include <uvm/uvm.h>
367374c0afSichiro 
37ed9977b1Sdyoung #include <sys/bus.h>
387374c0afSichiro 
397374c0afSichiro #include <arm/ixp12x0/ixp12x0reg.h>
407374c0afSichiro #include <arm/ixp12x0/ixp12x0var.h>
417374c0afSichiro #include <arm/ixp12x0/ixp12x0_pcireg.h>
427374c0afSichiro 
437374c0afSichiro static struct ixp12x0_softc *ixp12x0_softc;
447374c0afSichiro 
457374c0afSichiro void
ixp12x0_attach(struct ixp12x0_softc * sc)46454af1c0Sdsl ixp12x0_attach(struct ixp12x0_softc *sc)
477374c0afSichiro {
487374c0afSichiro 	struct pcibus_attach_args pba;
497374c0afSichiro 	pcireg_t reg;
507374c0afSichiro 
517374c0afSichiro 	ixp12x0_softc = sc;
527374c0afSichiro 
537374c0afSichiro 	printf("\n");
54cdb56b83Sigy 
55cdb56b83Sigy 	sc->sc_iot = &ixp12x0_bs_tag;
56cdb56b83Sigy 
577374c0afSichiro 	/*
58cdb56b83Sigy 	 * Mapping for PCI Configuration Spase Registers
597374c0afSichiro 	 */
60cdb56b83Sigy 	if (bus_space_map(sc->sc_iot, IXP12X0_PCI_HWBASE, IXP12X0_PCI_SIZE,
61cdb56b83Sigy 			  0, &sc->sc_pci_ioh))
62cbab9cadSchs 		panic("%s: unable to map PCI registers", device_xname(sc->sc_dev));
63cdb56b83Sigy 	if (bus_space_map(sc->sc_iot, IXP12X0_PCI_TYPE0_HWBASE,
64cdb56b83Sigy 			  IXP12X0_PCI_TYPE0_SIZE, 0, &sc->sc_conf0_ioh))
65cdb56b83Sigy 		panic("%s: unable to map PCI Configutation 0\n",
66cbab9cadSchs 		      device_xname(sc->sc_dev));
67cdb56b83Sigy 	if (bus_space_map(sc->sc_iot, IXP12X0_PCI_TYPE1_HWBASE,
68cdb56b83Sigy 			  IXP12X0_PCI_TYPE0_SIZE, 1, &sc->sc_conf1_ioh))
69cdb56b83Sigy 		panic("%s: unable to map PCI Configutation 1\n",
70cbab9cadSchs 		      device_xname(sc->sc_dev));
714b8928adSichiro 
727374c0afSichiro 	/*
737374c0afSichiro 	 * PCI bus reset
747374c0afSichiro 	 */
754b8928adSichiro 	/* disable PCI command */
764b8928adSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
774b8928adSichiro 		PCI_COMMAND_STATUS_REG, 0xffff0000);
78517449c3Sichiro 	/* XXX assert PCI reset Mode */
797374c0afSichiro 	reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
807374c0afSichiro 		SA_CONTROL) &~ SA_CONTROL_PNR;
817374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
827374c0afSichiro 		SA_CONTROL, reg);
837374c0afSichiro 	DELAY(10);
847374c0afSichiro 
857374c0afSichiro 	/* XXX Disable door bell and outbound interrupt */
867374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
877374c0afSichiro 		PCI_CAP_PTR, 0xc);
887374c0afSichiro 	/* Disable door bell int to PCI */
897374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
90517449c3Sichiro 		DBELL_PCI_MASK, 0x0);
917374c0afSichiro 	/* Disable door bell int to SA-core */
927374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
93517449c3Sichiro 		DBELL_SA_MASK, 0x0);
947374c0afSichiro 
954b8928adSichiro 	/*  We setup a 1:1 memory map of bus<->physical addresses */
967374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
974b8928adSichiro 		PCI_ADDR_EXT,
984b8928adSichiro 		PCI_ADDR_EXT_PMSA(IXP12X0_PCI_MEM_HWBASE));
997374c0afSichiro 
100517449c3Sichiro 	/* XXX Negate PCI reset */
1017374c0afSichiro 	reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
1027374c0afSichiro 		SA_CONTROL) | SA_CONTROL_PNR;
1037374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
1047374c0afSichiro 		SA_CONTROL, reg);
1057374c0afSichiro 	DELAY(10);
1067374c0afSichiro 	/*
1077374c0afSichiro 	 * specify window size of memory access and SDRAM.
1087374c0afSichiro 	 */
1094b8928adSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_MEM_BAR,
1104b8928adSichiro 		IXP1200_PCI_MEM_BAR & IXP_PCI_MEM_BAR_MASK);
1117374c0afSichiro 
1124b8928adSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_IO_BAR,
1134b8928adSichiro 		IXP1200_PCI_IO_BAR & IXP_PCI_IO_BAR_MASK);
1147374c0afSichiro 
1154b8928adSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_DRAM_BAR,
1164b8928adSichiro 		IXP1200_PCI_DRAM_BAR & IXP_PCI_DRAM_BAR_MASK);
1177374c0afSichiro 
1187374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
1197374c0afSichiro 		CSR_BASE_ADDR_MASK, CSR_BASE_ADDR_MASK_1M);
1207374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
1217374c0afSichiro 		DRAM_BASE_ADDR_MASK, DRAM_BASE_ADDR_MASK_256MB);
1227374c0afSichiro 
1234b8928adSichiro #ifdef PCI_DEBUG
1244b8928adSichiro 	printf("IXP_PCI_MEM_BAR = 0x%08x\nIXP_PCI_IO_BAR = 0x%08x\nIXP_PCI_DRAM_BAR = 0x%08x\nPCI_ADDR_EXT = 0x%08x\nCSR_BASE_ADDR_MASK = 0x%08x\nDRAM_BASE_ADDR_MASK = 0x%08x\n",
1257374c0afSichiro 	bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_MEM_BAR),
1267374c0afSichiro 	bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_IO_BAR),
1277374c0afSichiro 	bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_DRAM_BAR),
1284b8928adSichiro 	bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, PCI_ADDR_EXT),
1294b8928adSichiro 	bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, CSR_BASE_ADDR_MASK),
1307374c0afSichiro 	bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, DRAM_BASE_ADDR_MASK));
1317374c0afSichiro #endif
1327374c0afSichiro 	/* Initialize complete */
1337374c0afSichiro 	reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
1347374c0afSichiro 		SA_CONTROL) | 0x1;
1357374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
1367374c0afSichiro 		SA_CONTROL, reg);
13722d06d95Sichiro #ifdef PCI_DEBUG
1387374c0afSichiro 	printf("SA_CONTROL = 0x%08x\n",
1397374c0afSichiro 		bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, SA_CONTROL));
1407374c0afSichiro #endif
1417374c0afSichiro 	/*
1427374c0afSichiro 	 * Enable bus mastering and I/O,memory access
1437374c0afSichiro 	 */
1447374c0afSichiro 	/* host only */
1457374c0afSichiro 	reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
1467374c0afSichiro 		PCI_COMMAND_STATUS_REG) |
1477374c0afSichiro 		PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
1484b8928adSichiro 		PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE |
1497374c0afSichiro 		PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE;
1507374c0afSichiro 	bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
1517374c0afSichiro 		PCI_COMMAND_STATUS_REG, reg);
1524b8928adSichiro #ifdef PCI_DEBUG
1537374c0afSichiro 	printf("PCI_COMMAND_STATUS_REG = 0x%08x\n",
1547374c0afSichiro 		bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, PCI_COMMAND_STATUS_REG));
1557374c0afSichiro #endif
1567374c0afSichiro 	/*
157365f7e19Sigy 	 * Initialize the PCI chipset tag.
1587374c0afSichiro 	 */
1597374c0afSichiro 	ixp12x0_pci_init(&sc->ia_pci_chipset, sc);
1604b8928adSichiro 
1614b8928adSichiro 	/*
1624b8928adSichiro 	 * Initialize the DMA tags.
1634b8928adSichiro 	 */
1644b8928adSichiro 	ixp12x0_pci_dma_init(sc);
1657374c0afSichiro 
1667374c0afSichiro 	/*
1677374c0afSichiro 	 * Attach the PCI bus.
1687374c0afSichiro 	 */
1697374c0afSichiro 	pba.pba_pc = &sc->ia_pci_chipset;
170365f7e19Sigy 	pba.pba_iot = &ixp12x0_bs_tag;
171365f7e19Sigy 	pba.pba_memt = &ixp12x0_bs_tag;
1727374c0afSichiro 	pba.pba_dmat = &sc->ia_pci_dmat;
1737dd7f8baSfvdl 	pba.pba_dmat64 = NULL;
1747374c0afSichiro 	pba.pba_bus = 0;	/* bus number = 0 */
1757374c0afSichiro 	pba.pba_intrswiz = 0;	/* XXX */
1767374c0afSichiro 	pba.pba_intrtag = 0;
177a6b2b839Sdyoung 	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
1787374c0afSichiro 		PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
179*c7fb772bSthorpej 	config_found(sc->sc_dev, &pba, pcibusprint, CFARGS_NONE);
1807374c0afSichiro }
1817374c0afSichiro 
1827374c0afSichiro void
ixp12x0_reset(void)1837374c0afSichiro ixp12x0_reset(void)
1847374c0afSichiro {
1857374c0afSichiro 	bus_space_write_4(ixp12x0_softc->sc_iot, ixp12x0_softc->sc_pci_ioh,
1867374c0afSichiro 		IXPPCI_IXP1200_RESET, RESET_FULL);
1877374c0afSichiro }
188