xref: /netbsd-src/sys/arch/arm/xscale/becc.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*	$NetBSD: becc.c,v 1.18 2021/08/07 16:18:46 thorpej Exp $	*/
2b1b164a8Sthorpej 
3b1b164a8Sthorpej /*
4891be168Sthorpej  * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
5b1b164a8Sthorpej  * All rights reserved.
6b1b164a8Sthorpej  *
7b1b164a8Sthorpej  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8b1b164a8Sthorpej  *
9b1b164a8Sthorpej  * Redistribution and use in source and binary forms, with or without
10b1b164a8Sthorpej  * modification, are permitted provided that the following conditions
11b1b164a8Sthorpej  * are met:
12b1b164a8Sthorpej  * 1. Redistributions of source code must retain the above copyright
13b1b164a8Sthorpej  *    notice, this list of conditions and the following disclaimer.
14b1b164a8Sthorpej  * 2. Redistributions in binary form must reproduce the above copyright
15b1b164a8Sthorpej  *    notice, this list of conditions and the following disclaimer in the
16b1b164a8Sthorpej  *    documentation and/or other materials provided with the distribution.
17b1b164a8Sthorpej  * 3. All advertising materials mentioning features or use of this software
18b1b164a8Sthorpej  *    must display the following acknowledgement:
19b1b164a8Sthorpej  *	This product includes software developed for the NetBSD Project by
20b1b164a8Sthorpej  *	Wasabi Systems, Inc.
21b1b164a8Sthorpej  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22b1b164a8Sthorpej  *    or promote products derived from this software without specific prior
23b1b164a8Sthorpej  *    written permission.
24b1b164a8Sthorpej  *
25b1b164a8Sthorpej  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26b1b164a8Sthorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27b1b164a8Sthorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28b1b164a8Sthorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29b1b164a8Sthorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30b1b164a8Sthorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31b1b164a8Sthorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32b1b164a8Sthorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33b1b164a8Sthorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34b1b164a8Sthorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35b1b164a8Sthorpej  * POSSIBILITY OF SUCH DAMAGE.
36b1b164a8Sthorpej  */
37b1b164a8Sthorpej 
38b1b164a8Sthorpej /*
39b1b164a8Sthorpej  * Autoconfiguration support for the ADI Engineering Big Endian
40b1b164a8Sthorpej  * Companion Chip.
41b1b164a8Sthorpej  */
42b1b164a8Sthorpej 
4308716eaeSlukem #include <sys/cdefs.h>
44*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: becc.c,v 1.18 2021/08/07 16:18:46 thorpej Exp $");
4508716eaeSlukem 
46b1b164a8Sthorpej #include <sys/param.h>
47b1b164a8Sthorpej #include <sys/systm.h>
48b1b164a8Sthorpej #include <sys/device.h>
49b1b164a8Sthorpej 
50b1b164a8Sthorpej #define	_ARM32_BUS_DMA_PRIVATE
51ed9977b1Sdyoung #include <sys/bus.h>
52b1b164a8Sthorpej 
53b1b164a8Sthorpej #include <arm/xscale/i80200reg.h>
54b1b164a8Sthorpej #include <arm/xscale/beccreg.h>
55b1b164a8Sthorpej #include <arm/xscale/beccvar.h>
56b1b164a8Sthorpej 
57b1b164a8Sthorpej /*
58b1b164a8Sthorpej  * Virtual address at which the BECC is mapped.  This is filled in
59b1b164a8Sthorpej  * by machine-dependent code.
60b1b164a8Sthorpej  */
61b1b164a8Sthorpej vaddr_t becc_vaddr;
62b1b164a8Sthorpej 
63b1b164a8Sthorpej /*
64b1b164a8Sthorpej  * BECC revision number.  This is initialized by early bootstrap code.
65b1b164a8Sthorpej  */
66b1b164a8Sthorpej int becc_rev;
67b1b164a8Sthorpej const char *becc_revisions[] = {
68b1b164a8Sthorpej 	"<= 7",
69b1b164a8Sthorpej 	"8",
70b1b164a8Sthorpej 	">= 9",
71b1b164a8Sthorpej };
72b1b164a8Sthorpej 
73b1b164a8Sthorpej /*
74b1b164a8Sthorpej  * There can be only one BECC, so we keep a global pointer to
75b1b164a8Sthorpej  * the softc, so board-specific code can use features of the
76b1b164a8Sthorpej  * BECC without having to have a handle on the softc itself.
77b1b164a8Sthorpej  */
78b1b164a8Sthorpej struct becc_softc *becc_softc;
79b1b164a8Sthorpej 
80a2b8c7fbSmsaitoh static int becc_search(device_t, cfdata_t, const int *, void *);
81891be168Sthorpej static int becc_print(void *, const char *);
82891be168Sthorpej 
83b1b164a8Sthorpej static void becc_pci_dma_init(struct becc_softc *);
84891be168Sthorpej static void becc_local_dma_init(struct becc_softc *);
85b1b164a8Sthorpej 
86b1b164a8Sthorpej /*
87b1b164a8Sthorpej  * becc_attach:
88b1b164a8Sthorpej  *
89b1b164a8Sthorpej  *	Board-independent attach routine for the BECC.
90b1b164a8Sthorpej  */
91b1b164a8Sthorpej void
becc_attach(struct becc_softc * sc)92b1b164a8Sthorpej becc_attach(struct becc_softc *sc)
93b1b164a8Sthorpej {
94b1b164a8Sthorpej 	struct pcibus_attach_args pba;
95b1b164a8Sthorpej 	uint32_t reg;
96b1b164a8Sthorpej 
97b1b164a8Sthorpej 	becc_softc = sc;
98b1b164a8Sthorpej 
99b1b164a8Sthorpej 	/*
100b1b164a8Sthorpej 	 * Set the AF bit in the BCUMOD since the BECC will honor it.
101b1b164a8Sthorpej 	 * This allows the BECC to return the requested 4-byte word
102b1b164a8Sthorpej 	 * first when filling a cache line.
103b1b164a8Sthorpej 	 */
1045f1c88d7Sperry 	__asm volatile("mrc p13, 0, %0, c1, c1, 0" : "=r" (reg));
1055f1c88d7Sperry 	__asm volatile("mcr p13, 0, %0, c1, c1, 0" : : "r" (reg | BCUMOD_AF));
106b1b164a8Sthorpej 
107b1b164a8Sthorpej 	/*
108b1b164a8Sthorpej 	 * Program the address windows of the PCI core.  Note
109b1b164a8Sthorpej 	 * that PCI master and target cycles must be disabled
110b1b164a8Sthorpej 	 * while we configure the windows.
111b1b164a8Sthorpej 	 */
112b1b164a8Sthorpej 	reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG);
113b1b164a8Sthorpej 	reg &= ~(PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE);
114b1b164a8Sthorpej 	becc_pcicore_write(sc, PCI_COMMAND_STATUS_REG, reg);
115b1b164a8Sthorpej 
116b1b164a8Sthorpej 	/*
117b1b164a8Sthorpej 	 * Program the two inbound PCI memory windows.
118b1b164a8Sthorpej 	 */
119b1b164a8Sthorpej 	becc_pcicore_write(sc, PCI_MAPREG_START + 0,
120b1b164a8Sthorpej 	    sc->sc_iwin[0].iwin_base | PCI_MAPREG_MEM_TYPE_32BIT |
121b1b164a8Sthorpej 	    PCI_MAPREG_MEM_PREFETCHABLE_MASK);
122b1b164a8Sthorpej 	reg = becc_pcicore_read(sc, PCI_MAPREG_START + 0);
123b1b164a8Sthorpej 	BECC_CSR_WRITE(BECC_PSTR0, sc->sc_iwin[0].iwin_xlate & PSTRx_ADDRMASK);
124b1b164a8Sthorpej 
125b1b164a8Sthorpej 	becc_pcicore_write(sc, PCI_MAPREG_START + 4,
126b1b164a8Sthorpej 	    sc->sc_iwin[1].iwin_base | PCI_MAPREG_MEM_TYPE_32BIT |
127b1b164a8Sthorpej 	    PCI_MAPREG_MEM_PREFETCHABLE_MASK);
128b1b164a8Sthorpej 	reg = becc_pcicore_read(sc, PCI_MAPREG_START + 4);
129b1b164a8Sthorpej 	BECC_CSR_WRITE(BECC_PSTR1, sc->sc_iwin[1].iwin_xlate & PSTRx_ADDRMASK);
130b1b164a8Sthorpej 
131b1b164a8Sthorpej 	/*
132b1b164a8Sthorpej 	 * ...and the third on v8 and later.
133b1b164a8Sthorpej 	 */
134b1b164a8Sthorpej 	if (becc_rev >= BECC_REV_V8) {
135b1b164a8Sthorpej 		becc_pcicore_write(sc, PCI_MAPREG_START + 8,
136b1b164a8Sthorpej 		    sc->sc_iwin[2].iwin_base | PCI_MAPREG_MEM_TYPE_32BIT |
137b1b164a8Sthorpej 		    PCI_MAPREG_MEM_PREFETCHABLE_MASK);
138b1b164a8Sthorpej 		reg = becc_pcicore_read(sc, PCI_MAPREG_START + 8);
13914acc892Sthorpej 		BECC_CSR_WRITE(BECC_PSTR2,
140b1b164a8Sthorpej 		    sc->sc_iwin[2].iwin_xlate & PSTR2_ADDRMASK);
141b1b164a8Sthorpej 	}
142b1b164a8Sthorpej 
143b1b164a8Sthorpej 	/*
1446955d476Sthorpej 	 * Program the two outbound PCI memory windows.
1456955d476Sthorpej 	 * NOTE: WE DO NOT BYTE-SWAP OUTBOUND WINDOWS IN BIG-ENDIAN
1466955d476Sthorpej 	 * MODE.  I know this seems counter-intuitive, but that's
1476955d476Sthorpej 	 * how it is.
148b1b164a8Sthorpej 	 *
149b1b164a8Sthorpej 	 * There's a third window on v9 and later, but we don't
150b1b164a8Sthorpej 	 * use it for anything; program it anyway, just to be
151b1b164a8Sthorpej 	 * safe.
152b1b164a8Sthorpej 	 */
153b1b164a8Sthorpej 	BECC_CSR_WRITE(BECC_POMR1, sc->sc_owin_xlate[0] /* | POMRx_F32 */);
154b1b164a8Sthorpej 	BECC_CSR_WRITE(BECC_POMR2, sc->sc_owin_xlate[1] /* | POMRx_F32 */);
155b1b164a8Sthorpej 
156b1b164a8Sthorpej 	if (becc_rev >= BECC_REV_V9)
157b1b164a8Sthorpej 		BECC_CSR_WRITE(BECC_POMR3,
158b1b164a8Sthorpej 		    sc->sc_owin_xlate[2] /* | POMRx_F32 */);
159b1b164a8Sthorpej 
160b1b164a8Sthorpej 	/*
1616955d476Sthorpej 	 * Program the PCI I/O window.  See note above about byte-swapping.
162b1b164a8Sthorpej 	 *
163b1b164a8Sthorpej 	 * XXX What about STREAM transfers?
164b1b164a8Sthorpej 	 */
165b1b164a8Sthorpej 	BECC_CSR_WRITE(BECC_POIR, sc->sc_ioout_xlate);
166b1b164a8Sthorpej 
167b1b164a8Sthorpej 	/*
168b1b164a8Sthorpej 	 * Configure PCI configuration cycle access.
169b1b164a8Sthorpej 	 */
170b1b164a8Sthorpej 	BECC_CSR_WRITE(BECC_POCR, 0);
171b1b164a8Sthorpej 
172b1b164a8Sthorpej 	/*
173b1b164a8Sthorpej 	 * ...and now reenable PCI access.
174b1b164a8Sthorpej 	 */
175b1b164a8Sthorpej 	reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG);
176b1b164a8Sthorpej 	reg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE |
177b1b164a8Sthorpej 	    PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
178b1b164a8Sthorpej 	becc_pcicore_write(sc, PCI_COMMAND_STATUS_REG, reg);
179b1b164a8Sthorpej 
180b1b164a8Sthorpej 	/* Initialize the bus space tags. */
181b1b164a8Sthorpej 	becc_io_bs_init(&sc->sc_pci_iot, sc);
182b1b164a8Sthorpej 	becc_mem_bs_init(&sc->sc_pci_memt, sc);
183b1b164a8Sthorpej 
184b1b164a8Sthorpej 	/* Initialize the PCI chipset tag. */
185b1b164a8Sthorpej 	becc_pci_init(&sc->sc_pci_chipset, sc);
186b1b164a8Sthorpej 
187b1b164a8Sthorpej 	/* Initialize the DMA tags. */
188b1b164a8Sthorpej 	becc_pci_dma_init(sc);
189891be168Sthorpej 	becc_local_dma_init(sc);
190891be168Sthorpej 
191891be168Sthorpej 	/*
192891be168Sthorpej 	 * Attach any on-chip peripherals.  We used indirect config, since
193891be168Sthorpej 	 * the BECC is a soft-core with a variety of peripherals, depending
194891be168Sthorpej 	 * on configuration.
195891be168Sthorpej 	 */
1962685996bSthorpej 	config_search(sc->sc_dev, NULL,
197*c7fb772bSthorpej 	    CFARGS(.search = becc_search,
198*c7fb772bSthorpej 		   .iattr = "becc"));
199b1b164a8Sthorpej 
200b1b164a8Sthorpej 	/*
201b1b164a8Sthorpej 	 * Attach the PCI bus.
202b1b164a8Sthorpej 	 */
203b1b164a8Sthorpej 	pba.pba_iot = &sc->sc_pci_iot;
204b1b164a8Sthorpej 	pba.pba_memt = &sc->sc_pci_memt;
205b1b164a8Sthorpej 	pba.pba_dmat = &sc->sc_pci_dmat;
2067dd7f8baSfvdl 	pba.pba_dmat64 = NULL;
207b1b164a8Sthorpej 	pba.pba_pc = &sc->sc_pci_chipset;
208b1b164a8Sthorpej 	pba.pba_bus = 0;
209b1b164a8Sthorpej 	pba.pba_bridgetag = NULL;
210b1b164a8Sthorpej 	pba.pba_intrswiz = 0;
211b1b164a8Sthorpej 	pba.pba_intrtag = 0;
212a6b2b839Sdyoung 	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
213b1b164a8Sthorpej 	    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
2142685996bSthorpej 	config_found(sc->sc_dev, &pba, pcibusprint,
215*c7fb772bSthorpej 	    CFARGS(.iattr = "pcibus"));
216b1b164a8Sthorpej }
217b1b164a8Sthorpej 
218b1b164a8Sthorpej /*
219891be168Sthorpej  * becc_search:
220891be168Sthorpej  *
221891be168Sthorpej  *	Indirect autoconfiguration glue for BECC.
222891be168Sthorpej  */
223891be168Sthorpej static int
becc_search(device_t parent,cfdata_t cf,const int * ldesc,void * aux)224a2b8c7fbSmsaitoh becc_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
225891be168Sthorpej {
226a2b8c7fbSmsaitoh 	struct becc_softc *sc = device_private(parent);
227891be168Sthorpej 	struct becc_attach_args ba;
228891be168Sthorpej 
229891be168Sthorpej 	ba.ba_dmat = &sc->sc_local_dmat;
230891be168Sthorpej 
2312685996bSthorpej 	if (config_probe(parent, cf, &ba))
232*c7fb772bSthorpej 		config_attach(parent, cf, &ba, becc_print, CFARGS_NONE);
233891be168Sthorpej 
234891be168Sthorpej 	return (0);
235891be168Sthorpej }
236891be168Sthorpej 
237891be168Sthorpej /*
238891be168Sthorpej  * becc_print:
239891be168Sthorpej  *
240891be168Sthorpej  *	Autoconfiguration cfprint routine when attaching
241891be168Sthorpej  *	to the BECC.
242891be168Sthorpej  */
243891be168Sthorpej static int
becc_print(void * aux,const char * pnp)244891be168Sthorpej becc_print(void *aux, const char *pnp)
245891be168Sthorpej {
246891be168Sthorpej 
247891be168Sthorpej 	return (UNCONF);
248891be168Sthorpej }
249891be168Sthorpej 
250891be168Sthorpej /*
251b1b164a8Sthorpej  * becc_pci_dma_init:
252b1b164a8Sthorpej  *
253b1b164a8Sthorpej  *	Initialize the PCI DMA tag.
254b1b164a8Sthorpej  */
255b1b164a8Sthorpej static void
becc_pci_dma_init(struct becc_softc * sc)256b1b164a8Sthorpej becc_pci_dma_init(struct becc_softc *sc)
257b1b164a8Sthorpej {
258b1b164a8Sthorpej 	bus_dma_tag_t dmat = &sc->sc_pci_dmat;
259b1b164a8Sthorpej 	struct arm32_dma_range *dr = sc->sc_pci_dma_range;
260b1b164a8Sthorpej 	int i = 0;
261b1b164a8Sthorpej 
262b1b164a8Sthorpej 	/*
263b1b164a8Sthorpej 	 * If we have the 128MB window, put it first, since it
264b1b164a8Sthorpej 	 * will always cover the entire memory range.
265b1b164a8Sthorpej 	 */
266b1b164a8Sthorpej 	if (becc_rev >= BECC_REV_V8) {
267b1b164a8Sthorpej 		dr[i].dr_sysbase = sc->sc_iwin[2].iwin_xlate;
268b1b164a8Sthorpej 		dr[i].dr_busbase = sc->sc_iwin[2].iwin_base;
269b1b164a8Sthorpej 		dr[i].dr_len = (128U * 1024 * 1024);
270b1b164a8Sthorpej 		i++;
271b1b164a8Sthorpej 	}
272b1b164a8Sthorpej 
273b1b164a8Sthorpej 	dr[i].dr_sysbase = sc->sc_iwin[0].iwin_xlate;
274b1b164a8Sthorpej 	dr[i].dr_busbase = sc->sc_iwin[0].iwin_base;
275b1b164a8Sthorpej 	dr[i].dr_len = (32U * 1024 * 1024);
276b1b164a8Sthorpej 	i++;
277b1b164a8Sthorpej 
278b1b164a8Sthorpej 	dr[i].dr_sysbase = sc->sc_iwin[1].iwin_xlate;
279b1b164a8Sthorpej 	dr[i].dr_busbase = sc->sc_iwin[1].iwin_base;
280b1b164a8Sthorpej 	dr[i].dr_len = (32U * 1024 * 1024);
281b1b164a8Sthorpej 	i++;
282b1b164a8Sthorpej 
283b1b164a8Sthorpej 	dmat->_ranges = dr;
284b1b164a8Sthorpej 	dmat->_nranges = i;
285b1b164a8Sthorpej 
286b1b164a8Sthorpej 	dmat->_dmamap_create = _bus_dmamap_create;
287b1b164a8Sthorpej 	dmat->_dmamap_destroy = _bus_dmamap_destroy;
288b1b164a8Sthorpej 	dmat->_dmamap_load = _bus_dmamap_load;
289b1b164a8Sthorpej 	dmat->_dmamap_load_mbuf = _bus_dmamap_load_mbuf;
290b1b164a8Sthorpej 	dmat->_dmamap_load_uio = _bus_dmamap_load_uio;
291b1b164a8Sthorpej 	dmat->_dmamap_load_raw = _bus_dmamap_load_raw;
292b1b164a8Sthorpej 	dmat->_dmamap_unload = _bus_dmamap_unload;
293b1b164a8Sthorpej 	dmat->_dmamap_sync_pre = _bus_dmamap_sync;
294b1b164a8Sthorpej 	dmat->_dmamap_sync_post = NULL;
295b1b164a8Sthorpej 
296b1b164a8Sthorpej 	dmat->_dmamem_alloc = _bus_dmamem_alloc;
297b1b164a8Sthorpej 	dmat->_dmamem_free = _bus_dmamem_free;
298b1b164a8Sthorpej 	dmat->_dmamem_map = _bus_dmamem_map;
299b1b164a8Sthorpej 	dmat->_dmamem_unmap = _bus_dmamem_unmap;
300b1b164a8Sthorpej 	dmat->_dmamem_mmap = _bus_dmamem_mmap;
3014710b77fSmatt 
3024710b77fSmatt 	dmat->_dmatag_subregion = _bus_dmatag_subregion;
3034710b77fSmatt 	dmat->_dmatag_destroy = _bus_dmatag_destroy;
304b1b164a8Sthorpej }
305b1b164a8Sthorpej 
306891be168Sthorpej /*
307891be168Sthorpej  * becc_local_dma_init:
308891be168Sthorpej  *
309891be168Sthorpej  *	Initialize the local DMA tag.
310891be168Sthorpej  */
311891be168Sthorpej static void
becc_local_dma_init(struct becc_softc * sc)312891be168Sthorpej becc_local_dma_init(struct becc_softc *sc)
313891be168Sthorpej {
314891be168Sthorpej 	bus_dma_tag_t dmat = &sc->sc_local_dmat;
315891be168Sthorpej 
316891be168Sthorpej 	dmat->_ranges = NULL;
317891be168Sthorpej 	dmat->_nranges = 0;
318891be168Sthorpej 
319891be168Sthorpej 	dmat->_dmamap_create = _bus_dmamap_create;
320891be168Sthorpej 	dmat->_dmamap_destroy = _bus_dmamap_destroy;
321891be168Sthorpej 	dmat->_dmamap_load = _bus_dmamap_load;
322891be168Sthorpej 	dmat->_dmamap_load_mbuf = _bus_dmamap_load_mbuf;
323891be168Sthorpej 	dmat->_dmamap_load_uio = _bus_dmamap_load_uio;
324891be168Sthorpej 	dmat->_dmamap_load_raw = _bus_dmamap_load_raw;
325891be168Sthorpej 	dmat->_dmamap_unload = _bus_dmamap_unload;
326891be168Sthorpej 	dmat->_dmamap_sync_pre = _bus_dmamap_sync;
327891be168Sthorpej 	dmat->_dmamap_sync_post = NULL;
328891be168Sthorpej 
329891be168Sthorpej 	dmat->_dmamem_alloc = _bus_dmamem_alloc;
330891be168Sthorpej 	dmat->_dmamem_free = _bus_dmamem_free;
331891be168Sthorpej 	dmat->_dmamem_map = _bus_dmamem_map;
332891be168Sthorpej 	dmat->_dmamem_unmap = _bus_dmamem_unmap;
333891be168Sthorpej 	dmat->_dmamem_mmap = _bus_dmamem_mmap;
334891be168Sthorpej }
335891be168Sthorpej 
336b1b164a8Sthorpej uint32_t
becc_pcicore_read(struct becc_softc * sc,bus_addr_t reg)337b1b164a8Sthorpej becc_pcicore_read(struct becc_softc *sc, bus_addr_t reg)
338b1b164a8Sthorpej {
339b1b164a8Sthorpej 	vaddr_t va = sc->sc_pci_cfg_base | (1U << BECC_IDSEL_BIT) | reg;
340b1b164a8Sthorpej 
3415f1c88d7Sperry 	return (*(volatile uint32_t *) va);
342b1b164a8Sthorpej }
343b1b164a8Sthorpej 
344b1b164a8Sthorpej void
becc_pcicore_write(struct becc_softc * sc,bus_addr_t reg,uint32_t val)345b1b164a8Sthorpej becc_pcicore_write(struct becc_softc *sc, bus_addr_t reg, uint32_t val)
346b1b164a8Sthorpej {
347b1b164a8Sthorpej 	vaddr_t va = sc->sc_pci_cfg_base | (1U << BECC_IDSEL_BIT) | reg;
348b1b164a8Sthorpej 
3495f1c88d7Sperry 	*(volatile uint32_t *) va = val;
350b1b164a8Sthorpej }
351