1/* $NetBSD: tc_dma_3000_500.c,v 1.24 2021/07/18 05:12:27 thorpej Exp $ */
2
3/*-
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
34
35__KERNEL_RCSID(0, "$NetBSD: tc_dma_3000_500.c,v 1.24 2021/07/18 05:12:27 thorpej Exp $");
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/device.h>
40#include <sys/kernel.h>
41#include <sys/kmem.h>
42
43#define _ALPHA_BUS_DMA_PRIVATE
44#include <sys/bus.h>
45
46#include <dev/tc/tcvar.h>
47#include <alpha/tc/tc_sgmap.h>
48#include <alpha/tc/tc_dma_3000_500.h>
49
50struct alpha_bus_dma_tag tc_dmat_sgmap = {
51	NULL,				/* _cookie */
52	0,				/* _wbase */
53	0,				/* _wsize */
54	NULL,				/* _next_window */
55	0,				/* _boundary */
56	NULL,				/* _sgmap */
57	PAGE_SIZE,			/* _sgmap_minalign */
58	0,				/* _pfthresh */
59	NULL,				/* _get_tag */
60	tc_bus_dmamap_create_sgmap,
61	tc_bus_dmamap_destroy_sgmap,
62	tc_bus_dmamap_load_sgmap,
63	tc_bus_dmamap_load_mbuf_sgmap,
64	tc_bus_dmamap_load_uio_sgmap,
65	tc_bus_dmamap_load_raw_sgmap,
66	tc_bus_dmamap_unload_sgmap,
67	_bus_dmamap_sync,
68	_bus_dmamem_alloc,
69	_bus_dmamem_free,
70	_bus_dmamem_map,
71	_bus_dmamem_unmap,
72	_bus_dmamem_mmap,
73};
74
75struct tc_dma_slot_info {
76	struct alpha_sgmap tdsi_sgmap;		/* sgmap for slot */
77	struct alpha_bus_dma_tag tdsi_dmat;	/* dma tag for slot */
78};
79struct tc_dma_slot_info *tc_dma_slot_info;
80
81void
82tc_dma_init_3000_500(int nslots)
83{
84	extern struct alpha_bus_dma_tag tc_dmat_direct;
85	size_t sisize;
86	int i;
87
88	/* Allocate per-slot DMA info. */
89	sisize = nslots * sizeof(struct tc_dma_slot_info);
90	tc_dma_slot_info = kmem_zalloc(sisize, KM_SLEEP);
91
92	/* Default all slots to direct-mapped. */
93	for (i = 0; i < nslots; i++)
94		memcpy(&tc_dma_slot_info[i].tdsi_dmat, &tc_dmat_direct,
95		    sizeof(tc_dma_slot_info[i].tdsi_dmat));
96}
97
98/*
99 * Return the DMA tag for the given slot.
100 */
101bus_dma_tag_t
102tc_dma_get_tag_3000_500(int slot)
103{
104
105	return (&tc_dma_slot_info[slot].tdsi_dmat);
106}
107
108/*
109 * Create a TURBOchannel SGMAP-mapped DMA map.
110 */
111int
112tc_bus_dmamap_create_sgmap(
113	bus_dma_tag_t t,
114	bus_size_t size,
115	int nsegments,
116	bus_size_t maxsegsz,
117	bus_size_t boundary,
118	int flags,
119	bus_dmamap_t *dmamp)
120{
121	int error;
122
123	error = _bus_dmamap_create(t, size, nsegments, maxsegsz,
124	    boundary, flags, dmamp);
125	if (error)
126		return (error);
127
128	(void)*dmamp;
129
130	/* XXX BUS_DMA_ALLOCNOW */
131
132	return (error);
133}
134
135/*
136 * Destroy a TURBOchannel SGMAP-mapped DMA map.
137 */
138void
139tc_bus_dmamap_destroy_sgmap(bus_dma_tag_t t, bus_dmamap_t map)
140{
141
142	KASSERT(map->dm_mapsize == 0);
143
144	_bus_dmamap_destroy(t, map);
145}
146
147/*
148 * Load a TURBOchannel SGMAP-mapped DMA map with a linear buffer.
149 */
150int
151tc_bus_dmamap_load_sgmap(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags)
152{
153	struct tc_dma_slot_info *tdsi = t->_cookie;
154
155	return (tc_sgmap_load(t, map, buf, buflen, p, flags,
156	    &tdsi->tdsi_sgmap));
157}
158
159/*
160 * Load a TURBOchannel SGMAP-mapped DMA map with an mbuf chain.
161 */
162int
163tc_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m, int flags)
164{
165	struct tc_dma_slot_info *tdsi = t->_cookie;
166
167	return (tc_sgmap_load_mbuf(t, map, m, flags, &tdsi->tdsi_sgmap));
168}
169
170/*
171 * Load a TURBOchannel SGMAP-mapped DMA map with a uio.
172 */
173int
174tc_bus_dmamap_load_uio_sgmap(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio, int flags)
175{
176	struct tc_dma_slot_info *tdsi = t->_cookie;
177
178	return (tc_sgmap_load_uio(t, map, uio, flags, &tdsi->tdsi_sgmap));
179}
180
181/*
182 * Load a TURBOchannel SGMAP-mapped DMA map with raw memory.
183 */
184int
185tc_bus_dmamap_load_raw_sgmap(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags)
186{
187	struct tc_dma_slot_info *tdsi = t->_cookie;
188
189	return (tc_sgmap_load_raw(t, map, segs, nsegs, size, flags,
190	    &tdsi->tdsi_sgmap));
191}
192
193/*
194 * Unload a TURBOchannel SGMAP-mapped DMA map.
195 */
196void
197tc_bus_dmamap_unload_sgmap(bus_dma_tag_t t, bus_dmamap_t map)
198{
199	struct tc_dma_slot_info *tdsi = t->_cookie;
200
201	/*
202	 * Invalidate any SGMAP page table entries used by this
203	 * mapping.
204	 */
205	tc_sgmap_unload(t, map, &tdsi->tdsi_sgmap);
206
207	/*
208	 * Do the generic bits of the unload.
209	 */
210	_bus_dmamap_unload_common(t, map);
211}
212