1*54816b7eSmacallan /* $NetBSD: i80321_space.c,v 1.18 2018/11/21 19:03:18 macallan Exp $ */
2f5362116Sthorpej
3f5362116Sthorpej /*
4f5362116Sthorpej * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
5f5362116Sthorpej * All rights reserved.
6f5362116Sthorpej *
7f5362116Sthorpej * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8f5362116Sthorpej *
9f5362116Sthorpej * Redistribution and use in source and binary forms, with or without
10f5362116Sthorpej * modification, are permitted provided that the following conditions
11f5362116Sthorpej * are met:
12f5362116Sthorpej * 1. Redistributions of source code must retain the above copyright
13f5362116Sthorpej * notice, this list of conditions and the following disclaimer.
14f5362116Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
15f5362116Sthorpej * notice, this list of conditions and the following disclaimer in the
16f5362116Sthorpej * documentation and/or other materials provided with the distribution.
17f5362116Sthorpej * 3. All advertising materials mentioning features or use of this software
18f5362116Sthorpej * must display the following acknowledgement:
19f5362116Sthorpej * This product includes software developed for the NetBSD Project by
20f5362116Sthorpej * Wasabi Systems, Inc.
21f5362116Sthorpej * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22f5362116Sthorpej * or promote products derived from this software without specific prior
23f5362116Sthorpej * written permission.
24f5362116Sthorpej *
25f5362116Sthorpej * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26f5362116Sthorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27f5362116Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28f5362116Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29f5362116Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30f5362116Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31f5362116Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32f5362116Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33f5362116Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34f5362116Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35f5362116Sthorpej * POSSIBILITY OF SUCH DAMAGE.
36f5362116Sthorpej */
37f5362116Sthorpej
38f5362116Sthorpej /*
39f5362116Sthorpej * bus_space functions for i80321 I/O Processor.
40f5362116Sthorpej */
41f5362116Sthorpej
4208716eaeSlukem #include <sys/cdefs.h>
43*54816b7eSmacallan __KERNEL_RCSID(0, "$NetBSD: i80321_space.c,v 1.18 2018/11/21 19:03:18 macallan Exp $");
4408716eaeSlukem
45f5362116Sthorpej #include <sys/param.h>
46f5362116Sthorpej #include <sys/systm.h>
47f5362116Sthorpej
48f5362116Sthorpej #include <uvm/uvm_extern.h>
49f5362116Sthorpej
50ed9977b1Sdyoung #include <sys/bus.h>
51f5362116Sthorpej
52f5362116Sthorpej #include <arm/xscale/i80321reg.h>
53f5362116Sthorpej #include <arm/xscale/i80321var.h>
54f5362116Sthorpej
55392aeaadSgavan #include "opt_i80321.h"
56392aeaadSgavan
57f5362116Sthorpej /* Prototypes for all the bus_space structure functions */
58f5362116Sthorpej bs_protos(i80321);
59f5362116Sthorpej bs_protos(i80321_io);
60f5362116Sthorpej bs_protos(i80321_mem);
6180146a51Sthorpej bs_protos(generic);
6280146a51Sthorpej bs_protos(generic_armv4);
63f5362116Sthorpej bs_protos(bs_notimpl);
64f5362116Sthorpej
65f5362116Sthorpej /*
66f5362116Sthorpej * Template bus_space -- copied, and the bits that are NULL are
67f5362116Sthorpej * filled in.
68f5362116Sthorpej */
69f5362116Sthorpej const struct bus_space i80321_bs_tag_template = {
70f5362116Sthorpej /* cookie */
71509197b6Sryo .bs_cookie = (void *) 0,
72f5362116Sthorpej
73f5362116Sthorpej /* mapping/unmapping */
74509197b6Sryo .bs_map = NULL,
75509197b6Sryo .bs_unmap = NULL,
76509197b6Sryo .bs_subregion = i80321_bs_subregion,
77f5362116Sthorpej
78f5362116Sthorpej /* allocation/deallocation */
79509197b6Sryo .bs_alloc = NULL,
80509197b6Sryo .bs_free = NULL,
81f5362116Sthorpej
82f5362116Sthorpej /* get kernel virtual address */
83509197b6Sryo .bs_vaddr = i80321_bs_vaddr,
84f5362116Sthorpej
85f5362116Sthorpej /* mmap */
86509197b6Sryo .bs_mmap = i80321_bs_mmap,
87f5362116Sthorpej
88f5362116Sthorpej /* barrier */
89509197b6Sryo .bs_barrier = i80321_bs_barrier,
90f5362116Sthorpej
91f5362116Sthorpej /* read (single) */
92509197b6Sryo .bs_r_1 = generic_bs_r_1,
93509197b6Sryo .bs_r_2 = generic_armv4_bs_r_2,
94509197b6Sryo .bs_r_4 = generic_bs_r_4,
95509197b6Sryo .bs_r_8 = bs_notimpl_bs_r_8,
96f5362116Sthorpej
9760617b8eSmacallan #ifdef __BUS_SPACE_HAS_STREAM_METHODS
9860617b8eSmacallan /* read (single, stream) */
9960617b8eSmacallan .bs_r_1_s = generic_bs_r_1,
10060617b8eSmacallan .bs_r_2_s = generic_armv4_bs_r_2,
10160617b8eSmacallan .bs_r_4_s = generic_bs_r_4,
10260617b8eSmacallan .bs_r_8_s = bs_notimpl_bs_r_8,
10360617b8eSmacallan #endif
10460617b8eSmacallan
105f5362116Sthorpej /* read multiple */
106509197b6Sryo .bs_rm_1 = generic_bs_rm_1,
107509197b6Sryo .bs_rm_2 = generic_armv4_bs_rm_2,
108509197b6Sryo .bs_rm_4 = generic_bs_rm_4,
109509197b6Sryo .bs_rm_8 = bs_notimpl_bs_rm_8,
110f5362116Sthorpej
11160617b8eSmacallan #ifdef __BUS_SPACE_HAS_STREAM_METHODS
11260617b8eSmacallan /* read multiple, stream */
11360617b8eSmacallan .bs_rm_1_s = generic_bs_rm_1,
11460617b8eSmacallan .bs_rm_2_s = generic_armv4_bs_rm_2,
11560617b8eSmacallan .bs_rm_4_s = generic_bs_rm_4,
11660617b8eSmacallan .bs_rm_8_s = bs_notimpl_bs_rm_8,
11760617b8eSmacallan #endif
11860617b8eSmacallan
119f5362116Sthorpej /* read region */
120509197b6Sryo .bs_rr_1 = generic_bs_rr_1,
121509197b6Sryo .bs_rr_2 = generic_armv4_bs_rr_2,
122509197b6Sryo .bs_rr_4 = generic_bs_rr_4,
123509197b6Sryo .bs_rr_8 = bs_notimpl_bs_rr_8,
124f5362116Sthorpej
12560617b8eSmacallan #ifdef __BUS_SPACE_HAS_STREAM_METHODS
12660617b8eSmacallan /* read region, stream */
12760617b8eSmacallan .bs_rr_1_s = generic_bs_rr_1,
12860617b8eSmacallan .bs_rr_2_s = generic_armv4_bs_rr_2,
12960617b8eSmacallan .bs_rr_4_s = generic_bs_rr_4,
13060617b8eSmacallan .bs_rr_8_s = bs_notimpl_bs_rr_8,
13160617b8eSmacallan #endif
13260617b8eSmacallan
133f5362116Sthorpej /* write (single) */
134509197b6Sryo .bs_w_1 = generic_bs_w_1,
135509197b6Sryo .bs_w_2 = generic_armv4_bs_w_2,
136509197b6Sryo .bs_w_4 = generic_bs_w_4,
137509197b6Sryo .bs_w_8 = bs_notimpl_bs_w_8,
138f5362116Sthorpej
13960617b8eSmacallan #ifdef __BUS_SPACE_HAS_STREAM_METHODS
14060617b8eSmacallan /* write (single, stream) */
14160617b8eSmacallan .bs_w_1_s = generic_bs_w_1,
14260617b8eSmacallan .bs_w_2_s = generic_armv4_bs_w_2,
14360617b8eSmacallan .bs_w_4_s = generic_bs_w_4,
14460617b8eSmacallan .bs_w_8_s = bs_notimpl_bs_w_8,
14560617b8eSmacallan #endif
14660617b8eSmacallan
147f5362116Sthorpej /* write multiple */
148509197b6Sryo .bs_wm_1 = generic_bs_wm_1,
149509197b6Sryo .bs_wm_2 = generic_armv4_bs_wm_2,
150509197b6Sryo .bs_wm_4 = generic_bs_wm_4,
151509197b6Sryo .bs_wm_8 = bs_notimpl_bs_wm_8,
152f5362116Sthorpej
15360617b8eSmacallan #ifdef __BUS_SPACE_HAS_STREAM_METHODS
15460617b8eSmacallan /* write multiple, stream */
15560617b8eSmacallan .bs_wm_1_s = generic_bs_wm_1,
15660617b8eSmacallan .bs_wm_2_s = generic_armv4_bs_wm_2,
15760617b8eSmacallan .bs_wm_4_s = generic_bs_wm_4,
15860617b8eSmacallan .bs_wm_8_s = bs_notimpl_bs_wm_8,
15960617b8eSmacallan #endif
16060617b8eSmacallan
161f5362116Sthorpej /* write region */
162509197b6Sryo .bs_wr_1 = generic_bs_wr_1,
163509197b6Sryo .bs_wr_2 = generic_armv4_bs_wr_2,
164509197b6Sryo .bs_wr_4 = generic_bs_wr_4,
165509197b6Sryo .bs_wr_8 = bs_notimpl_bs_wr_8,
166f5362116Sthorpej
16760617b8eSmacallan #ifdef __BUS_SPACE_HAS_STREAM_METHODS
16860617b8eSmacallan /* write region, stream */
16960617b8eSmacallan .bs_wr_1_s = generic_bs_wr_1,
17060617b8eSmacallan .bs_wr_2_s = generic_armv4_bs_wr_2,
17160617b8eSmacallan .bs_wr_4_s = generic_bs_wr_4,
17260617b8eSmacallan .bs_wr_8_s = bs_notimpl_bs_wr_8,
17360617b8eSmacallan #endif
17460617b8eSmacallan
175f5362116Sthorpej /* set multiple */
176509197b6Sryo .bs_sm_1 = bs_notimpl_bs_sm_1,
177509197b6Sryo .bs_sm_2 = bs_notimpl_bs_sm_2,
178509197b6Sryo .bs_sm_4 = bs_notimpl_bs_sm_4,
179509197b6Sryo .bs_sm_8 = bs_notimpl_bs_sm_8,
180f5362116Sthorpej
181f5362116Sthorpej /* set region */
182509197b6Sryo .bs_sr_1 = bs_notimpl_bs_sr_1,
183509197b6Sryo .bs_sr_2 = generic_armv4_bs_sr_2,
184509197b6Sryo .bs_sr_4 = generic_bs_sr_4,
185509197b6Sryo .bs_sr_8 = bs_notimpl_bs_sr_8,
186f5362116Sthorpej
187f5362116Sthorpej /* copy */
188509197b6Sryo .bs_c_1 = bs_notimpl_bs_c_1,
189509197b6Sryo .bs_c_2 = generic_armv4_bs_c_2,
190509197b6Sryo .bs_c_4 = bs_notimpl_bs_c_4,
191509197b6Sryo .bs_c_8 = bs_notimpl_bs_c_8,
192f5362116Sthorpej };
193f5362116Sthorpej
194f5362116Sthorpej void
i80321_bs_init(bus_space_tag_t bs,void * cookie)195f5362116Sthorpej i80321_bs_init(bus_space_tag_t bs, void *cookie)
196f5362116Sthorpej {
197f5362116Sthorpej
198f5362116Sthorpej *bs = i80321_bs_tag_template;
199f5362116Sthorpej bs->bs_cookie = cookie;
200f5362116Sthorpej }
201f5362116Sthorpej
202f5362116Sthorpej void
i80321_io_bs_init(bus_space_tag_t bs,void * cookie)203f5362116Sthorpej i80321_io_bs_init(bus_space_tag_t bs, void *cookie)
204f5362116Sthorpej {
205f5362116Sthorpej
206f5362116Sthorpej *bs = i80321_bs_tag_template;
207f5362116Sthorpej bs->bs_cookie = cookie;
208f5362116Sthorpej
209f5362116Sthorpej bs->bs_map = i80321_io_bs_map;
210f5362116Sthorpej bs->bs_unmap = i80321_io_bs_unmap;
211f5362116Sthorpej bs->bs_alloc = i80321_io_bs_alloc;
212f5362116Sthorpej bs->bs_free = i80321_io_bs_free;
213f5362116Sthorpej
214f5362116Sthorpej bs->bs_vaddr = i80321_io_bs_vaddr;
21560617b8eSmacallan bs->bs_mmap = i80321_io_bs_mmap;
216f5362116Sthorpej }
217f5362116Sthorpej
218f5362116Sthorpej void
i80321_mem_bs_init(bus_space_tag_t bs,void * cookie)219f5362116Sthorpej i80321_mem_bs_init(bus_space_tag_t bs, void *cookie)
220f5362116Sthorpej {
221f5362116Sthorpej
222f5362116Sthorpej *bs = i80321_bs_tag_template;
223f5362116Sthorpej bs->bs_cookie = cookie;
224f5362116Sthorpej
225f5362116Sthorpej bs->bs_map = i80321_mem_bs_map;
226f5362116Sthorpej bs->bs_unmap = i80321_mem_bs_unmap;
227f5362116Sthorpej bs->bs_alloc = i80321_mem_bs_alloc;
228f5362116Sthorpej bs->bs_free = i80321_mem_bs_free;
229f5362116Sthorpej bs->bs_mmap = i80321_mem_bs_mmap;
230f5362116Sthorpej }
231f5362116Sthorpej
232f5362116Sthorpej /* *** Routines shared by i80321, PCI IO, and PCI MEM. *** */
233f5362116Sthorpej
234f5362116Sthorpej int
i80321_bs_subregion(void * t,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size,bus_space_handle_t * nbshp)235f5362116Sthorpej i80321_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
236f5362116Sthorpej bus_size_t size, bus_space_handle_t *nbshp)
237f5362116Sthorpej {
238f5362116Sthorpej
239f5362116Sthorpej *nbshp = bsh + offset;
240f5362116Sthorpej return (0);
241f5362116Sthorpej }
242f5362116Sthorpej
243f5362116Sthorpej void
i80321_bs_barrier(void * t,bus_space_handle_t bsh,bus_size_t offset,bus_size_t len,int flags)244f5362116Sthorpej i80321_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
245f5362116Sthorpej bus_size_t len, int flags)
246f5362116Sthorpej {
247f5362116Sthorpej
248f5362116Sthorpej /* Nothing to do. */
249f5362116Sthorpej }
250f5362116Sthorpej
251f5362116Sthorpej void *
i80321_bs_vaddr(void * t,bus_space_handle_t bsh)252f5362116Sthorpej i80321_bs_vaddr(void *t, bus_space_handle_t bsh)
253f5362116Sthorpej {
254f5362116Sthorpej
255f5362116Sthorpej return ((void *)bsh);
256f5362116Sthorpej }
257f5362116Sthorpej
258f5362116Sthorpej paddr_t
i80321_bs_mmap(void * t,bus_addr_t addr,off_t off,int prot,int flags)259f5362116Sthorpej i80321_bs_mmap(void *t, bus_addr_t addr, off_t off, int prot, int flags)
260f5362116Sthorpej {
261f5362116Sthorpej
262f5362116Sthorpej /* Not supported. */
263f5362116Sthorpej return (-1);
264f5362116Sthorpej }
265f5362116Sthorpej
266f5362116Sthorpej /* *** Routines for PCI IO. *** */
267f5362116Sthorpej
268f5362116Sthorpej int
i80321_io_bs_map(void * t,bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)269f5362116Sthorpej i80321_io_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
270f5362116Sthorpej bus_space_handle_t *bshp)
271f5362116Sthorpej {
272f5362116Sthorpej struct i80321_softc *sc = t;
273f5362116Sthorpej vaddr_t winvaddr;
274f5362116Sthorpej uint32_t busbase;
275f5362116Sthorpej
276f5362116Sthorpej if (bpa >= sc->sc_ioout_xlate &&
277f5362116Sthorpej bpa < (sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE)) {
278f5362116Sthorpej busbase = sc->sc_ioout_xlate;
279f5362116Sthorpej winvaddr = sc->sc_iow_vaddr;
280f5362116Sthorpej } else
281f5362116Sthorpej return (EINVAL);
282f5362116Sthorpej
283f5362116Sthorpej if ((bpa + size) >= (busbase + VERDE_OUT_XLATE_IO_WIN_SIZE))
284f5362116Sthorpej return (EINVAL);
285f5362116Sthorpej
286f5362116Sthorpej /*
287f5362116Sthorpej * Found the window -- PCI I/O space is mapped at a fixed
288f5362116Sthorpej * virtual address by board-specific code. Translate the
289f5362116Sthorpej * bus address to the virtual address.
290f5362116Sthorpej */
291f5362116Sthorpej *bshp = winvaddr + (bpa - busbase);
292f5362116Sthorpej
293f5362116Sthorpej return (0);
294f5362116Sthorpej }
295f5362116Sthorpej
29660617b8eSmacallan paddr_t
i80321_io_bs_mmap(void * t,bus_addr_t addr,off_t off,int prot,int flags)29760617b8eSmacallan i80321_io_bs_mmap(void *t, bus_addr_t addr, off_t off, int prot, int flags)
29860617b8eSmacallan {
29960617b8eSmacallan struct i80321_softc *sc = t;
30060617b8eSmacallan paddr_t bpa = addr + off, winpaddr, busbase;
30160617b8eSmacallan
30260617b8eSmacallan if (bpa >= sc->sc_ioout_xlate &&
30360617b8eSmacallan bpa < (sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE)) {
30460617b8eSmacallan busbase = sc->sc_ioout_xlate;
30560617b8eSmacallan winpaddr = VERDE_OUT_XLATE_IO_WIN0_BASE;
30660617b8eSmacallan } else
30731997526Sthorpej return (-1);
30860617b8eSmacallan
30960617b8eSmacallan return (arm_btop(winpaddr + (bpa - busbase)));
31060617b8eSmacallan }
31160617b8eSmacallan
312f5362116Sthorpej void
i80321_io_bs_unmap(void * t,bus_space_handle_t bsh,bus_size_t size)313f5362116Sthorpej i80321_io_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
314f5362116Sthorpej {
315f5362116Sthorpej
316f5362116Sthorpej /* Nothing to do. */
317f5362116Sthorpej }
318f5362116Sthorpej
319f5362116Sthorpej int
i80321_io_bs_alloc(void * t,bus_addr_t rstart,bus_addr_t rend,bus_size_t size,bus_size_t alignment,bus_size_t boundary,int flags,bus_addr_t * bpap,bus_space_handle_t * bshp)320f5362116Sthorpej i80321_io_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
321f5362116Sthorpej bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
322f5362116Sthorpej bus_addr_t *bpap, bus_space_handle_t *bshp)
323f5362116Sthorpej {
324f5362116Sthorpej
3250f09ed48Sprovos panic("i80321_io_bs_alloc(): not implemented");
326f5362116Sthorpej }
327f5362116Sthorpej
328f5362116Sthorpej void
i80321_io_bs_free(void * t,bus_space_handle_t bsh,bus_size_t size)329f5362116Sthorpej i80321_io_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
330f5362116Sthorpej {
331f5362116Sthorpej
3320f09ed48Sprovos panic("i80321_io_bs_free(): not implemented");
333f5362116Sthorpej }
334f5362116Sthorpej
335f5362116Sthorpej void *
i80321_io_bs_vaddr(void * t,bus_space_handle_t bsh)336f5362116Sthorpej i80321_io_bs_vaddr(void *t, bus_space_handle_t bsh)
337f5362116Sthorpej {
338f5362116Sthorpej
339f5362116Sthorpej /* Not supported. */
340f5362116Sthorpej return (NULL);
341f5362116Sthorpej }
342f5362116Sthorpej
343f5362116Sthorpej /* *** Routines for PCI MEM. *** */
344f5362116Sthorpej
345f5362116Sthorpej int
i80321_mem_bs_map(void * t,bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)346f5362116Sthorpej i80321_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
347f5362116Sthorpej bus_space_handle_t *bshp)
348f5362116Sthorpej {
349f5362116Sthorpej
350392aeaadSgavan #ifndef I80321_USE_DIRECT_WIN
351f5362116Sthorpej struct i80321_softc *sc = t;
352392aeaadSgavan #endif
353f5362116Sthorpej vaddr_t va;
354f5362116Sthorpej uint32_t busbase;
355f5362116Sthorpej paddr_t pa, endpa, physbase;
356f5362116Sthorpej
357392aeaadSgavan #ifdef I80321_USE_DIRECT_WIN
3586eb573f0Sjoerg if (
3596eb573f0Sjoerg #if VERDE_OUT_DIRECT_WIN_BASE != 0
3606eb573f0Sjoerg bpa >= (VERDE_OUT_DIRECT_WIN_BASE) &&
3616eb573f0Sjoerg #endif
362392aeaadSgavan bpa < (VERDE_OUT_DIRECT_WIN_BASE + VERDE_OUT_DIRECT_WIN_SIZE)) {
363392aeaadSgavan busbase = VERDE_OUT_DIRECT_WIN_BASE;
364392aeaadSgavan physbase = VERDE_OUT_DIRECT_WIN_BASE;
365392aeaadSgavan } else
366392aeaadSgavan return (EINVAL);
367392aeaadSgavan if ((bpa + size) >= (VERDE_OUT_DIRECT_WIN_BASE +
368392aeaadSgavan VERDE_OUT_DIRECT_WIN_SIZE))
369392aeaadSgavan return (EINVAL);
370392aeaadSgavan #else
371f5362116Sthorpej if (bpa >= sc->sc_owin[0].owin_xlate_lo &&
372f5362116Sthorpej bpa < (sc->sc_owin[0].owin_xlate_lo +
373f5362116Sthorpej VERDE_OUT_XLATE_MEM_WIN_SIZE)) {
374f5362116Sthorpej busbase = sc->sc_owin[0].owin_xlate_lo;
375f5362116Sthorpej physbase = sc->sc_iwin[1].iwin_xlate;
376f5362116Sthorpej } else
377f5362116Sthorpej return (EINVAL);
378f5362116Sthorpej
379f5362116Sthorpej if ((bpa + size) >= (busbase + VERDE_OUT_XLATE_MEM_WIN_SIZE))
380f5362116Sthorpej return (EINVAL);
381392aeaadSgavan #endif
382f5362116Sthorpej
383f5362116Sthorpej /*
384952a515dSskrll * Found the window -- PCI MEM space is now mapped by allocating
385f5362116Sthorpej * some kernel VA space and mapping the pages with pmap_enter().
386f5362116Sthorpej * pmap_enter() will map unmanaged pages as non-cacheable.
387f5362116Sthorpej */
388f5362116Sthorpej pa = trunc_page((bpa - busbase) + physbase);
389f5362116Sthorpej endpa = round_page(((bpa - busbase) + physbase) + size);
390f5362116Sthorpej
391bc21da4cSyamt va = uvm_km_alloc(kernel_map, endpa - pa, 0,
392bc21da4cSyamt UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
393f5362116Sthorpej if (va == 0)
394f5362116Sthorpej return (ENOMEM);
395f5362116Sthorpej
396f5362116Sthorpej *bshp = va + (bpa & PAGE_MASK);
397f5362116Sthorpej
398f5362116Sthorpej for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
399f5362116Sthorpej pmap_enter(pmap_kernel(), va, pa,
400df011fdaSthorpej VM_PROT_READ | VM_PROT_WRITE,
40160617b8eSmacallan VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED |
40260617b8eSmacallan ((flags & BUS_SPACE_MAP_PREFETCHABLE) ?
40360617b8eSmacallan ARM_MMAP_WRITECOMBINE : 0));
404f5362116Sthorpej }
405f5362116Sthorpej pmap_update(pmap_kernel());
406f5362116Sthorpej
407f5362116Sthorpej return (0);
408f5362116Sthorpej }
409f5362116Sthorpej
410f5362116Sthorpej void
i80321_mem_bs_unmap(void * t,bus_space_handle_t bsh,bus_size_t size)411f5362116Sthorpej i80321_mem_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
412f5362116Sthorpej {
413f5362116Sthorpej vaddr_t va, endva;
414f5362116Sthorpej
415f5362116Sthorpej va = trunc_page(bsh);
416f5362116Sthorpej endva = round_page(bsh + size);
417f5362116Sthorpej
4186b2d8b66Syamt pmap_remove(pmap_kernel(), va, endva - va);
4196b2d8b66Syamt pmap_update(pmap_kernel());
4206b2d8b66Syamt
421f5362116Sthorpej /* Free the kernel virtual mapping. */
4226b2d8b66Syamt uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
423f5362116Sthorpej }
424f5362116Sthorpej
425f5362116Sthorpej int
i80321_mem_bs_alloc(void * t,bus_addr_t rstart,bus_addr_t rend,bus_size_t size,bus_size_t alignment,bus_size_t boundary,int flags,bus_addr_t * bpap,bus_space_handle_t * bshp)426f5362116Sthorpej i80321_mem_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
427f5362116Sthorpej bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
428f5362116Sthorpej bus_addr_t *bpap, bus_space_handle_t *bshp)
429f5362116Sthorpej {
430f5362116Sthorpej
4310f09ed48Sprovos panic("i80321_mem_bs_alloc(): not implemented");
432f5362116Sthorpej }
433f5362116Sthorpej
434f5362116Sthorpej void
i80321_mem_bs_free(void * t,bus_space_handle_t bsh,bus_size_t size)435f5362116Sthorpej i80321_mem_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
436f5362116Sthorpej {
437f5362116Sthorpej
4380f09ed48Sprovos panic("i80321_mem_bs_free(): not implemented");
439f5362116Sthorpej }
440f5362116Sthorpej
441f5362116Sthorpej paddr_t
i80321_mem_bs_mmap(void * t,bus_addr_t addr,off_t off,int prot,int flags)442f5362116Sthorpej i80321_mem_bs_mmap(void *t, bus_addr_t addr, off_t off, int prot, int flags)
443f5362116Sthorpej {
44460617b8eSmacallan #ifndef I80321_USE_DIRECT_WIN
44560617b8eSmacallan struct i80321_softc *sc = t;
44660617b8eSmacallan #endif
44760617b8eSmacallan uint32_t busbase;
44860617b8eSmacallan paddr_t pa, physbase, bpa = addr + off, pflags = 0;
449f5362116Sthorpej
45060617b8eSmacallan #ifdef I80321_USE_DIRECT_WIN
45160617b8eSmacallan if (
45260617b8eSmacallan #if VERDE_OUT_DIRECT_WIN_BASE != 0
45360617b8eSmacallan bpa >= (VERDE_OUT_DIRECT_WIN_BASE) &&
45460617b8eSmacallan #endif
45560617b8eSmacallan bpa < (VERDE_OUT_DIRECT_WIN_BASE + VERDE_OUT_DIRECT_WIN_SIZE)) {
45660617b8eSmacallan busbase = VERDE_OUT_DIRECT_WIN_BASE;
45760617b8eSmacallan physbase = VERDE_OUT_DIRECT_WIN_BASE;
45860617b8eSmacallan } else
45931997526Sthorpej return (-1);
46060617b8eSmacallan #else
46160617b8eSmacallan if (bpa >= sc->sc_owin[0].owin_xlate_lo &&
46260617b8eSmacallan bpa < (sc->sc_owin[0].owin_xlate_lo +
46360617b8eSmacallan VERDE_OUT_XLATE_MEM_WIN_SIZE)) {
46460617b8eSmacallan busbase = sc->sc_owin[0].owin_xlate_lo;
46560617b8eSmacallan physbase = sc->sc_iwin[1].iwin_xlate;
46660617b8eSmacallan } else
46731997526Sthorpej return (-1);
46860617b8eSmacallan #endif
46960617b8eSmacallan
47060617b8eSmacallan pa = trunc_page((bpa - busbase) + physbase);
47160617b8eSmacallan if (flags & BUS_SPACE_MAP_PREFETCHABLE) {
47260617b8eSmacallan pflags = ARM_MMAP_WRITECOMBINE;
47360617b8eSmacallan }
47460617b8eSmacallan return (arm_btop(pa) | pflags);
475f5362116Sthorpej }
476