1/* $Id: arbus.c,v 1.17 2021/08/07 16:18:58 thorpej 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.17 2021/08/07 16:18:58 thorpej Exp $");
45
46#include "locators.h"
47#define	_MIPS_BUS_DMA_PRIVATE
48
49#include <sys/param.h>
50#include <sys/bus.h>
51#include <sys/device.h>
52#include <sys/extent.h>
53#include <sys/kmem.h>
54#include <sys/systm.h>
55
56#include <mips/atheros/include/platform.h>
57#include <mips/atheros/include/arbusvar.h>
58
59static int arbus_match(device_t, cfdata_t, void *);
60static void arbus_attach(device_t, device_t, void *);
61static int arbus_print(void *, const char *);
62static void arbus_bus_mem_init(bus_space_tag_t, void *);
63
64struct arbus_intrhand {
65	int		ih_cirq;
66	int		ih_mirq;
67	void		*ih_cookie;
68};
69
70CFATTACH_DECL_NEW(arbus, 0, arbus_match, arbus_attach, NULL, NULL);
71
72struct mips_bus_space	arbus_mbst;
73#if _BYTE_ORDER == _BIG_ENDIAN
74struct mips_bus_space	arbus_mbst_le;
75#endif
76struct mips_bus_dma_tag	arbus_mdt = {
77	._dmamap_ops = _BUS_DMAMAP_OPS_INITIALIZER,
78	._dmamem_ops = _BUS_DMAMEM_OPS_INITIALIZER,
79	._dmatag_ops = _BUS_DMATAG_OPS_INITIALIZER,
80};
81
82void
83arbus_init(void)
84{
85	static bool done = false;
86	if (done)
87		return;
88	done = true;
89
90	arbus_bus_mem_init(&arbus_mbst, NULL);
91#if _BYTE_ORDER == _BIG_ENDIAN
92	arbusle_bus_mem_init(&arbus_mbst_le, NULL);
93#endif
94}
95
96/* this primarily exists so we can get to the console... */
97bus_space_tag_t
98arbus_get_bus_space_tag(void)
99{
100	arbus_init();
101	return (&arbus_mbst);
102}
103
104bus_dma_tag_t
105arbus_get_bus_dma_tag(void)
106{
107	arbus_init();
108	return (&arbus_mdt);
109}
110
111int
112arbus_match(device_t parent, cfdata_t match, void *aux)
113{
114
115	return 1;
116}
117
118void
119arbus_attach(device_t parent, device_t self, void *aux)
120{
121	aprint_normal("\n");
122
123	arbus_init();
124
125	for (const struct atheros_device *adv = platformsw->apsw_devices;
126	     adv->adv_name;
127	     adv++) {
128		struct arbus_attach_args aa;
129		aa.aa_name = adv->adv_name;
130		aa.aa_addr = adv->adv_addr;
131		aa.aa_size = adv->adv_size;
132		aa.aa_dmat = &arbus_mdt;
133		aa.aa_bst = &arbus_mbst;
134#if _BYTE_ORDER == _BIG_ENDIAN
135		aa.aa_bst_le = &arbus_mbst_le;
136#else
137		aa.aa_bst_le = &arbus_mbst;
138#endif
139		aa.aa_cirq = adv->adv_cirq;
140		aa.aa_mirq = adv->adv_mirq;
141
142		const int locs[ARBUSCF_NLOCS] = {
143			[ARBUSCF_ADDR] = aa.aa_addr,
144		};
145
146		if (atheros_enable_device(adv) != 0) {
147			continue;
148		}
149
150		config_found(self, &aa, arbus_print,
151		    CFARGS(.submatch = config_stdsubmatch,
152			   .locators = locs));
153	}
154}
155
156int
157arbus_print(void *aux, const char *pnp)
158{
159	struct arbus_attach_args *aa = aux;
160
161	if (pnp)
162		aprint_normal("%s at %s", aa->aa_name, pnp);
163
164	if (aa->aa_addr)
165		aprint_normal(" addr 0x%" PRIxBUSADDR, aa->aa_addr);
166
167	if (aa->aa_cirq >= 0)
168		aprint_normal(" cpu irq %d", aa->aa_cirq);
169
170	if (aa->aa_mirq >= 0)
171		aprint_normal(" misc irq %d", aa->aa_mirq);
172
173	return (UNCONF);
174}
175
176void *
177arbus_intr_establish(int cirq, int mirq, int (*handler)(void *), void *arg)
178{
179
180	struct arbus_intrhand * const ih = kmem_zalloc(sizeof(*ih), KM_NOSLEEP);
181	if (ih == NULL)
182		return NULL;
183
184	ih->ih_cirq = ih->ih_mirq = -1;
185	ih->ih_cookie = NULL;
186
187	if (mirq >= 0) {
188		ih->ih_mirq = mirq;
189		ih->ih_cookie = atheros_misc_intr_establish(mirq, handler, arg);
190	} else if (cirq >= 0) {
191		ih->ih_cirq = cirq;
192		ih->ih_cookie = atheros_cpu_intr_establish(cirq, handler, arg);
193	} else
194		return ih;
195
196	if (ih->ih_cookie == NULL) {
197		kmem_free(ih, sizeof(*ih));
198		return NULL;
199	}
200	return ih;
201}
202
203void
204arbus_intr_disestablish(void *arg)
205{
206	struct arbus_intrhand * const ih = arg;
207	if (ih->ih_mirq >= 0)
208		atheros_misc_intr_disestablish(ih->ih_cookie);
209	else if (ih->ih_cirq >= 0)
210		atheros_cpu_intr_disestablish(ih->ih_cookie);
211	kmem_free(ih, sizeof(*ih));
212}
213
214/*
215 * CPU memory/register stuff
216 */
217
218#define CHIP	   		arbus
219#define	CHIP_MEM		/* defined */
220#define	CHIP_W1_BUS_START(v)	0x00000000UL
221#define CHIP_W1_BUS_END(v)	0x1fffffffUL
222#define	CHIP_W1_SYS_START(v)	CHIP_W1_BUS_START(v)
223#define	CHIP_W1_SYS_END(v)	CHIP_W1_BUS_END(v)
224
225#include <mips/mips/bus_space_alignstride_chipdep.c>
226