1 /* $NetBSD: ixp12x0.c,v 1.15 2009/03/14 15:36:02 dsl Exp $ */
3 * Copyright (c) 2002, 2003
4 * Ichiro FUKUHARA <ichiro@ichiro.org>.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: ixp12x0.c,v 1.15 2009/03/14 15:36:02 dsl Exp $");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/device.h>
37 #include <machine/bus.h>
39 #include <arm/ixp12x0/ixp12x0reg.h>
40 #include <arm/ixp12x0/ixp12x0var.h>
41 #include <arm/ixp12x0/ixp12x0_pcireg.h>
43 static struct ixp12x0_softc
*ixp12x0_softc
;
46 ixp12x0_attach(struct ixp12x0_softc
*sc
)
48 struct pcibus_attach_args pba
;
55 sc
->sc_iot
= &ixp12x0_bs_tag
;
58 * Mapping for PCI Configuration Spase Registers
60 if (bus_space_map(sc
->sc_iot
, IXP12X0_PCI_HWBASE
, IXP12X0_PCI_SIZE
,
62 panic("%s: unable to map PCI registers", sc
->sc_dev
.dv_xname
);
63 if (bus_space_map(sc
->sc_iot
, IXP12X0_PCI_TYPE0_HWBASE
,
64 IXP12X0_PCI_TYPE0_SIZE
, 0, &sc
->sc_conf0_ioh
))
65 panic("%s: unable to map PCI Configutation 0\n",
67 if (bus_space_map(sc
->sc_iot
, IXP12X0_PCI_TYPE1_HWBASE
,
68 IXP12X0_PCI_TYPE0_SIZE
, 1, &sc
->sc_conf1_ioh
))
69 panic("%s: unable to map PCI Configutation 1\n",
75 /* disable PCI command */
76 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
77 PCI_COMMAND_STATUS_REG
, 0xffff0000);
78 /* XXX assert PCI reset Mode */
79 reg
= bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
80 SA_CONTROL
) &~ SA_CONTROL_PNR
;
81 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
85 /* XXX Disable door bell and outbound interrupt */
86 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
88 /* Disable door bell int to PCI */
89 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
91 /* Disable door bell int to SA-core */
92 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
95 /* We setup a 1:1 memory map of bus<->physical addresses */
96 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
98 PCI_ADDR_EXT_PMSA(IXP12X0_PCI_MEM_HWBASE
));
100 /* XXX Negate PCI reset */
101 reg
= bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
102 SA_CONTROL
) | SA_CONTROL_PNR
;
103 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
107 * specify window size of memory access and SDRAM.
109 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
, IXP_PCI_MEM_BAR
,
110 IXP1200_PCI_MEM_BAR
& IXP_PCI_MEM_BAR_MASK
);
112 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
, IXP_PCI_IO_BAR
,
113 IXP1200_PCI_IO_BAR
& IXP_PCI_IO_BAR_MASK
);
115 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
, IXP_PCI_DRAM_BAR
,
116 IXP1200_PCI_DRAM_BAR
& IXP_PCI_DRAM_BAR_MASK
);
118 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
119 CSR_BASE_ADDR_MASK
, CSR_BASE_ADDR_MASK_1M
);
120 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
121 DRAM_BASE_ADDR_MASK
, DRAM_BASE_ADDR_MASK_256MB
);
124 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",
125 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, IXP_PCI_MEM_BAR
),
126 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, IXP_PCI_IO_BAR
),
127 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, IXP_PCI_DRAM_BAR
),
128 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, PCI_ADDR_EXT
),
129 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, CSR_BASE_ADDR_MASK
),
130 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, DRAM_BASE_ADDR_MASK
));
132 /* Initialize complete */
133 reg
= bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
135 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
138 printf("SA_CONTROL = 0x%08x\n",
139 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, SA_CONTROL
));
142 * Enable bus mastering and I/O,memory access
145 reg
= bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
146 PCI_COMMAND_STATUS_REG
) |
147 PCI_COMMAND_IO_ENABLE
| PCI_COMMAND_MEM_ENABLE
|
148 PCI_COMMAND_PARITY_ENABLE
| PCI_COMMAND_SERR_ENABLE
|
149 PCI_COMMAND_MASTER_ENABLE
| PCI_COMMAND_INVALIDATE_ENABLE
;
150 bus_space_write_4(sc
->sc_iot
, sc
->sc_pci_ioh
,
151 PCI_COMMAND_STATUS_REG
, reg
);
153 printf("PCI_COMMAND_STATUS_REG = 0x%08x\n",
154 bus_space_read_4(sc
->sc_iot
, sc
->sc_pci_ioh
, PCI_COMMAND_STATUS_REG
));
157 * Initialize the PCI chipset tag.
159 ixp12x0_pci_init(&sc
->ia_pci_chipset
, sc
);
162 * Initialize the DMA tags.
164 ixp12x0_pci_dma_init(sc
);
167 * Attach the PCI bus.
169 pba
.pba_pc
= &sc
->ia_pci_chipset
;
170 pba
.pba_iot
= &ixp12x0_bs_tag
;
171 pba
.pba_memt
= &ixp12x0_bs_tag
;
172 pba
.pba_dmat
= &sc
->ia_pci_dmat
;
173 pba
.pba_dmat64
= NULL
;
174 pba
.pba_bus
= 0; /* bus number = 0 */
175 pba
.pba_intrswiz
= 0; /* XXX */
177 pba
.pba_flags
= PCI_FLAGS_IO_ENABLED
| PCI_FLAGS_MEM_ENABLED
|
178 PCI_FLAGS_MRL_OKAY
| PCI_FLAGS_MRM_OKAY
| PCI_FLAGS_MWI_OKAY
;
179 (void) config_found_ia(&sc
->sc_dev
, "pcibus", &pba
, pcibusprint
);
185 bus_space_write_4(ixp12x0_softc
->sc_iot
, ixp12x0_softc
->sc_pci_ioh
,
186 IXPPCI_IXP1200_RESET
, RESET_FULL
);