i80321_space.c revision 139735
1135669Scognet/*	$NetBSD: i80321_space.c,v 1.6 2003/10/06 15:43:35 thorpej Exp $	*/
2135669Scognet
3139735Simp/*-
4135669Scognet * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
5135669Scognet * All rights reserved.
6135669Scognet *
7135669Scognet * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8135669Scognet *
9135669Scognet * Redistribution and use in source and binary forms, with or without
10135669Scognet * modification, are permitted provided that the following conditions
11135669Scognet * are met:
12135669Scognet * 1. Redistributions of source code must retain the above copyright
13135669Scognet *    notice, this list of conditions and the following disclaimer.
14135669Scognet * 2. Redistributions in binary form must reproduce the above copyright
15135669Scognet *    notice, this list of conditions and the following disclaimer in the
16135669Scognet *    documentation and/or other materials provided with the distribution.
17135669Scognet * 3. All advertising materials mentioning features or use of this software
18135669Scognet *    must display the following acknowledgement:
19135669Scognet *	This product includes software developed for the NetBSD Project by
20135669Scognet *	Wasabi Systems, Inc.
21135669Scognet * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22135669Scognet *    or promote products derived from this software without specific prior
23135669Scognet *    written permission.
24135669Scognet *
25135669Scognet * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26135669Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27135669Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28135669Scognet * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29135669Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30135669Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31135669Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32135669Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33135669Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34135669Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35135669Scognet * POSSIBILITY OF SUCH DAMAGE.
36135669Scognet */
37135669Scognet
38135669Scognet/*
39135669Scognet * bus_space functions for i80321 I/O Processor.
40135669Scognet */
41135669Scognet
42135669Scognet#include <sys/cdefs.h>
43135669Scognet__FBSDID("$FreeBSD: head/sys/arm/xscale/i80321/i80321_space.c 139735 2005-01-05 21:58:49Z imp $");
44135669Scognet
45135669Scognet#include <sys/param.h>
46135669Scognet#include <sys/systm.h>
47135669Scognet#include <sys/bus.h>
48135669Scognet
49135669Scognet#include <machine/pcb.h>
50135669Scognet
51135669Scognet#include <vm/vm.h>
52135669Scognet#include <vm/vm_kern.h>
53135669Scognet#include <vm/pmap.h>
54135669Scognet#include <vm/vm_page.h>
55135669Scognet#include <vm/vm_extern.h>
56135669Scognet
57135669Scognet#include <machine/bus.h>
58135669Scognet
59135669Scognet#include <arm/xscale/i80321/i80321reg.h>
60135669Scognet#include <arm/xscale/i80321/i80321var.h>
61135669Scognet
62135669Scognet/* Prototypes for all the bus_space structure functions */
63135669Scognetbs_protos(i80321);
64135669Scognetbs_protos(i80321_io);
65135669Scognetbs_protos(i80321_mem);
66135669Scognetbs_protos(generic);
67135669Scognetbs_protos(generic_armv4);
68135669Scognetbs_protos(bs_notimpl);
69135669Scognet
70135669Scognet/*
71135669Scognet * Template bus_space -- copied, and the bits that are NULL are
72135669Scognet * filled in.
73135669Scognet */
74135669Scognetconst struct bus_space i80321_bs_tag_template = {
75135669Scognet	/* cookie */
76135669Scognet	(void *) 0,
77135669Scognet
78135669Scognet	/* mapping/unmapping */
79135669Scognet	NULL,
80135669Scognet	NULL,
81135669Scognet	i80321_bs_subregion,
82135669Scognet
83135669Scognet	/* allocation/deallocation */
84135669Scognet	NULL,
85135669Scognet	NULL,
86135669Scognet
87135669Scognet	/* barrier */
88135669Scognet	i80321_bs_barrier,
89135669Scognet
90135669Scognet	/* read (single) */
91135669Scognet	generic_bs_r_1,
92135669Scognet	generic_armv4_bs_r_2,
93135669Scognet	generic_bs_r_4,
94135669Scognet	NULL,
95135669Scognet
96135669Scognet	/* read multiple */
97135669Scognet	generic_bs_rm_1,
98135669Scognet	generic_armv4_bs_rm_2,
99135669Scognet	generic_bs_rm_4,
100135669Scognet	NULL,
101135669Scognet
102135669Scognet	/* read region */
103135669Scognet	NULL,
104135669Scognet	generic_armv4_bs_rr_2,
105135669Scognet	generic_bs_rr_4,
106135669Scognet	NULL,
107135669Scognet
108135669Scognet	/* write (single) */
109135669Scognet	generic_bs_w_1,
110135669Scognet	generic_armv4_bs_w_2,
111135669Scognet	generic_bs_w_4,
112135669Scognet	NULL,
113135669Scognet
114135669Scognet	/* write multiple */
115135669Scognet	generic_bs_wm_1,
116135669Scognet	generic_armv4_bs_wm_2,
117135669Scognet	generic_bs_wm_4,
118135669Scognet	NULL,
119135669Scognet
120135669Scognet	/* write region */
121135669Scognet	NULL,
122135669Scognet	generic_armv4_bs_wr_2,
123135669Scognet	generic_bs_wr_4,
124135669Scognet	NULL,
125135669Scognet
126135669Scognet	/* set multiple */
127135669Scognet	NULL,
128135669Scognet	NULL,
129135669Scognet	NULL,
130135669Scognet	NULL,
131135669Scognet
132135669Scognet	/* set region */
133135669Scognet	NULL,
134135669Scognet	generic_armv4_bs_sr_2,
135135669Scognet	generic_bs_sr_4,
136135669Scognet	NULL,
137135669Scognet
138135669Scognet	/* copy */
139135669Scognet	NULL,
140135669Scognet	generic_armv4_bs_c_2,
141135669Scognet	NULL,
142135669Scognet	NULL,
143135669Scognet};
144135669Scognet
145135669Scognetvoid
146135669Scogneti80321_bs_init(bus_space_tag_t bs, void *cookie)
147135669Scognet{
148135669Scognet
149135669Scognet	*bs = i80321_bs_tag_template;
150135669Scognet	bs->bs_cookie = cookie;
151135669Scognet}
152135669Scognet
153135669Scognetvoid
154135669Scogneti80321_io_bs_init(bus_space_tag_t bs, void *cookie)
155135669Scognet{
156135669Scognet
157135669Scognet	*bs = i80321_bs_tag_template;
158135669Scognet	bs->bs_cookie = cookie;
159135669Scognet
160135669Scognet	bs->bs_map = i80321_io_bs_map;
161135669Scognet	bs->bs_unmap = i80321_io_bs_unmap;
162135669Scognet	bs->bs_alloc = i80321_io_bs_alloc;
163135669Scognet	bs->bs_free = i80321_io_bs_free;
164135669Scognet
165135669Scognet}
166135669Scognet
167135669Scognetvoid
168135669Scogneti80321_mem_bs_init(bus_space_tag_t bs, void *cookie)
169135669Scognet{
170135669Scognet
171135669Scognet	*bs = i80321_bs_tag_template;
172135669Scognet	bs->bs_cookie = cookie;
173135669Scognet
174135669Scognet	bs->bs_map = i80321_mem_bs_map;
175135669Scognet	bs->bs_unmap = i80321_mem_bs_unmap;
176135669Scognet	bs->bs_alloc = i80321_mem_bs_alloc;
177135669Scognet	bs->bs_free = i80321_mem_bs_free;
178135669Scognet
179135669Scognet}
180135669Scognet
181135669Scognet/* *** Routines shared by i80321, PCI IO, and PCI MEM. *** */
182135669Scognet
183135669Scognetint
184135669Scogneti80321_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
185135669Scognet    bus_size_t size, bus_space_handle_t *nbshp)
186135669Scognet{
187135669Scognet
188135669Scognet	*nbshp = bsh + offset;
189135669Scognet	return (0);
190135669Scognet}
191135669Scognet
192135669Scognetvoid
193135669Scogneti80321_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
194135669Scognet    bus_size_t len, int flags)
195135669Scognet{
196135669Scognet
197135669Scognet	/* Nothing to do. */
198135669Scognet}
199135669Scognet
200135669Scognet/* *** Routines for PCI IO. *** */
201135669Scognet
202135669Scognetextern struct i80321_softc *i80321_softc;
203135669Scognetint
204135669Scogneti80321_io_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
205135669Scognet    bus_space_handle_t *bshp)
206135669Scognet{
207135669Scognet	struct i80321_softc *sc = i80321_softc;
208135669Scognet	vm_offset_t winvaddr;
209135669Scognet	uint32_t busbase;
210135669Scognet
211135669Scognet	if (bpa >= sc->sc_ioout_xlate &&
212135669Scognet	    bpa < (sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE)) {
213135669Scognet		busbase = sc->sc_ioout_xlate;
214135669Scognet		winvaddr = sc->sc_iow_vaddr;
215135669Scognet	} else
216135669Scognet		return (EINVAL);
217135669Scognet
218135669Scognet	if ((bpa + size) >= (busbase + VERDE_OUT_XLATE_IO_WIN_SIZE))
219135669Scognet		return (EINVAL);
220135669Scognet
221135669Scognet	/*
222135669Scognet	 * Found the window -- PCI I/O space is mapped at a fixed
223135669Scognet	 * virtual address by board-specific code.  Translate the
224135669Scognet	 * bus address to the virtual address.
225135669Scognet	 */
226135669Scognet	*bshp = winvaddr + (bpa - busbase);
227135669Scognet
228135669Scognet	return (0);
229135669Scognet}
230135669Scognet
231135669Scognetvoid
232135669Scogneti80321_io_bs_unmap(void *t, bus_size_t size)
233135669Scognet{
234135669Scognet
235135669Scognet	/* Nothing to do. */
236135669Scognet}
237135669Scognet
238135669Scognetint
239135669Scogneti80321_io_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
240135669Scognet    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
241135669Scognet    bus_addr_t *bpap, bus_space_handle_t *bshp)
242135669Scognet{
243135669Scognet
244135669Scognet	panic("i80321_io_bs_alloc(): not implemented");
245135669Scognet}
246135669Scognet
247135669Scognetvoid
248135669Scogneti80321_io_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
249135669Scognet{
250135669Scognet
251135669Scognet	panic("i80321_io_bs_free(): not implemented");
252135669Scognet}
253135669Scognet
254135669Scognet
255135669Scognet/* *** Routines for PCI MEM. *** */
256135669Scognetextern int badaddr_read(void *, int, void *);
257135669Scognetint
258135669Scogneti80321_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
259135669Scognet    bus_space_handle_t *bshp)
260135669Scognet{
261135669Scognet
262135669Scognet	vm_offset_t va;
263135669Scognet	uint32_t busbase;
264135669Scognet	vm_paddr_t pa, endpa, physbase;
265135669Scognet
266135669Scognet	/*
267135669Scognet	 * Found the window -- PCI MEM space is not mapped by allocating
268135669Scognet	 * some kernel VA space and mapping the pages with pmap_enter().
269135669Scognet	 * pmap_enter() will map unmanaged pages as non-cacheable.
270135669Scognet	 */
271135669Scognet	pa = trunc_page((bpa - busbase) + physbase);
272135669Scognet	endpa = round_page(((bpa - busbase) + physbase) + size);
273135669Scognet	pa = trunc_page(bpa);
274135669Scognet	endpa = round_page(bpa + size);
275135669Scognet
276135669Scognet	*bshp = va + (bpa & PAGE_MASK);
277135669Scognet	*bshp = pa;
278135669Scognet	*bshp = (vm_offset_t)pmap_mapdev(pa, endpa - pa);
279135669Scognet
280135669Scognet	return (0);
281135669Scognet}
282135669Scognet
283135669Scognetvoid
284135669Scogneti80321_mem_bs_unmap(void *t, bus_size_t size)
285135669Scognet{
286135669Scognet	vm_offset_t va, endva;
287135669Scognet
288135669Scognet	va = trunc_page((vm_offset_t)t);
289135669Scognet	endva = va + round_page(size);
290135669Scognet
291135669Scognet	/* Free the kernel virtual mapping. */
292135669Scognet	kmem_free(kernel_map, va, endva - va);
293135669Scognet}
294135669Scognet
295135669Scognetint
296135669Scogneti80321_mem_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
297135669Scognet    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
298135669Scognet    bus_addr_t *bpap, bus_space_handle_t *bshp)
299135669Scognet{
300135669Scognet
301135669Scognet	panic("i80321_mem_bs_alloc(): not implemented");
302135669Scognet}
303135669Scognet
304135669Scognetvoid
305135669Scogneti80321_mem_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
306135669Scognet{
307135669Scognet
308135669Scognet	panic("i80321_mem_bs_free(): not implemented");
309135669Scognet}
310