arbus.c revision 1.10.84.1
11.10.84.1Srmind/* $Id: arbus.c,v 1.10.84.1 2011/03/05 20:51:02 rmind Exp $ */
21.1Sgdamore/*
31.1Sgdamore * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
41.1Sgdamore * Copyright (c) 2006 Garrett D'Amore.
51.1Sgdamore * All rights reserved.
61.1Sgdamore *
71.1Sgdamore * This code was written by Garrett D'Amore for the Champaign-Urbana
81.1Sgdamore * Community Wireless Network Project.
91.1Sgdamore *
101.1Sgdamore * Redistribution and use in source and binary forms, with or
111.1Sgdamore * without modification, are permitted provided that the following
121.1Sgdamore * conditions are met:
131.1Sgdamore * 1. Redistributions of source code must retain the above copyright
141.1Sgdamore *    notice, this list of conditions and the following disclaimer.
151.1Sgdamore * 2. Redistributions in binary form must reproduce the above
161.1Sgdamore *    copyright notice, this list of conditions and the following
171.1Sgdamore *    disclaimer in the documentation and/or other materials provided
181.1Sgdamore *    with the distribution.
191.1Sgdamore * 3. All advertising materials mentioning features or use of this
201.1Sgdamore *    software must display the following acknowledgements:
211.1Sgdamore *      This product includes software developed by the Urbana-Champaign
221.1Sgdamore *      Independent Media Center.
231.1Sgdamore *	This product includes software developed by Garrett D'Amore.
241.1Sgdamore * 4. Urbana-Champaign Independent Media Center's name and Garrett
251.1Sgdamore *    D'Amore's name may not be used to endorse or promote products
261.1Sgdamore *    derived from this software without specific prior written permission.
271.1Sgdamore *
281.1Sgdamore * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
291.1Sgdamore * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
301.1Sgdamore * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
311.1Sgdamore * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
321.1Sgdamore * ARE DISCLAIMED.  IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
331.1Sgdamore * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
341.1Sgdamore * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
351.1Sgdamore * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
361.1Sgdamore * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
371.1Sgdamore * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
381.1Sgdamore * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
391.1Sgdamore * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
401.1Sgdamore * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
411.1Sgdamore */
421.1Sgdamore
431.1Sgdamore#include <sys/cdefs.h>
441.10.84.1Srmind__KERNEL_RCSID(0, "$NetBSD: arbus.c,v 1.10.84.1 2011/03/05 20:51:02 rmind Exp $");
451.1Sgdamore
461.1Sgdamore#include "locators.h"
471.1Sgdamore#include <sys/param.h>
481.1Sgdamore#include <sys/systm.h>
491.1Sgdamore#include <sys/device.h>
501.1Sgdamore#include <sys/extent.h>
511.1Sgdamore#include <sys/malloc.h>
521.1Sgdamore
531.1Sgdamore#define	_MIPS_BUS_DMA_PRIVATE
541.1Sgdamore#include <machine/bus.h>
551.9Sgdamore#include <mips/atheros/include/ar5312reg.h>
561.1Sgdamore#include <mips/atheros/include/ar531xvar.h>
571.1Sgdamore#include <mips/atheros/include/arbusvar.h>
581.1Sgdamore
591.10.84.1Srmindstatic int arbus_match(device_t, struct cfdata *, void *);
601.10.84.1Srmindstatic void arbus_attach(device_t, device_t, void *);
611.1Sgdamorestatic int arbus_print(void *, const char *);
621.1Sgdamorestatic void arbus_bus_mem_init(bus_space_tag_t, void *);
631.1Sgdamore
641.1Sgdamorestruct arbus_intrhand {
651.10Sgdamore	int		ih_cirq;
661.10Sgdamore	int		ih_mirq;
671.1Sgdamore	void		*ih_cookie;
681.1Sgdamore};
691.1Sgdamore
701.10.84.1SrmindCFATTACH_DECL_NEW(arbus, 0, arbus_match, arbus_attach, NULL, NULL);
711.1Sgdamore
721.1Sgdamorestruct mips_bus_space	arbus_mbst;
731.10.84.1Srmindstruct mips_bus_dma_tag	arbus_mdt = {
741.10.84.1Srmind	._dmamap_ops = _BUS_DMAMAP_OPS_INITIALIZER,
751.10.84.1Srmind	._dmamem_ops = _BUS_DMAMEM_OPS_INITIALIZER,
761.10.84.1Srmind	._dmatag_ops = _BUS_DMATAG_OPS_INITIALIZER,
771.10.84.1Srmind};
781.1Sgdamore
791.1Sgdamorevoid
801.1Sgdamorearbus_init(void)
811.1Sgdamore{
821.10.84.1Srmind	static bool done = false;
831.1Sgdamore	if (done)
841.1Sgdamore		return;
851.10.84.1Srmind	done = true;
861.1Sgdamore
871.1Sgdamore	arbus_bus_mem_init(&arbus_mbst, NULL);
881.1Sgdamore}
891.1Sgdamore
901.1Sgdamore/* this primarily exists so we can get to the console... */
911.1Sgdamorebus_space_tag_t
921.1Sgdamorearbus_get_bus_space_tag(void)
931.1Sgdamore{
941.1Sgdamore	arbus_init();
951.1Sgdamore	return (&arbus_mbst);
961.1Sgdamore}
971.1Sgdamore
981.1Sgdamorebus_dma_tag_t
991.1Sgdamorearbus_get_bus_dma_tag(void)
1001.1Sgdamore{
1011.1Sgdamore	arbus_init();
1021.1Sgdamore	return (&arbus_mdt);
1031.1Sgdamore}
1041.1Sgdamore
1051.1Sgdamoreint
1061.10.84.1Srmindarbus_match(device_t parent, cfdata_t match, void *aux)
1071.1Sgdamore{
1081.1Sgdamore
1091.1Sgdamore	return 1;
1101.1Sgdamore}
1111.1Sgdamore
1121.1Sgdamorevoid
1131.10.84.1Srmindarbus_attach(device_t parent, device_t self, void *aux)
1141.1Sgdamore{
1151.1Sgdamore	struct arbus_attach_args aa;
1161.10Sgdamore	const struct ar531x_device *devices;
1171.1Sgdamore	int i;
1181.1Sgdamore
1191.1Sgdamore	printf("\n");
1201.1Sgdamore	int locs[ARBUSCF_NLOCS];
1211.1Sgdamore
1221.1Sgdamore	arbus_init();
1231.1Sgdamore
1241.10Sgdamore	for (i = 0, devices = ar531x_get_devices(); devices[i].name; i++) {
1251.10Sgdamore
1261.10Sgdamore		aa.aa_name = devices[i].name;
1271.10Sgdamore		aa.aa_size = devices[i].size;
1281.1Sgdamore		aa.aa_dmat = &arbus_mdt;
1291.1Sgdamore		aa.aa_bst = &arbus_mbst;
1301.10Sgdamore		aa.aa_cirq = devices[i].cirq;
1311.10Sgdamore		aa.aa_mirq = devices[i].mirq;
1321.10Sgdamore		aa.aa_addr = devices[i].addr;
1331.1Sgdamore
1341.1Sgdamore		locs[ARBUSCF_ADDR] = aa.aa_addr;
1351.1Sgdamore
1361.10Sgdamore		if (ar531x_enable_device(&devices[i]) != 0) {
1371.10Sgdamore			continue;
1381.1Sgdamore		}
1391.1Sgdamore
1401.1Sgdamore		(void) config_found_sm_loc(self, "arbus", locs, &aa,
1411.1Sgdamore		    arbus_print, config_stdsubmatch);
1421.1Sgdamore	}
1431.1Sgdamore}
1441.1Sgdamore
1451.1Sgdamoreint
1461.1Sgdamorearbus_print(void *aux, const char *pnp)
1471.1Sgdamore{
1481.1Sgdamore	struct arbus_attach_args *aa = aux;
1491.1Sgdamore
1501.1Sgdamore	if (pnp)
1511.1Sgdamore		aprint_normal("%s at %s", aa->aa_name, pnp);
1521.1Sgdamore
1531.1Sgdamore	if (aa->aa_addr)
1541.10.84.1Srmind		aprint_normal(" addr 0x%" PRIxBUSADDR, aa->aa_addr);
1551.1Sgdamore
1561.10Sgdamore	if (aa->aa_cirq >= 0)
1571.10Sgdamore		aprint_normal(" cpu irq %d", aa->aa_cirq);
1581.1Sgdamore
1591.10Sgdamore	if (aa->aa_mirq >= 0)
1601.10Sgdamore		aprint_normal(" misc irq %d", aa->aa_mirq);
1611.1Sgdamore
1621.1Sgdamore	return (UNCONF);
1631.1Sgdamore}
1641.1Sgdamore
1651.1Sgdamorevoid *
1661.10Sgdamorearbus_intr_establish(int cirq, int mirq, int (*handler)(void *), void *arg)
1671.1Sgdamore{
1681.1Sgdamore	struct arbus_intrhand	*ih;
1691.1Sgdamore
1701.1Sgdamore	ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
1711.1Sgdamore	if (ih == NULL)
1721.1Sgdamore		return NULL;
1731.1Sgdamore
1741.10Sgdamore	ih->ih_cirq = ih->ih_mirq = -1;
1751.1Sgdamore	ih->ih_cookie = NULL;
1761.1Sgdamore
1771.10Sgdamore	if (mirq >= 0) {
1781.10Sgdamore		ih->ih_mirq = mirq;
1791.10Sgdamore		ih->ih_cookie = ar531x_misc_intr_establish(mirq, handler, arg);
1801.10Sgdamore	} else if (cirq >= 0) {
1811.10Sgdamore		ih->ih_cirq = cirq;
1821.10Sgdamore		ih->ih_cookie = ar531x_cpu_intr_establish(cirq, handler, arg);
1831.10Sgdamore	} else
1841.10Sgdamore		return ih;
1851.1Sgdamore
1861.1Sgdamore	if (ih->ih_cookie == NULL) {
1871.1Sgdamore		free(ih, M_DEVBUF);
1881.1Sgdamore		return NULL;
1891.1Sgdamore	}
1901.1Sgdamore	return ih;
1911.1Sgdamore}
1921.1Sgdamore
1931.1Sgdamorevoid
1941.1Sgdamorearbus_intr_disestablish(void *arg)
1951.1Sgdamore{
1961.1Sgdamore	struct arbus_intrhand	*ih = arg;
1971.10Sgdamore	if (ih->ih_mirq >= 0)
1981.1Sgdamore		ar531x_misc_intr_disestablish(ih->ih_cookie);
1991.10Sgdamore	else if (ih->ih_cirq >= 0)
2001.10Sgdamore		ar531x_cpu_intr_disestablish(ih->ih_cookie);
2011.1Sgdamore	free(ih, M_DEVBUF);
2021.1Sgdamore}
2031.1Sgdamore
2041.1Sgdamore/*
2051.1Sgdamore * CPU memory/register stuff
2061.1Sgdamore */
2071.1Sgdamore
2081.1Sgdamore#define CHIP	   		arbus
2091.1Sgdamore#define	CHIP_MEM		/* defined */
2101.1Sgdamore#define	CHIP_W1_BUS_START(v)	0x00000000UL
2111.1Sgdamore#define CHIP_W1_BUS_END(v)	0x1fffffffUL
2121.1Sgdamore#define	CHIP_W1_SYS_START(v)	CHIP_W1_BUS_START(v)
2131.1Sgdamore#define	CHIP_W1_SYS_END(v)	CHIP_W1_BUS_END(v)
2141.1Sgdamore
2151.1Sgdamore#include <mips/mips/bus_space_alignstride_chipdep.c>
216