xref: /netbsd-src/sys/arch/hppa/dev/asp.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*	$NetBSD: asp.c,v 1.4 2021/08/07 16:18:55 thorpej Exp $	*/
26d3ceb1dSskrll 
36d3ceb1dSskrll /*	$OpenBSD: asp.c,v 1.5 2000/02/09 05:04:22 mickey Exp $	*/
46d3ceb1dSskrll 
56d3ceb1dSskrll /*
66d3ceb1dSskrll  * Copyright (c) 1998-2003 Michael Shalayeff
76d3ceb1dSskrll  * All rights reserved.
86d3ceb1dSskrll  *
96d3ceb1dSskrll  * Redistribution and use in source and binary forms, with or without
106d3ceb1dSskrll  * modification, are permitted provided that the following conditions
116d3ceb1dSskrll  * are met:
126d3ceb1dSskrll  * 1. Redistributions of source code must retain the above copyright
136d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer.
146d3ceb1dSskrll  * 2. Redistributions in binary form must reproduce the above copyright
156d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer in the
166d3ceb1dSskrll  *    documentation and/or other materials provided with the distribution.
176d3ceb1dSskrll  *
186d3ceb1dSskrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
196d3ceb1dSskrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
206d3ceb1dSskrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
216d3ceb1dSskrll  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
226d3ceb1dSskrll  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
236d3ceb1dSskrll  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
246d3ceb1dSskrll  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
256d3ceb1dSskrll  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
266d3ceb1dSskrll  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
276d3ceb1dSskrll  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
286d3ceb1dSskrll  * THE POSSIBILITY OF SUCH DAMAGE.
296d3ceb1dSskrll  */
306d3ceb1dSskrll 
316d3ceb1dSskrll /*
326d3ceb1dSskrll  * References:
336d3ceb1dSskrll  *
346d3ceb1dSskrll  * 1. Cobra/Coral I/O Subsystem External Reference Specification
356d3ceb1dSskrll  *    Hewlett-Packard
366d3ceb1dSskrll  *
376d3ceb1dSskrll  */
386d3ceb1dSskrll 
396d3ceb1dSskrll #include <sys/cdefs.h>
40*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: asp.c,v 1.4 2021/08/07 16:18:55 thorpej Exp $");
416d3ceb1dSskrll 
426d3ceb1dSskrll #include <sys/param.h>
436d3ceb1dSskrll #include <sys/systm.h>
446d3ceb1dSskrll #include <sys/device.h>
456d3ceb1dSskrll #include <sys/reboot.h>
466d3ceb1dSskrll 
476d3ceb1dSskrll #include <sys/bus.h>
486d3ceb1dSskrll #include <machine/iomod.h>
496d3ceb1dSskrll #include <machine/autoconf.h>
506d3ceb1dSskrll #include <machine/cpufunc.h>
516d3ceb1dSskrll 
526d3ceb1dSskrll #include <hppa/hppa/machdep.h>
536d3ceb1dSskrll #include <hppa/dev/cpudevs.h>
546d3ceb1dSskrll #include <hppa/dev/viper.h>
556d3ceb1dSskrll 
566d3ceb1dSskrll #include <hppa/gsc/gscbusvar.h>
576d3ceb1dSskrll 
586d3ceb1dSskrll struct asp_hwr {
596d3ceb1dSskrll 	uint8_t asp_reset;
606d3ceb1dSskrll 	uint8_t asp_resv[31];
616d3ceb1dSskrll 	uint8_t asp_version;
626d3ceb1dSskrll 	uint8_t asp_resv1[15];
636d3ceb1dSskrll 	uint8_t asp_scsidsync;
646d3ceb1dSskrll 	uint8_t asp_resv2[15];
656d3ceb1dSskrll 	uint8_t asp_error;
666d3ceb1dSskrll };
676d3ceb1dSskrll 
686d3ceb1dSskrll struct asp_trs {
696d3ceb1dSskrll 	uint32_t asp_irr;
706d3ceb1dSskrll 	uint32_t asp_imr;
716d3ceb1dSskrll 	uint32_t asp_ipr;
726d3ceb1dSskrll 	uint32_t asp_icr;
736d3ceb1dSskrll 	uint32_t asp_iar;
746d3ceb1dSskrll 	uint32_t asp_resv[3];
756d3ceb1dSskrll 	uint8_t  asp_cled;
766d3ceb1dSskrll 	uint8_t  asp_resv1[3];
776d3ceb1dSskrll 	struct {
786d3ceb1dSskrll 		u_int		:20,
796d3ceb1dSskrll 			asp_spu	: 3,	/* SPU ID board jumper */
806d3ceb1dSskrll #define	ASP_SPUCOBRA	0
816d3ceb1dSskrll #define	ASP_SPUCORAL	1
826d3ceb1dSskrll #define	ASP_SPUBUSH	2
836d3ceb1dSskrll #define	ASP_SPUHARDBALL	3
846d3ceb1dSskrll #define	ASP_SPUSCORPIO	4
856d3ceb1dSskrll #define	ASP_SPUCORAL2	5
866d3ceb1dSskrll 			asp_sw	: 1,	/* front switch is normal */
876d3ceb1dSskrll 			asp_clk : 1,	/* SCSI clock is doubled */
886d3ceb1dSskrll 			asp_lan : 2,	/* LAN iface selector */
896d3ceb1dSskrll #define	ASP_LANINVAL	0
906d3ceb1dSskrll #define	ASP_LANAUI	1
916d3ceb1dSskrll #define	ASP_LANTHIN	2
926d3ceb1dSskrll #define	ASP_LANMISS	3
936d3ceb1dSskrll 			asp_lanf: 1,	/* LAN AUI fuse is ok */
946d3ceb1dSskrll 			asp_spwr: 1,	/* SCSI power ok */
956d3ceb1dSskrll 			asp_scsi: 3;	/* SCSI ctrl ID */
966d3ceb1dSskrll 	} _asp_ios;
976d3ceb1dSskrll #define	asp_spu		_asp_ios.asp_spu
986d3ceb1dSskrll #define	asp_sw		_asp_ios.asp_sw
996d3ceb1dSskrll #define	asp_clk		_asp_ios.asp_clk
1006d3ceb1dSskrll #define	asp_lan		_asp_ios.asp_lan
1016d3ceb1dSskrll #define	asp_lanf	_asp_ios.asp_lanf
1026d3ceb1dSskrll #define	asp_spwr	_asp_ios.asp_spwr
1036d3ceb1dSskrll #define	asp_scsi	_asp_ios.asp_scsi
1046d3ceb1dSskrll };
1056d3ceb1dSskrll 
1066d3ceb1dSskrll #define	ASP_BANK_SZ	0x02000000
1076d3ceb1dSskrll #define	ASP_REG_INT	0x00800000
1086d3ceb1dSskrll #define	ASP_ETHER_ADDR	0x00810000
1096d3ceb1dSskrll #define	ASP_REG_MISC	0x0082f000
1106d3ceb1dSskrll 
1116d3ceb1dSskrll const struct asp_spus_tag {
1126d3ceb1dSskrll 	char	name[12];
1136d3ceb1dSskrll 	int	ledword;
1146d3ceb1dSskrll } asp_spus[] = {
1156d3ceb1dSskrll 	{ "Cobra", 0 },
1166d3ceb1dSskrll 	{ "Coral", 0 },
1176d3ceb1dSskrll 	{ "Bushmaster", 0 },
1186d3ceb1dSskrll 	{ "Hardball", 1 },
1196d3ceb1dSskrll 	{ "Scorpio", 0 },
1206d3ceb1dSskrll 	{ "Coral II", 1 },
1216d3ceb1dSskrll 	{ "#6", 0 },
1226d3ceb1dSskrll 	{ "#7", 0 }
1236d3ceb1dSskrll };
1246d3ceb1dSskrll 
1256d3ceb1dSskrll struct asp_softc {
1266d3ceb1dSskrll 	device_t sc_dev;
1276d3ceb1dSskrll 
1286d3ceb1dSskrll 	struct hppa_interrupt_register sc_ir;
1296d3ceb1dSskrll 
1306d3ceb1dSskrll 	volatile struct asp_hwr *sc_hw;
1316d3ceb1dSskrll 	volatile struct asp_trs *sc_trs;
1326d3ceb1dSskrll };
1336d3ceb1dSskrll 
1346d3ceb1dSskrll int	aspmatch(device_t, cfdata_t, void *);
1356d3ceb1dSskrll void	aspattach(device_t, device_t, void *);
1366d3ceb1dSskrll 
1376d3ceb1dSskrll CFATTACH_DECL_NEW(asp, sizeof(struct asp_softc),
1386d3ceb1dSskrll     aspmatch, aspattach, NULL, NULL);
1396d3ceb1dSskrll 
1406d3ceb1dSskrll /*
1416d3ceb1dSskrll  * Before a module is matched, this fixes up its gsc_attach_args.
1426d3ceb1dSskrll  */
1436d3ceb1dSskrll static void asp_fix_args(void *, struct gsc_attach_args *);
1446d3ceb1dSskrll static void
asp_fix_args(void * _sc,struct gsc_attach_args * ga)1456d3ceb1dSskrll asp_fix_args(void *_sc, struct gsc_attach_args *ga)
1466d3ceb1dSskrll {
1476d3ceb1dSskrll 	hppa_hpa_t module_offset;
1486d3ceb1dSskrll 	struct asp_softc *sc = _sc;
1496d3ceb1dSskrll 
1506d3ceb1dSskrll 	/*
1516d3ceb1dSskrll 	 * Determine this module's interrupt bit.
1526d3ceb1dSskrll 	 */
1536d3ceb1dSskrll 	module_offset = ga->ga_hpa - (hppa_hpa_t) sc->sc_trs;
1546d3ceb1dSskrll 	ga->ga_irq = HPPACF_IRQ_UNDEF;
1556d3ceb1dSskrll #define ASP_IRQ(off, irq) if (module_offset == off) ga->ga_irq = irq
1566d3ceb1dSskrll 	ASP_IRQ(0x22000, 6);	/* com1 */
1576d3ceb1dSskrll 	ASP_IRQ(0x23000, 5);	/* com0 */
1586d3ceb1dSskrll 	ASP_IRQ(0x24000, 7);	/* lpt */
1596d3ceb1dSskrll 	ASP_IRQ(0x25000, 9);	/* osiop */
1606d3ceb1dSskrll 	ASP_IRQ(0x26000, 8);	/* ie */
1616d3ceb1dSskrll 	ASP_IRQ(0x30000, 3);	/* siop */
1626d3ceb1dSskrll 	ASP_IRQ(0x800000, 13);	/* harmony */
1636d3ceb1dSskrll #undef ASP_IRQ
1646d3ceb1dSskrll }
1656d3ceb1dSskrll 
1666d3ceb1dSskrll int
aspmatch(device_t parent,cfdata_t cf,void * aux)1676d3ceb1dSskrll aspmatch(device_t parent, cfdata_t cf, void *aux)
1686d3ceb1dSskrll {
1696d3ceb1dSskrll 	struct confargs *ca = aux;
1706d3ceb1dSskrll 
1716d3ceb1dSskrll 	if (ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
1726d3ceb1dSskrll 	    ca->ca_type.iodc_sv_model != HPPA_BHA_ASP)
1736d3ceb1dSskrll 		return 0;
1746d3ceb1dSskrll 
1756d3ceb1dSskrll 	/*
1766d3ceb1dSskrll 	 * Forcibly mask the HPA down to the start of the ASP
1776d3ceb1dSskrll 	 * chip address space.
1786d3ceb1dSskrll 	 */
1796d3ceb1dSskrll 	ca->ca_hpa &= ~(ASP_BANK_SZ - 1);
1806d3ceb1dSskrll 
1816d3ceb1dSskrll 	return 1;
1826d3ceb1dSskrll }
1836d3ceb1dSskrll 
1846d3ceb1dSskrll void
aspattach(device_t parent,device_t self,void * aux)1856d3ceb1dSskrll aspattach(device_t parent, device_t self, void *aux)
1866d3ceb1dSskrll {
1876d3ceb1dSskrll 	struct confargs *ca = aux;
1886d3ceb1dSskrll 	struct asp_softc *sc = device_private(self);
1896d3ceb1dSskrll 	struct gsc_attach_args ga;
1906d3ceb1dSskrll 	struct cpu_info *ci = &cpus[0];
1916d3ceb1dSskrll 	bus_space_handle_t ioh;
1926d3ceb1dSskrll 	int s;
1936d3ceb1dSskrll 
1946d3ceb1dSskrll 	sc->sc_dev = self;
1956d3ceb1dSskrll 
1966d3ceb1dSskrll 	ca->ca_irq = hppa_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
1976d3ceb1dSskrll 	if (ca->ca_irq == HPPACF_IRQ_UNDEF) {
1986d3ceb1dSskrll 		aprint_error_dev(self, ": can't allocate interrupt");
1996d3ceb1dSskrll 		return;
2006d3ceb1dSskrll 	}
2016d3ceb1dSskrll 
2026d3ceb1dSskrll 	/*
2036d3ceb1dSskrll 	 * Map the ASP interrupt registers.
2046d3ceb1dSskrll 	 */
2056d3ceb1dSskrll 	if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_REG_INT,
2066d3ceb1dSskrll 	    sizeof(struct asp_trs), 0, &ioh)) {
2076d3ceb1dSskrll 		aprint_error(": can't map interrupt registers.\n");
2086d3ceb1dSskrll 		return;
2096d3ceb1dSskrll 	}
2106d3ceb1dSskrll 	sc->sc_trs = (struct asp_trs *)ioh;
2116d3ceb1dSskrll 
2126d3ceb1dSskrll 	/*
2136d3ceb1dSskrll 	 * Map the ASP miscellaneous registers.
2146d3ceb1dSskrll 	 */
2156d3ceb1dSskrll 	if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_REG_MISC,
2166d3ceb1dSskrll 			  sizeof(struct asp_hwr), 0, &ioh)) {
2176d3ceb1dSskrll 		aprint_error(": can't map miscellaneous registers.\n");
2186d3ceb1dSskrll 		return;
2196d3ceb1dSskrll 	}
2206d3ceb1dSskrll 	sc->sc_hw = (struct asp_hwr *)ioh;
2216d3ceb1dSskrll 
2226d3ceb1dSskrll 	/*
2236d3ceb1dSskrll 	 * Map the Ethernet address and read it out.
2246d3ceb1dSskrll 	 */
2256d3ceb1dSskrll 	if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_ETHER_ADDR,
2266d3ceb1dSskrll 			  sizeof(ga.ga_ether_address), 0, &ioh)) {
2276d3ceb1dSskrll 		aprint_error(": can't map EEPROM.\n");
2286d3ceb1dSskrll 		return;
2296d3ceb1dSskrll 	}
2306d3ceb1dSskrll 	bus_space_read_region_1(ca->ca_iot, ioh, 0,
2316d3ceb1dSskrll 		ga.ga_ether_address, sizeof(ga.ga_ether_address));
2326d3ceb1dSskrll 	bus_space_unmap(ca->ca_iot, ioh, sizeof(ga.ga_ether_address));
2336d3ceb1dSskrll 
2346d3ceb1dSskrll #ifdef USELEDS
2356d3ceb1dSskrll 	machine_ledaddr = &sc->sc_trs->asp_cled;
2366d3ceb1dSskrll 	machine_ledword = asp_spus[sc->sc_trs->asp_spu].ledword;
2376d3ceb1dSskrll #endif
2386d3ceb1dSskrll 
2396d3ceb1dSskrll 	/* reset ASP */
2406d3ceb1dSskrll 	/* sc->sc_hw->asp_reset = 1; */
2416d3ceb1dSskrll 	/* delay(400000); */
2426d3ceb1dSskrll 
2436d3ceb1dSskrll 	s = splhigh();
2446d3ceb1dSskrll 	viper_setintrwnd(1 << ca->ca_irq);
2456d3ceb1dSskrll 
2466d3ceb1dSskrll 	sc->sc_trs->asp_imr = 0;
247fc85ec4fSskrll 	(void)sc->sc_trs->asp_irr;
2486d3ceb1dSskrll 
2496d3ceb1dSskrll 	/* Establish the interrupt register. */
2506d3ceb1dSskrll 	hppa_interrupt_register_establish(ci, &sc->sc_ir);
2516d3ceb1dSskrll 	sc->sc_ir.ir_name = device_xname(self);
2526d3ceb1dSskrll 	sc->sc_ir.ir_mask = &sc->sc_trs->asp_imr;
2536d3ceb1dSskrll 	sc->sc_ir.ir_req = &sc->sc_trs->asp_irr;
2546d3ceb1dSskrll 
2556d3ceb1dSskrll 	splx(s);
2566d3ceb1dSskrll 
2576d3ceb1dSskrll 	aprint_normal(": %s rev %d, lan %d scsi %d\n",
2586d3ceb1dSskrll 	    asp_spus[sc->sc_trs->asp_spu].name, sc->sc_hw->asp_version,
2596d3ceb1dSskrll 	    sc->sc_trs->asp_lan, sc->sc_trs->asp_scsi);
2606d3ceb1dSskrll 
2616d3ceb1dSskrll 	/* Attach the GSC bus. */
2626d3ceb1dSskrll 	ga.ga_ca = *ca;	/* clone from us */
2636d3ceb1dSskrll 	if (strcmp(device_xname(parent), "mainbus0") == 0) {
2646d3ceb1dSskrll 		ga.ga_dp.dp_bc[0] = ga.ga_dp.dp_bc[1];
2656d3ceb1dSskrll 		ga.ga_dp.dp_bc[1] = ga.ga_dp.dp_bc[2];
2666d3ceb1dSskrll 		ga.ga_dp.dp_bc[2] = ga.ga_dp.dp_bc[3];
2676d3ceb1dSskrll 		ga.ga_dp.dp_bc[3] = ga.ga_dp.dp_bc[4];
2686d3ceb1dSskrll 		ga.ga_dp.dp_bc[4] = ga.ga_dp.dp_bc[5];
2696d3ceb1dSskrll 		ga.ga_dp.dp_bc[5] = ga.ga_dp.dp_mod;
2706d3ceb1dSskrll 		ga.ga_dp.dp_mod = 0;
2716d3ceb1dSskrll 	}
2726d3ceb1dSskrll 
2736d3ceb1dSskrll 	ga.ga_name = "gsc";
2746d3ceb1dSskrll 	ga.ga_ir = &sc->sc_ir;
2756d3ceb1dSskrll 	ga.ga_fix_args = asp_fix_args;
2766d3ceb1dSskrll 	ga.ga_fix_args_cookie = sc;
2776d3ceb1dSskrll 	ga.ga_scsi_target = sc->sc_trs->asp_scsi;
278*c7fb772bSthorpej 	config_found(self, &ga, gscprint, CFARGS_NONE);
2796d3ceb1dSskrll }
280