i80321_space.c revision 158746
197403Sobrien/*	$NetBSD: i80321_space.c,v 1.6 2003/10/06 15:43:35 thorpej Exp $	*/
297403Sobrien
3132720Skan/*-
497403Sobrien * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
597403Sobrien * All rights reserved.
697403Sobrien *
797403Sobrien * Written by Jason R. Thorpe for Wasabi Systems, Inc.
897403Sobrien *
997403Sobrien * Redistribution and use in source and binary forms, with or without
1097403Sobrien * modification, are permitted provided that the following conditions
1197403Sobrien * are met:
1297403Sobrien * 1. Redistributions of source code must retain the above copyright
1397403Sobrien *    notice, this list of conditions and the following disclaimer.
1497403Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1597403Sobrien *    notice, this list of conditions and the following disclaimer in the
1697403Sobrien *    documentation and/or other materials provided with the distribution.
1797403Sobrien * 3. All advertising materials mentioning features or use of this software
1897403Sobrien *    must display the following acknowledgement:
1997403Sobrien *	This product includes software developed for the NetBSD Project by
2097403Sobrien *	Wasabi Systems, Inc.
2197403Sobrien * 4. The name of Wasabi Systems, Inc. may not be used to endorse
2297403Sobrien *    or promote products derived from this software without specific prior
2397403Sobrien *    written permission.
2497403Sobrien *
2597403Sobrien * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
2697403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2797403Sobrien * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2897403Sobrien * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
2997403Sobrien * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3097403Sobrien * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3197403Sobrien * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3297403Sobrien * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3397403Sobrien * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3497403Sobrien * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3597403Sobrien * POSSIBILITY OF SUCH DAMAGE.
36132720Skan */
3797403Sobrien
3897403Sobrien/*
3997403Sobrien * bus_space functions for i80321 I/O Processor.
4097403Sobrien */
4197403Sobrien
4297403Sobrien#include <sys/cdefs.h>
4397403Sobrien__FBSDID("$FreeBSD: head/sys/arm/xscale/i80321/i80321_space.c 158746 2006-05-19 11:27:02Z cognet $");
4497403Sobrien
4597403Sobrien#include <sys/param.h>
4697403Sobrien#include <sys/systm.h>
4797403Sobrien#include <sys/bus.h>
4897403Sobrien
4997403Sobrien#include <machine/pcb.h>
5097403Sobrien
5197403Sobrien#include <vm/vm.h>
5297403Sobrien#include <vm/vm_kern.h>
5397403Sobrien#include <vm/pmap.h>
5497403Sobrien#include <vm/vm_page.h>
5597403Sobrien#include <vm/vm_extern.h>
5697403Sobrien
5797403Sobrien#include <machine/bus.h>
5897403Sobrien
5997403Sobrien#include <arm/xscale/i80321/i80321reg.h>
6097403Sobrien#include <arm/xscale/i80321/i80321var.h>
6197403Sobrien
6297403Sobrien/* Prototypes for all the bus_space structure functions */
6397403Sobrienbs_protos(i80321);
6497403Sobrienbs_protos(i80321_io);
6597403Sobrienbs_protos(i80321_mem);
6697403Sobrienbs_protos(generic);
6797403Sobrienbs_protos(generic_armv4);
6897403Sobrien
6997403Sobrien/*
7097403Sobrien * Template bus_space -- copied, and the bits that are NULL are
7197403Sobrien * filled in.
7297403Sobrien */
7397403Sobrienconst struct bus_space i80321_bs_tag_template = {
7497403Sobrien	/* cookie */
7597403Sobrien	(void *) 0,
7697403Sobrien
7797403Sobrien	/* mapping/unmapping */
7897403Sobrien	NULL,
7997403Sobrien	NULL,
8097403Sobrien	i80321_bs_subregion,
8197403Sobrien
8297403Sobrien	/* allocation/deallocation */
8397403Sobrien	NULL,
8497403Sobrien	NULL,
8597403Sobrien
8697403Sobrien	/* barrier */
8797403Sobrien	i80321_bs_barrier,
8897403Sobrien
8997403Sobrien	/* read (single) */
9097403Sobrien	generic_bs_r_1,
9197403Sobrien	generic_armv4_bs_r_2,
9297403Sobrien	generic_bs_r_4,
9397403Sobrien	NULL,
9497403Sobrien
9597403Sobrien	/* read multiple */
9697403Sobrien	generic_bs_rm_1,
9797403Sobrien	generic_armv4_bs_rm_2,
9897403Sobrien	generic_bs_rm_4,
9997403Sobrien	NULL,
10097403Sobrien
10197403Sobrien	/* read region */
10297403Sobrien	generic_bs_rr_1,
10397403Sobrien	generic_armv4_bs_rr_2,
10497403Sobrien	generic_bs_rr_4,
10597403Sobrien	NULL,
10697403Sobrien
10797403Sobrien	/* write (single) */
10897403Sobrien	generic_bs_w_1,
10997403Sobrien	generic_armv4_bs_w_2,
110132720Skan	generic_bs_w_4,
11197403Sobrien	NULL,
112132720Skan
11397403Sobrien	/* write multiple */
114132720Skan	generic_bs_wm_1,
115132720Skan	generic_armv4_bs_wm_2,
116132720Skan	generic_bs_wm_4,
117132720Skan	NULL,
11897403Sobrien
119132720Skan	/* write region */
120132720Skan	NULL,
121132720Skan	generic_armv4_bs_wr_2,
12297403Sobrien	generic_bs_wr_4,
123132720Skan	NULL,
124132720Skan
125132720Skan	/* set multiple */
12697403Sobrien	NULL,
127132720Skan	NULL,
128132720Skan	NULL,
129132720Skan	NULL,
13097403Sobrien
131132720Skan	/* set region */
132132720Skan	NULL,
13397403Sobrien	generic_armv4_bs_sr_2,
13497403Sobrien	generic_bs_sr_4,
13597403Sobrien	NULL,
13697403Sobrien
13797403Sobrien	/* copy */
13897403Sobrien	NULL,
13997403Sobrien	generic_armv4_bs_c_2,
14097403Sobrien	NULL,
14197403Sobrien	NULL,
14297403Sobrien};
143132720Skan
14497403Sobrienvoid
14597403Sobrieni80321_bs_init(bus_space_tag_t bs, void *cookie)
146132720Skan{
147132720Skan
148132720Skan	*bs = i80321_bs_tag_template;
149132720Skan	bs->bs_cookie = cookie;
15097403Sobrien}
15197403Sobrien
152132720Skanvoid
15397403Sobrieni80321_io_bs_init(bus_space_tag_t bs, void *cookie)
15497403Sobrien{
15597403Sobrien
15697403Sobrien	*bs = i80321_bs_tag_template;
15797403Sobrien	bs->bs_cookie = cookie;
15897403Sobrien
15997403Sobrien	bs->bs_map = i80321_io_bs_map;
16097403Sobrien	bs->bs_unmap = i80321_io_bs_unmap;
16197403Sobrien	bs->bs_alloc = i80321_io_bs_alloc;
16297403Sobrien	bs->bs_free = i80321_io_bs_free;
16397403Sobrien
16497403Sobrien}
16597403Sobrien
16697403Sobrienvoid
16797403Sobrieni80321_mem_bs_init(bus_space_tag_t bs, void *cookie)
168132720Skan{
169132720Skan
170132720Skan	*bs = i80321_bs_tag_template;
171132720Skan	bs->bs_cookie = cookie;
172132720Skan
173132720Skan	bs->bs_map = i80321_mem_bs_map;
17497403Sobrien	bs->bs_unmap = i80321_mem_bs_unmap;
17597403Sobrien	bs->bs_alloc = i80321_mem_bs_alloc;
17697403Sobrien	bs->bs_free = i80321_mem_bs_free;
17797403Sobrien
17897403Sobrien}
17997403Sobrien
18097403Sobrien/* *** Routines shared by i80321, PCI IO, and PCI MEM. *** */
18197403Sobrien
18297403Sobrienint
18397403Sobrieni80321_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
18497403Sobrien    bus_size_t size, bus_space_handle_t *nbshp)
18597403Sobrien{
18697403Sobrien
187117397Skan	*nbshp = bsh + offset;
188132720Skan	return (0);
189132720Skan}
190132720Skan
191132720Skanvoid
192132720Skani80321_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
19397403Sobrien    bus_size_t len, int flags)
19497403Sobrien{
19597403Sobrien
19697403Sobrien	/* Nothing to do. */
19797403Sobrien}
19897403Sobrien
19997403Sobrien/* *** Routines for PCI IO. *** */
20097403Sobrien
20197403Sobrienextern struct i80321_softc *i80321_softc;
20297403Sobrienint
20397403Sobrieni80321_io_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
20497403Sobrien    bus_space_handle_t *bshp)
20597403Sobrien{
20697403Sobrien	struct i80321_softc *sc = i80321_softc;
20797403Sobrien	vm_offset_t winvaddr;
20897403Sobrien	uint32_t busbase;
20997403Sobrien
21097403Sobrien	if (bpa >= sc->sc_ioout_xlate &&
21197403Sobrien	    bpa < (sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE)) {
21297403Sobrien		busbase = sc->sc_ioout_xlate;
21397403Sobrien		winvaddr = sc->sc_iow_vaddr;
21497403Sobrien	} else
21597403Sobrien		return (EINVAL);
21697403Sobrien
21797403Sobrien	if ((bpa + size) >= (busbase + VERDE_OUT_XLATE_IO_WIN_SIZE))
21897403Sobrien		return (EINVAL);
21997403Sobrien
22097403Sobrien	/*
22197403Sobrien	 * Found the window -- PCI I/O space is mapped at a fixed
22297403Sobrien	 * virtual address by board-specific code.  Translate the
22397403Sobrien	 * bus address to the virtual address.
22497403Sobrien	 */
22597403Sobrien	*bshp = winvaddr + (bpa - busbase);
22697403Sobrien
227132720Skan	return (0);
228}
229
230void
231i80321_io_bs_unmap(void *t, bus_size_t size)
232{
233
234	/* Nothing to do. */
235}
236
237int
238i80321_io_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
239    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
240    bus_addr_t *bpap, bus_space_handle_t *bshp)
241{
242
243	panic("i80321_io_bs_alloc(): not implemented");
244}
245
246void
247i80321_io_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
248{
249
250	panic("i80321_io_bs_free(): not implemented");
251}
252
253
254/* *** Routines for PCI MEM. *** */
255extern int badaddr_read(void *, int, void *);
256int
257i80321_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
258    bus_space_handle_t *bshp)
259{
260	vm_paddr_t pa, endpa;
261
262	pa = trunc_page(bpa);
263	endpa = round_page(bpa + size);
264
265	*bshp = (vm_offset_t)pmap_mapdev(pa, endpa - pa);
266
267	return (0);
268}
269
270void
271i80321_mem_bs_unmap(void *t, bus_size_t size)
272{
273	vm_offset_t va, endva;
274
275	va = trunc_page((vm_offset_t)t);
276	endva = va + round_page(size);
277
278	/* Free the kernel virtual mapping. */
279	kmem_free(kernel_map, va, endva - va);
280}
281
282int
283i80321_mem_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
284    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
285    bus_addr_t *bpap, bus_space_handle_t *bshp)
286{
287
288	panic("i80321_mem_bs_alloc(): not implemented");
289}
290
291void
292i80321_mem_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
293{
294
295	panic("i80321_mem_bs_free(): not implemented");
296}
297