arbus.c revision 1.11
1/* $Id: arbus.c,v 1.11 2010/12/15 00:05:46 matt Exp $ */
2/*
3 * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
4 * Copyright (c) 2006 Garrett D'Amore.
5 * All rights reserved.
6 *
7 * This code was written by Garrett D'Amore for the Champaign-Urbana
8 * Community Wireless Network Project.
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above
16 *    copyright notice, this list of conditions and the following
17 *    disclaimer in the documentation and/or other materials provided
18 *    with the distribution.
19 * 3. All advertising materials mentioning features or use of this
20 *    software must display the following acknowledgements:
21 *      This product includes software developed by the Urbana-Champaign
22 *      Independent Media Center.
23 *	This product includes software developed by Garrett D'Amore.
24 * 4. Urbana-Champaign Independent Media Center's name and Garrett
25 *    D'Amore's name may not be used to endorse or promote products
26 *    derived from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
29 * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED.  IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
33 * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
37 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
40 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: arbus.c,v 1.11 2010/12/15 00:05:46 matt Exp $");
45
46#include "locators.h"
47#include <sys/param.h>
48#include <sys/systm.h>
49#include <sys/device.h>
50#include <sys/extent.h>
51#include <sys/malloc.h>
52
53#define	_MIPS_BUS_DMA_PRIVATE
54#include <machine/bus.h>
55#include <mips/atheros/include/ar5312reg.h>
56#include <mips/atheros/include/ar531xvar.h>
57#include <mips/atheros/include/arbusvar.h>
58
59static int arbus_match(struct device *, struct cfdata *, void *);
60static void arbus_attach(struct device *, struct device *, void *);
61static int arbus_print(void *, const char *);
62static void arbus_bus_mem_init(bus_space_tag_t, void *);
63static void arbus_dma_init(struct device *, bus_dma_tag_t);
64
65struct arbus_intrhand {
66	int		ih_cirq;
67	int		ih_mirq;
68	void		*ih_cookie;
69};
70
71CFATTACH_DECL(arbus, sizeof(struct device), arbus_match, arbus_attach,
72    NULL, NULL);
73
74struct mips_bus_space	arbus_mbst;
75struct mips_bus_dma_tag	arbus_mdt;
76
77void
78arbus_init(void)
79{
80	static int done = 0;
81	if (done)
82		return;
83	done++;
84
85	arbus_bus_mem_init(&arbus_mbst, NULL);
86	arbus_dma_init(NULL, &arbus_mdt);
87}
88
89/* this primarily exists so we can get to the console... */
90bus_space_tag_t
91arbus_get_bus_space_tag(void)
92{
93	arbus_init();
94	return (&arbus_mbst);
95}
96
97bus_dma_tag_t
98arbus_get_bus_dma_tag(void)
99{
100	arbus_init();
101	return (&arbus_mdt);
102}
103
104int
105arbus_match(struct device *parent, struct cfdata *match, void *aux)
106{
107
108	return 1;
109}
110
111void
112arbus_attach(struct device *parent, struct device *self, void *aux)
113{
114	struct arbus_attach_args aa;
115	const struct ar531x_device *devices;
116	int i;
117
118	printf("\n");
119	int locs[ARBUSCF_NLOCS];
120
121	arbus_init();
122
123	for (i = 0, devices = ar531x_get_devices(); devices[i].name; i++) {
124
125		aa.aa_name = devices[i].name;
126		aa.aa_size = devices[i].size;
127		aa.aa_dmat = &arbus_mdt;
128		aa.aa_bst = &arbus_mbst;
129		aa.aa_cirq = devices[i].cirq;
130		aa.aa_mirq = devices[i].mirq;
131		aa.aa_addr = devices[i].addr;
132
133		locs[ARBUSCF_ADDR] = aa.aa_addr;
134
135		if (ar531x_enable_device(&devices[i]) != 0) {
136			continue;
137		}
138
139		(void) config_found_sm_loc(self, "arbus", locs, &aa,
140		    arbus_print, config_stdsubmatch);
141	}
142}
143
144int
145arbus_print(void *aux, const char *pnp)
146{
147	struct arbus_attach_args *aa = aux;
148
149	if (pnp)
150		aprint_normal("%s at %s", aa->aa_name, pnp);
151
152	if (aa->aa_addr)
153		aprint_normal(" addr 0x%" PRIxBUSADDR, aa->aa_addr);
154
155	if (aa->aa_cirq >= 0)
156		aprint_normal(" cpu irq %d", aa->aa_cirq);
157
158	if (aa->aa_mirq >= 0)
159		aprint_normal(" misc irq %d", aa->aa_mirq);
160
161	return (UNCONF);
162}
163
164void *
165arbus_intr_establish(int cirq, int mirq, int (*handler)(void *), void *arg)
166{
167	struct arbus_intrhand	*ih;
168
169	ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
170	if (ih == NULL)
171		return NULL;
172
173	ih->ih_cirq = ih->ih_mirq = -1;
174	ih->ih_cookie = NULL;
175
176	if (mirq >= 0) {
177		ih->ih_mirq = mirq;
178		ih->ih_cookie = ar531x_misc_intr_establish(mirq, handler, arg);
179	} else if (cirq >= 0) {
180		ih->ih_cirq = cirq;
181		ih->ih_cookie = ar531x_cpu_intr_establish(cirq, handler, arg);
182	} else
183		return ih;
184
185	if (ih->ih_cookie == NULL) {
186		free(ih, M_DEVBUF);
187		return NULL;
188	}
189	return ih;
190}
191
192void
193arbus_intr_disestablish(void *arg)
194{
195	struct arbus_intrhand	*ih = arg;
196	if (ih->ih_mirq >= 0)
197		ar531x_misc_intr_disestablish(ih->ih_cookie);
198	else if (ih->ih_cirq >= 0)
199		ar531x_cpu_intr_disestablish(ih->ih_cookie);
200	free(ih, M_DEVBUF);
201}
202
203
204void
205arbus_dma_init(struct device *sc, bus_dma_tag_t pdt)
206{
207	bus_dma_tag_t	t;
208
209	t = pdt;
210	t->_cookie = sc;
211	t->_wbase = 0;
212	t->_physbase = 0;
213	t->_wsize = MIPS_KSEG1_START - MIPS_KSEG0_START;
214	t->_dmamap_create = _bus_dmamap_create;
215	t->_dmamap_destroy = _bus_dmamap_destroy;
216	t->_dmamap_load = _bus_dmamap_load;
217	t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf;
218	t->_dmamap_load_uio = _bus_dmamap_load_uio;
219	t->_dmamap_load_raw = _bus_dmamap_load_raw;
220	t->_dmamap_unload = _bus_dmamap_unload;
221	t->_dmamap_sync = _bus_dmamap_sync;
222	t->_dmamem_alloc = _bus_dmamem_alloc;
223	t->_dmamem_free = _bus_dmamem_free;
224	t->_dmamem_map = _bus_dmamem_map;
225	t->_dmamem_unmap = _bus_dmamem_unmap;
226	t->_dmamem_mmap = _bus_dmamem_mmap;
227}
228
229/*
230 * CPU memory/register stuff
231 */
232
233#define CHIP	   		arbus
234#define	CHIP_MEM		/* defined */
235#define	CHIP_W1_BUS_START(v)	0x00000000UL
236#define CHIP_W1_BUS_END(v)	0x1fffffffUL
237#define	CHIP_W1_SYS_START(v)	CHIP_W1_BUS_START(v)
238#define	CHIP_W1_SYS_END(v)	CHIP_W1_BUS_END(v)
239
240#include <mips/mips/bus_space_alignstride_chipdep.c>
241