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