1 /* $NetBSD: becc.c,v 1.11 2005/12/11 12:16:51 christos Exp $ */
4 * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
39 * Autoconfiguration support for the ADI Engineering Big Endian
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: becc.c,v 1.11 2005/12/11 12:16:51 christos Exp $");
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/device.h>
50 #define _ARM32_BUS_DMA_PRIVATE
51 #include <machine/bus.h>
53 #include <arm/xscale/i80200reg.h>
54 #include <arm/xscale/beccreg.h>
55 #include <arm/xscale/beccvar.h>
58 * Virtual address at which the BECC is mapped. This is filled in
59 * by machine-dependent code.
64 * BECC revision number. This is initialized by early bootstrap code.
67 const char *becc_revisions
[] = {
74 * There can be only one BECC, so we keep a global pointer to
75 * the softc, so board-specific code can use features of the
76 * BECC without having to have a handle on the softc itself.
78 struct becc_softc
*becc_softc
;
80 static int becc_search(struct device
*, struct cfdata
*,
82 static int becc_print(void *, const char *);
84 static void becc_pci_dma_init(struct becc_softc
*);
85 static void becc_local_dma_init(struct becc_softc
*);
90 * Board-independent attach routine for the BECC.
93 becc_attach(struct becc_softc
*sc
)
95 struct pcibus_attach_args pba
;
101 * Set the AF bit in the BCUMOD since the BECC will honor it.
102 * This allows the BECC to return the requested 4-byte word
103 * first when filling a cache line.
105 __asm
volatile("mrc p13, 0, %0, c1, c1, 0" : "=r" (reg
));
106 __asm
volatile("mcr p13, 0, %0, c1, c1, 0" : : "r" (reg
| BCUMOD_AF
));
109 * Program the address windows of the PCI core. Note
110 * that PCI master and target cycles must be disabled
111 * while we configure the windows.
113 reg
= becc_pcicore_read(sc
, PCI_COMMAND_STATUS_REG
);
114 reg
&= ~(PCI_COMMAND_MEM_ENABLE
|PCI_COMMAND_MASTER_ENABLE
);
115 becc_pcicore_write(sc
, PCI_COMMAND_STATUS_REG
, reg
);
118 * Program the two inbound PCI memory windows.
120 becc_pcicore_write(sc
, PCI_MAPREG_START
+ 0,
121 sc
->sc_iwin
[0].iwin_base
| PCI_MAPREG_MEM_TYPE_32BIT
|
122 PCI_MAPREG_MEM_PREFETCHABLE_MASK
);
123 reg
= becc_pcicore_read(sc
, PCI_MAPREG_START
+ 0);
124 BECC_CSR_WRITE(BECC_PSTR0
, sc
->sc_iwin
[0].iwin_xlate
& PSTRx_ADDRMASK
);
126 becc_pcicore_write(sc
, PCI_MAPREG_START
+ 4,
127 sc
->sc_iwin
[1].iwin_base
| PCI_MAPREG_MEM_TYPE_32BIT
|
128 PCI_MAPREG_MEM_PREFETCHABLE_MASK
);
129 reg
= becc_pcicore_read(sc
, PCI_MAPREG_START
+ 4);
130 BECC_CSR_WRITE(BECC_PSTR1
, sc
->sc_iwin
[1].iwin_xlate
& PSTRx_ADDRMASK
);
133 * ...and the third on v8 and later.
135 if (becc_rev
>= BECC_REV_V8
) {
136 becc_pcicore_write(sc
, PCI_MAPREG_START
+ 8,
137 sc
->sc_iwin
[2].iwin_base
| PCI_MAPREG_MEM_TYPE_32BIT
|
138 PCI_MAPREG_MEM_PREFETCHABLE_MASK
);
139 reg
= becc_pcicore_read(sc
, PCI_MAPREG_START
+ 8);
140 BECC_CSR_WRITE(BECC_PSTR2
,
141 sc
->sc_iwin
[2].iwin_xlate
& PSTR2_ADDRMASK
);
145 * Program the two outbound PCI memory windows.
146 * NOTE: WE DO NOT BYTE-SWAP OUTBOUND WINDOWS IN BIG-ENDIAN
147 * MODE. I know this seems counter-intuitive, but that's
150 * There's a third window on v9 and later, but we don't
151 * use it for anything; program it anyway, just to be
154 BECC_CSR_WRITE(BECC_POMR1
, sc
->sc_owin_xlate
[0] /* | POMRx_F32 */);
155 BECC_CSR_WRITE(BECC_POMR2
, sc
->sc_owin_xlate
[1] /* | POMRx_F32 */);
157 if (becc_rev
>= BECC_REV_V9
)
158 BECC_CSR_WRITE(BECC_POMR3
,
159 sc
->sc_owin_xlate
[2] /* | POMRx_F32 */);
162 * Program the PCI I/O window. See note above about byte-swapping.
164 * XXX What about STREAM transfers?
166 BECC_CSR_WRITE(BECC_POIR
, sc
->sc_ioout_xlate
);
169 * Configure PCI configuration cycle access.
171 BECC_CSR_WRITE(BECC_POCR
, 0);
174 * ...and now reenable PCI access.
176 reg
= becc_pcicore_read(sc
, PCI_COMMAND_STATUS_REG
);
177 reg
|= PCI_COMMAND_MEM_ENABLE
| PCI_COMMAND_MASTER_ENABLE
|
178 PCI_COMMAND_PARITY_ENABLE
| PCI_COMMAND_SERR_ENABLE
;
179 becc_pcicore_write(sc
, PCI_COMMAND_STATUS_REG
, reg
);
181 /* Initialize the bus space tags. */
182 becc_io_bs_init(&sc
->sc_pci_iot
, sc
);
183 becc_mem_bs_init(&sc
->sc_pci_memt
, sc
);
185 /* Initialize the PCI chipset tag. */
186 becc_pci_init(&sc
->sc_pci_chipset
, sc
);
188 /* Initialize the DMA tags. */
189 becc_pci_dma_init(sc
);
190 becc_local_dma_init(sc
);
193 * Attach any on-chip peripherals. We used indirect config, since
194 * the BECC is a soft-core with a variety of peripherals, depending
197 config_search_ia(becc_search
, &sc
->sc_dev
, "becc", NULL
);
200 * Attach the PCI bus.
202 pba
.pba_iot
= &sc
->sc_pci_iot
;
203 pba
.pba_memt
= &sc
->sc_pci_memt
;
204 pba
.pba_dmat
= &sc
->sc_pci_dmat
;
205 pba
.pba_dmat64
= NULL
;
206 pba
.pba_pc
= &sc
->sc_pci_chipset
;
208 pba
.pba_bridgetag
= NULL
;
209 pba
.pba_intrswiz
= 0;
211 pba
.pba_flags
= PCI_FLAGS_IO_ENABLED
| PCI_FLAGS_MEM_ENABLED
|
212 PCI_FLAGS_MRL_OKAY
| PCI_FLAGS_MRM_OKAY
| PCI_FLAGS_MWI_OKAY
;
213 (void) config_found_ia(&sc
->sc_dev
, "pcibus", &pba
, pcibusprint
);
219 * Indirect autoconfiguration glue for BECC.
222 becc_search(struct device
*parent
, struct cfdata
*cf
,
223 const int *ldesc
, void *aux
)
225 struct becc_softc
*sc
= (void *) parent
;
226 struct becc_attach_args ba
;
228 ba
.ba_dmat
= &sc
->sc_local_dmat
;
230 if (config_match(parent
, cf
, &ba
) > 0)
231 config_attach(parent
, cf
, &ba
, becc_print
);
239 * Autoconfiguration cfprint routine when attaching
243 becc_print(void *aux
, const char *pnp
)
252 * Initialize the PCI DMA tag.
255 becc_pci_dma_init(struct becc_softc
*sc
)
257 bus_dma_tag_t dmat
= &sc
->sc_pci_dmat
;
258 struct arm32_dma_range
*dr
= sc
->sc_pci_dma_range
;
262 * If we have the 128MB window, put it first, since it
263 * will always cover the entire memory range.
265 if (becc_rev
>= BECC_REV_V8
) {
266 dr
[i
].dr_sysbase
= sc
->sc_iwin
[2].iwin_xlate
;
267 dr
[i
].dr_busbase
= sc
->sc_iwin
[2].iwin_base
;
268 dr
[i
].dr_len
= (128U * 1024 * 1024);
272 dr
[i
].dr_sysbase
= sc
->sc_iwin
[0].iwin_xlate
;
273 dr
[i
].dr_busbase
= sc
->sc_iwin
[0].iwin_base
;
274 dr
[i
].dr_len
= (32U * 1024 * 1024);
277 dr
[i
].dr_sysbase
= sc
->sc_iwin
[1].iwin_xlate
;
278 dr
[i
].dr_busbase
= sc
->sc_iwin
[1].iwin_base
;
279 dr
[i
].dr_len
= (32U * 1024 * 1024);
285 dmat
->_dmamap_create
= _bus_dmamap_create
;
286 dmat
->_dmamap_destroy
= _bus_dmamap_destroy
;
287 dmat
->_dmamap_load
= _bus_dmamap_load
;
288 dmat
->_dmamap_load_mbuf
= _bus_dmamap_load_mbuf
;
289 dmat
->_dmamap_load_uio
= _bus_dmamap_load_uio
;
290 dmat
->_dmamap_load_raw
= _bus_dmamap_load_raw
;
291 dmat
->_dmamap_unload
= _bus_dmamap_unload
;
292 dmat
->_dmamap_sync_pre
= _bus_dmamap_sync
;
293 dmat
->_dmamap_sync_post
= NULL
;
295 dmat
->_dmamem_alloc
= _bus_dmamem_alloc
;
296 dmat
->_dmamem_free
= _bus_dmamem_free
;
297 dmat
->_dmamem_map
= _bus_dmamem_map
;
298 dmat
->_dmamem_unmap
= _bus_dmamem_unmap
;
299 dmat
->_dmamem_mmap
= _bus_dmamem_mmap
;
303 * becc_local_dma_init:
305 * Initialize the local DMA tag.
308 becc_local_dma_init(struct becc_softc
*sc
)
310 bus_dma_tag_t dmat
= &sc
->sc_local_dmat
;
312 dmat
->_ranges
= NULL
;
315 dmat
->_dmamap_create
= _bus_dmamap_create
;
316 dmat
->_dmamap_destroy
= _bus_dmamap_destroy
;
317 dmat
->_dmamap_load
= _bus_dmamap_load
;
318 dmat
->_dmamap_load_mbuf
= _bus_dmamap_load_mbuf
;
319 dmat
->_dmamap_load_uio
= _bus_dmamap_load_uio
;
320 dmat
->_dmamap_load_raw
= _bus_dmamap_load_raw
;
321 dmat
->_dmamap_unload
= _bus_dmamap_unload
;
322 dmat
->_dmamap_sync_pre
= _bus_dmamap_sync
;
323 dmat
->_dmamap_sync_post
= NULL
;
325 dmat
->_dmamem_alloc
= _bus_dmamem_alloc
;
326 dmat
->_dmamem_free
= _bus_dmamem_free
;
327 dmat
->_dmamem_map
= _bus_dmamem_map
;
328 dmat
->_dmamem_unmap
= _bus_dmamem_unmap
;
329 dmat
->_dmamem_mmap
= _bus_dmamem_mmap
;
333 becc_pcicore_read(struct becc_softc
*sc
, bus_addr_t reg
)
335 vaddr_t va
= sc
->sc_pci_cfg_base
| (1U << BECC_IDSEL_BIT
) | reg
;
337 return (*(volatile uint32_t *) va
);
341 becc_pcicore_write(struct becc_softc
*sc
, bus_addr_t reg
, uint32_t val
)
343 vaddr_t va
= sc
->sc_pci_cfg_base
| (1U << BECC_IDSEL_BIT
) | reg
;
345 *(volatile uint32_t *) va
= val
;