xref: /netbsd-src/sys/arch/amiga/dev/p5bus.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*      $NetBSD: p5bus.c,v 1.6 2021/08/07 16:18:41 thorpej Exp $ */
2363ad7afSrkujawa 
3363ad7afSrkujawa /*-
4363ad7afSrkujawa  * Copyright (c) 2011, 2012 The NetBSD Foundation, Inc.
5363ad7afSrkujawa  * All rights reserved.
6363ad7afSrkujawa  *
7363ad7afSrkujawa  * This code is derived from software contributed to The NetBSD Foundation
8363ad7afSrkujawa  * by Radoslaw Kujawa.
9363ad7afSrkujawa  *
10363ad7afSrkujawa  * Redistribution and use in source and binary forms, with or without
11363ad7afSrkujawa  * modification, are permitted provided that the following conditions
12363ad7afSrkujawa  * are met:
13363ad7afSrkujawa  * 1. Redistributions of source code must retain the above copyright
14363ad7afSrkujawa  *    notice, this list of conditions and the following disclaimer.
15363ad7afSrkujawa  * 2. Redistributions in binary form must reproduce the above copyright
16363ad7afSrkujawa  *    notice, this list of conditions and the following disclaimer in the
17363ad7afSrkujawa  *    documentation and/or other materials provided with the distribution.
18363ad7afSrkujawa  *
19363ad7afSrkujawa  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20363ad7afSrkujawa  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21363ad7afSrkujawa  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22363ad7afSrkujawa  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23363ad7afSrkujawa  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24363ad7afSrkujawa  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25363ad7afSrkujawa  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26363ad7afSrkujawa  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27363ad7afSrkujawa  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28363ad7afSrkujawa  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29363ad7afSrkujawa  * POSSIBILITY OF SUCH DAMAGE.
30363ad7afSrkujawa  */
31363ad7afSrkujawa 
32363ad7afSrkujawa /* Driver for internal BlizzardPPC, CyberStorm Mk-III/PPC bus. */
33363ad7afSrkujawa 
34363ad7afSrkujawa #include <sys/cdefs.h>
35363ad7afSrkujawa 
36363ad7afSrkujawa #include <sys/systm.h>
37363ad7afSrkujawa #include <sys/types.h>
38363ad7afSrkujawa #include <sys/device.h>
39363ad7afSrkujawa #include <sys/kmem.h>
40363ad7afSrkujawa 
41363ad7afSrkujawa #include <amiga/dev/zbusvar.h>
42363ad7afSrkujawa #include <amiga/dev/p5busvar.h>
43363ad7afSrkujawa 
44363ad7afSrkujawa #define ZORRO_MANID_P5		8512
45363ad7afSrkujawa #define ZORRO_PRODID_CSPPC	100
46363ad7afSrkujawa #define ZORRO_PRODID_BPPC	110
47363ad7afSrkujawa 
48363ad7afSrkujawa #define P5_ROM_OFF		0xF00010
49363ad7afSrkujawa #define P5_SN_LEN		7
50363ad7afSrkujawa 
51cbab9cadSchs static int	p5bus_match(device_t, cfdata_t, void *);
52cbab9cadSchs static void	p5bus_attach(device_t, device_t, void *);
53363ad7afSrkujawa static char*	p5bus_cardsn(void);
54363ad7afSrkujawa static int	p5bus_print(void *aux, const char *str);
55363ad7afSrkujawa static void	p5bus_callback(device_t self);
56363ad7afSrkujawa 
57363ad7afSrkujawa struct p5bus_softc {
58363ad7afSrkujawa 	device_t	sc_dev;
59363ad7afSrkujawa 	uint8_t		sc_cardtype;
60363ad7afSrkujawa 	uint8_t		sc_has_scsi;
61363ad7afSrkujawa #define P5BUS_SCSI_NONE	0
62363ad7afSrkujawa #define P5BUS_SCSI_710		1	/* NCR 53C710 */
63363ad7afSrkujawa #define P5BUS_SCSI_770		2	/* NCR 53C770 */
64363ad7afSrkujawa 	uint8_t		sc_has_ppc;
65363ad7afSrkujawa #define P5BUS_PPC_NONE		0	/* CS Mk-III only */
66363ad7afSrkujawa #define P5BUS_PPC_OK		1	/* has working PPC CPU */
67363ad7afSrkujawa };
68363ad7afSrkujawa 
69363ad7afSrkujawa CFATTACH_DECL_NEW(p5bus, sizeof(struct p5bus_softc),
70363ad7afSrkujawa     p5bus_match, p5bus_attach, NULL, NULL);
71363ad7afSrkujawa 
72363ad7afSrkujawa static int
p5bus_match(device_t parent,cfdata_t cf,void * aux)73cbab9cadSchs p5bus_match(device_t parent, cfdata_t cf, void *aux)
74363ad7afSrkujawa {
75363ad7afSrkujawa 	struct zbus_args *zap;
76363ad7afSrkujawa 
77cbab9cadSchs 	zap = aux;
78363ad7afSrkujawa 
79363ad7afSrkujawa 	if (zap->manid != ZORRO_MANID_P5)
80363ad7afSrkujawa 		return 0;
81363ad7afSrkujawa 
82363ad7afSrkujawa 
83363ad7afSrkujawa 	if ((zap->prodid != ZORRO_PRODID_BPPC) &&
84363ad7afSrkujawa 	    (zap->prodid != ZORRO_PRODID_CSPPC))
85363ad7afSrkujawa 		return 0;
86363ad7afSrkujawa 
87363ad7afSrkujawa 	return 1;
88363ad7afSrkujawa }
89363ad7afSrkujawa 
90363ad7afSrkujawa static void
p5bus_attach(device_t parent,device_t self,void * aux)91363ad7afSrkujawa p5bus_attach(device_t parent, device_t self, void *aux)
92363ad7afSrkujawa {
93363ad7afSrkujawa 	struct p5bus_softc *sc;
94363ad7afSrkujawa 	struct zbus_args *zap;
95363ad7afSrkujawa 	struct p5bus_attach_args p5baa;
96363ad7afSrkujawa 	char *sn;
97363ad7afSrkujawa 
98363ad7afSrkujawa 	zap = aux;
99363ad7afSrkujawa 	sc = device_private(self);
100363ad7afSrkujawa 	sc->sc_dev = self;
101363ad7afSrkujawa 
102363ad7afSrkujawa 	sn = p5bus_cardsn();
103363ad7afSrkujawa 
104363ad7afSrkujawa 	aprint_normal(": Phase5 PowerUP on-board bus\n");
105363ad7afSrkujawa 
106363ad7afSrkujawa 	/* "Detect" what devices are present and attach the right drivers. */
107363ad7afSrkujawa 
108363ad7afSrkujawa 	if (zap->prodid == ZORRO_PRODID_CSPPC) {
109363ad7afSrkujawa 
110363ad7afSrkujawa 		if (sn[0] == 'F') {
111363ad7afSrkujawa 			aprint_normal_dev(sc->sc_dev,
112363ad7afSrkujawa 			    "CyberStorm Mk-III (sn %s)\n", sn);
113363ad7afSrkujawa 			sc->sc_has_ppc = P5BUS_PPC_NONE;
114363ad7afSrkujawa 		} else {
115363ad7afSrkujawa 			aprint_normal_dev(sc->sc_dev,
116363ad7afSrkujawa 			    "CyberStorm PPC 604e (sn %s)\n", sn);
117363ad7afSrkujawa 			sc->sc_has_ppc = P5BUS_PPC_OK;
118363ad7afSrkujawa 		}
119363ad7afSrkujawa 
120363ad7afSrkujawa 		sc->sc_cardtype = P5_CARDTYPE_CS;
121363ad7afSrkujawa 		sc->sc_has_scsi = P5BUS_SCSI_770;
122363ad7afSrkujawa 
123363ad7afSrkujawa 	} else if (zap->prodid == ZORRO_PRODID_BPPC) {
124363ad7afSrkujawa 
1251502adf2Srkujawa 		if (sn[0] != 'I') {	/* only "+" model has SCSI */
126363ad7afSrkujawa 			aprint_normal_dev(sc->sc_dev,
127363ad7afSrkujawa 			    "BlizzardPPC 603e (sn %s)\n", sn);
128363ad7afSrkujawa 			sc->sc_has_scsi = P5BUS_SCSI_NONE;
129363ad7afSrkujawa 		} else {
130363ad7afSrkujawa 			aprint_normal_dev(sc->sc_dev,
131363ad7afSrkujawa 			    "BlizzardPPC 603e+ (sn %s)\n", sn);
132363ad7afSrkujawa 			sc->sc_has_scsi = P5BUS_SCSI_710;
133363ad7afSrkujawa 		}
134363ad7afSrkujawa 
135363ad7afSrkujawa 		sc->sc_cardtype = P5_CARDTYPE_BPPC;
136363ad7afSrkujawa 		sc->sc_has_ppc = P5BUS_PPC_OK;
137363ad7afSrkujawa 
138363ad7afSrkujawa 	}
139363ad7afSrkujawa 
140363ad7afSrkujawa 	p5baa.p5baa_cardtype = sc->sc_cardtype;
141363ad7afSrkujawa 
142363ad7afSrkujawa 	/* Attach the SCSI host adapters. */
143363ad7afSrkujawa 	switch (sc->sc_has_scsi) {
144363ad7afSrkujawa 	case P5BUS_SCSI_710:
145363ad7afSrkujawa 		strcpy(p5baa.p5baa_name, "bppcsc");
146*c7fb772bSthorpej 		config_found(sc->sc_dev, &p5baa, p5bus_print, CFARGS_NONE);
147363ad7afSrkujawa 		break;
148363ad7afSrkujawa 	case P5BUS_SCSI_770:
149363ad7afSrkujawa 		strcpy(p5baa.p5baa_name, "cbiiisc");
150*c7fb772bSthorpej 		config_found(sc->sc_dev, &p5baa, p5bus_print, CFARGS_NONE);
151363ad7afSrkujawa 		break;
152363ad7afSrkujawa 	default:
153363ad7afSrkujawa 		break;
154363ad7afSrkujawa 	}
155363ad7afSrkujawa 
156363ad7afSrkujawa 	/*
157363ad7afSrkujawa 	 * We need to wait for possible p5membar attachments. Defer the rest
158363ad7afSrkujawa 	 * until parent (zbus) is completely configured.
159363ad7afSrkujawa 	 */
160363ad7afSrkujawa 	config_defer(self, p5bus_callback);
161363ad7afSrkujawa 
162363ad7afSrkujawa }
163363ad7afSrkujawa 
164363ad7afSrkujawa /* Continue the attachment. */
165363ad7afSrkujawa static void
p5bus_callback(device_t self)166363ad7afSrkujawa p5bus_callback(device_t self) {
167363ad7afSrkujawa 
168363ad7afSrkujawa 	struct p5bus_attach_args p5baa;
169363ad7afSrkujawa 	struct p5bus_softc *sc;
170363ad7afSrkujawa 
171363ad7afSrkujawa 	sc = device_private(self);
172363ad7afSrkujawa 	p5baa.p5baa_cardtype = sc->sc_cardtype;
173363ad7afSrkujawa 
1741502adf2Srkujawa 	/* p5pb is always found, probe is inside of p5pb driver */
175363ad7afSrkujawa 	strcpy(p5baa.p5baa_name, "p5pb");
176*c7fb772bSthorpej 	config_found(sc->sc_dev, &p5baa, p5bus_print, CFARGS_NONE);
177363ad7afSrkujawa }
178363ad7afSrkujawa 
179363ad7afSrkujawa /* Get serial number of the card. */
180363ad7afSrkujawa static char *
p5bus_cardsn(void)1811d7f24eaSmatt p5bus_cardsn(void)
182363ad7afSrkujawa {
183363ad7afSrkujawa 	char *snr, *sn;
184363ad7afSrkujawa 
185363ad7afSrkujawa 	sn = kmem_zalloc(P5_SN_LEN + 1, KM_SLEEP);
186363ad7afSrkujawa 	snr = (char *)__UNVOLATILE(ztwomap(P5_ROM_OFF));
187363ad7afSrkujawa 
188363ad7afSrkujawa 	memcpy(sn, snr, P5_SN_LEN);
189363ad7afSrkujawa 	return sn;
190363ad7afSrkujawa }
191363ad7afSrkujawa 
192363ad7afSrkujawa static int
p5bus_print(void * aux,const char * str)193363ad7afSrkujawa p5bus_print(void *aux, const char *str)
194363ad7afSrkujawa {
195363ad7afSrkujawa 	if (str == NULL)
196363ad7afSrkujawa 		return 0;
197363ad7afSrkujawa 
198363ad7afSrkujawa 	printf("%s ", str);
199363ad7afSrkujawa 
200363ad7afSrkujawa 	return 0;
201363ad7afSrkujawa }
202