xref: /netbsd-src/sys/arch/mac68k/nubus/cpi_nubus.c (revision c2d090fa74a790634b934c9d63ba18942f1fcee0)
1 /*	$NetBSD: cpi_nubus.c,v 1.11 2020/12/19 21:48:04 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (c) 2008 Hauke Fath
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c,v 1.11 2020/12/19 21:48:04 thorpej Exp $");
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/proc.h>
32 #include <sys/device.h>
33 #include <sys/kmem.h>
34 #include <sys/event.h>
35 #include <sys/callout.h>
36 #include <sys/conf.h>
37 #include <sys/file.h>
38 #include <sys/uio.h>
39 #include <sys/ioctl.h>
40 #include <sys/tty.h>
41 #include <sys/time.h>
42 #include <sys/timetc.h>
43 #include <sys/kernel.h>
44 #include <sys/syslog.h>
45 #include <sys/errno.h>
46 
47 #include <machine/intr.h>
48 #include <machine/bus.h>
49 #include <machine/viareg.h>
50 
51 #include <dev/ic/z8536reg.h>
52 #include <mac68k/nubus/nubus.h>
53 #include <mac68k/nubus/cpi_nubusvar.h>
54 
55 #include "ioconf.h"
56 
57 #ifdef DEBUG
58 #define CPI_DEBUG
59 #endif
60 
61 /*
62  * Stuff taken from Egan/Teixeira ch 8: 'if(TRACE_FOO)' debug output
63  * statements don't break indentation, and when DEBUG is not defined,
64  * the compiler code optimizer drops them as dead code.
65  */
66 #ifdef CPI_DEBUG
67 #define M_TRACE_CONFIG	0x0001
68 #define M_TRACE_OPEN	0x0002
69 #define M_TRACE_CLOSE	0x0004
70 #define M_TRACE_READ	0x0008
71 #define M_TRACE_WRITE	0x0010
72 #define M_TRACE_IOCTL	0x0020
73 #define M_TRACE_STATUS	0x0040
74 #define M_TRACE_TCNTR	0x0080
75 #define M_TRACE_ALL	0xFFFF
76 #define M_TRACE_NONE	0x0000
77 
78 #define TRACE_CONFIG	(cpi_debug_mask & M_TRACE_CONFIG)
79 #define TRACE_OPEN	(cpi_debug_mask & M_TRACE_OPEN)
80 #define TRACE_CLOSE	(cpi_debug_mask & M_TRACE_CLOSE)
81 #define TRACE_READ	(cpi_debug_mask & M_TRACE_READ)
82 #define TRACE_WRITE	(cpi_debug_mask & M_TRACE_WRITE)
83 #define TRACE_IOCTL	(cpi_debug_mask & M_TRACE_IOCTL)
84 #define TRACE_STATUS	(cpi_debug_mask & M_TRACE_STATUS)
85 #define TRACE_TCNTR	(cpi_debug_mask & M_TRACE_TCNTR)
86 #define TRACE_ALL	(cpi_debug_mask & M_TRACE_ALL)
87 #define TRACE_NONE	(cpi_debug_mask & M_TRACE_NONE)
88 
89 uint32_t cpi_debug_mask = M_TRACE_NONE /* | M_TRACE_TCNTR | M_TRACE_WRITE */ ;
90 #else /* CPI_DEBUG */
91 #define TRACE_CONFIG	0
92 #define TRACE_OPEN	0
93 #define TRACE_CLOSE	0
94 #define TRACE_READ	0
95 #define TRACE_WRITE	0
96 #define TRACE_IOCTL	0
97 #define TRACE_STATUS	0
98 #define TRACE_TCNTR	0
99 #define TRACE_ALL	0
100 #define TRACE_NONE	0
101 #endif /* CPI_DEBUG */
102 
103 /* autoconf interface */
104 int cpi_nubus_match(device_t, cfdata_t, void *);
105 void cpi_nubus_attach(device_t, device_t, void *);
106 void cpi_nubus_intr(void *);
107 
108 CFATTACH_DECL_NEW(cpi, sizeof(struct cpi_softc),
109     cpi_nubus_match, cpi_nubus_attach, NULL, NULL);
110 
111 dev_type_open(cpi_open);
112 dev_type_close(cpi_close);
113 dev_type_read(cpi_read);
114 dev_type_write(cpi_write);
115 dev_type_ioctl(cpi_ioctl);
116 
117 const struct cdevsw cpi_cdevsw = {
118 	.d_open = cpi_open,
119 	.d_close = cpi_close,
120 	.d_read = noread,
121 	.d_write = cpi_write,
122 	.d_ioctl = cpi_ioctl,
123 	.d_stop = nostop,
124 	.d_tty = notty,
125 	.d_poll = nopoll,
126 	.d_mmap = nommap,
127 	.d_kqfilter = nokqfilter,
128 	.d_discard = nodiscard,
129 	.d_flag = D_OTHER
130 };
131 
132 /* prototypes */
133 static void cpi_lpreset(struct cpi_softc *);
134 static int cpi_notready(struct cpi_softc *);
135 static void cpi_wakeup(void *);
136 static int cpi_flush(struct cpi_softc *);
137 static void cpi_intr(void *);
138 
139 static void cpi_tc_initclock(struct cpi_softc *);
140 static uint cpi_get_timecount(struct timecounter *);
141 static uint z8536_read_counter1(bus_space_tag_t, bus_space_handle_t);
142 static uint z8536_read_counter2(bus_space_tag_t, bus_space_handle_t);
143 static void z8536_reg_set(bus_space_tag_t, bus_space_handle_t,
144     uint8_t, uint8_t);
145 static uint8_t z8536_reg_get(bus_space_tag_t, bus_space_handle_t,
146     uint8_t);
147 
148 
149 const uint8_t cio_reset[] = {
150 	/* register	value */
151 	Z8536_MICR, 	0x00,
152 	Z8536_MICR, 	MICR_RESET,
153 	Z8536_MICR, 	0x00
154 };
155 
156 const uint8_t cio_init[] = {
157 	/* register	value */
158 
159 	/* Interrupt vectors - clear all */
160 	Z8536_IVRA, 	0x00,
161 	Z8536_IVRB, 	0x00,
162 	Z8536_IVRCT, 	0x20 /* ??? Do we use this? */,
163 
164 	/*
165 	 * Port A specification - bit port, single buffered,
166 	 * latched output, pulsed handshake, all bits non-inverting
167 	 * non-special I/O
168 	 */
169 	Z8536_PMSRA, 	PMSR_PTS_OUT | PMSR_LPM,
170 	Z8536_PHSRA, 	PHSR_HTS_PUL,
171 	Z8536_DPPRA, 	0x00,
172 	Z8536_DDRA, 	0x00,
173 	Z8536_SIOCRA, 	0x00,
174 
175 	/*
176 	 * Port B specification - bit port, transparent output,
177 	 * pulsed handshake, all bits non-inverting
178 	 * bits 0, 4 output; bits 1-3, 5-8 input,
179 	 * non-special I/O
180 	 * Pattern matching: Bit 6 (BUSY) matching "1"
181 	 * Alternatively: Bit 3 (/ACK) matching "0"
182 	 */
183 	Z8536_PMSRB, 	PMSR_PMS_OR_PEV,
184 	Z8536_PHSRB, 	0x00,
185 	Z8536_DPPRB, 	0x00,
186 	Z8536_DDRB, 	0xee /*11101110b*/,
187 	Z8536_SIOCRB, 	0x00,
188 	Z8536_PPRB, 	0x00,
189 	Z8536_PTRB, 	0x00,
190 	Z8536_PMRB, 	0x40 /*01000000b = PB6 */,
191 
192 	Z8536_PDRB, 	0xFE,	/* Assign printer -RESET */
193 	Z8536_PCSRA, 	0x00,	/* Clear port A interrupt bits */
194 
195 	/*
196 	 * Port C specification - bit 3 out, bits 0-2 in,
197 	 * all 4 non-inverting, non-special I/O
198 	 */
199 	Z8536_DDRC, 	0x07 /*00000111b*/,
200 	Z8536_DPPRC, 	0x00,
201 	Z8536_SIOCRC, 	0x00,
202 
203 	/*
204 	 * We need Timer 3 for running port A in strobed mode.
205 	 *
206 	 * Counter/Timer 3 specification -- clear IP & IUS, trigger +
207 	 * gate command bit, one-shot operation
208 	 */
209 	Z8536_CTCSR3, 	CTCS_CLR_IP_IUS | CTCS_GCB | CTCS_TCB,
210 	Z8536_CTMSR3, 	CTMS_DCS_ONESHOT,
211 	Z8536_CTTCR3_MSB, 0x00,
212 	Z8536_CTTCR3_LSB, 0x03,
213 
214 	/* Enable ports A+B+C+CT3 */
215 	Z8536_MCCR,	MCCR_PAE | MCCR_PBE | MCCR_PC_CT3E,
216 
217 	/* Master Interrupt Enable, Disable Lower Chain,
218 	 * No Interrupt Vector, port A+B+CT vectors include status */
219 	Z8536_MICR,  	MICR_MIE | MICR_DLC | MICR_NV | MICR_PAVIS |
220 	MICR_PBVIS | MICR_CTVIS,
221 	Z8536_PDRB, 	0xFE,	/* Clear printer -RESET */
222 };
223 
224 /* CPI default options */
225 /* int	cpi_options = 0 | CPI_CTC12_IS_TIMECOUNTER; */
226 
227 
228 /*
229  * Look for Creative Systems Inc. "Hurdler Centronics Parallel Interface"
230  */
231 int
cpi_nubus_match(device_t parent,cfdata_t cf,void * aux)232 cpi_nubus_match(device_t parent, cfdata_t cf, void *aux)
233 {
234 	struct nubus_attach_args *na;
235 
236 	na = aux;
237 	if ((na->category == NUBUS_CATEGORY_COMMUNICATIONS) &&
238 	    (na->type == NUBUS_TYPE_CENTRONICS) &&
239 	    (na->drsw == NUBUS_DRSW_CPI) &&
240 	    (na->drhw == NUBUS_DRHW_CPI))
241 		return 1;
242 	else
243 		return 0;
244 }
245 
246 void
cpi_nubus_attach(device_t parent,device_t self,void * aux)247 cpi_nubus_attach(device_t parent, device_t self, void *aux)
248 {
249 	struct cpi_softc *sc;
250 	struct nubus_attach_args *na;
251 	int err, ii;
252 
253 	sc = device_private(self);
254 	sc->sc_options = (device_cfdata(self)->cf_flags & CPI_OPTIONS_MASK);
255 
256 	na = aux;
257 	sc->sc_bst = na->na_tag;
258 	memcpy(&sc->sc_slot, na->fmt, sizeof(nubus_slot));
259 	sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot);
260 
261 	/*
262 	 * The CIO sits eight bit wide on the top byte lane of
263 	 * Nubus, so map 16 byte.
264 	 */
265 	if (TRACE_CONFIG) {
266 		printf("\n");
267 		printf("\tcpi_nubus_attach() mapping 8536 CIO at 0x%lx.\n",
268 		    sc->sc_basepa + CIO_BASE_OFFSET);
269 	}
270 
271 	err = bus_space_map(sc->sc_bst, sc->sc_basepa + CIO_BASE_OFFSET,
272 	    (Z8536_IOSIZE << 4), 0, &sc->sc_bsh);
273 	if (err) {
274 		aprint_normal(": failed to map memory space.\n");
275 		return;
276 	}
277 
278 	sc->sc_lpstate = LP_INITIAL;
279 	sc->sc_intcount = 0;
280 	sc->sc_bytestoport = 0;
281 
282 	if (TRACE_CONFIG)
283 		printf("\tcpi_nubus_attach() about to set up 8536 CIO.\n");
284 
285 	for (ii = 0; ii < sizeof(cio_reset); ii += 2)
286 		z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_reset[ii],
287 		    cio_reset[ii + 1]);
288 
289 	delay(1000);		/* Give the CIO time to set itself up */
290 	for (ii = 0; ii < sizeof(cio_init); ii += 2) {
291 		z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_init[ii],
292 		    cio_init[ii + 1]);
293 	}
294 
295 	if (TRACE_CONFIG)
296 		printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n");
297 
298 	/* XXX Get information strings from the card ROM */
299 	aprint_normal(": CSI Hurdler II Centronics\n");
300 
301 	/* Attach CIO timers 1+2 as timecounter */
302 	if (sc->sc_options & CPI_CTC12_IS_TIMECOUNTER) {
303 		cpi_tc_initclock(sc);
304 	}
305 
306 	callout_init(&sc->sc_wakeupchan, 0);	/* XXX */
307 
308 	/* make sure interrupts are vectored to us */
309 	add_nubus_intr(na->slot, cpi_nubus_intr, sc);
310 }
311 
312 void
cpi_nubus_intr(void * arg)313 cpi_nubus_intr(void *arg)
314 {
315         struct cpi_softc *sc;
316 	int s;
317 
318 	sc = (struct cpi_softc *)arg;
319 
320 	s = spltty();
321 
322 	sc->sc_intcount++;
323 
324 	/* Check for interrupt source, and clear interrupt */
325 
326 	/*
327 	 * Clear port A interrupt
328 	 * Interrupt from register A, clear "pending"
329 	 * and set "under service"
330 	 */
331 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IE);
332 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP);
333 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IUS);
334 
335 	cpi_intr(sc);
336 
337 	/* Interrupt from register A, mark serviced */
338 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IUS);
339 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IE);
340 
341 	splx(s);
342 }
343 
344 
345 /* cpi nuts and bolts */
346 
347 int
cpi_open(dev_t device,int flag,int mode,struct lwp * l)348 cpi_open(dev_t device, int flag, int mode, struct lwp *l)
349 {
350 	int err, ii, s;
351         struct cpi_softc *sc;
352 
353 	if (TRACE_OPEN)
354 		printf("\tcpi_open() called...\n");
355 
356 	/* Consistency checks: Valid unit number, softc, device state */
357 	sc = device_lookup_private(&cpi_cd, CPI_UNIT(device));
358 	if (NULL == sc) {
359 		if (TRACE_OPEN)
360 			printf("Tried to cpi_open() with NULL softc\n");
361 		return ENXIO;
362 	}
363 	if (sc->sc_lpstate != LP_INITIAL) {
364 		if (TRACE_OPEN)
365 			printf("Not in initial state (%x).\n",
366 			    sc->sc_lpstate);
367 		return EBUSY;
368 	}
369 	sc->sc_lpstate = LP_OPENING;
370 
371 	if (TRACE_OPEN)
372 		printf("\tcpi_open() resetting the printer...\n");
373 	cpi_lpreset(sc);
374 
375 	if (TRACE_OPEN)
376 		printf("\tcpi_open() waiting for printer ready...\n");
377 
378 	/* Wait max 15 sec for printer to get ready */
379 	for (ii = 15; cpi_notready(sc); ii--) {
380 		if (0 == ii) {
381 			sc->sc_lpstate = LP_INITIAL;
382 			return EBUSY;
383 		}
384 		/* sleep for a second, unless we get a signal */
385 		err = tsleep(sc, PZERO | PCATCH, "cpi_open", hz);
386 		if (err != EWOULDBLOCK) {
387 			sc->sc_lpstate = LP_INITIAL;
388 			return err;
389 		}
390 	}
391 	if (TRACE_OPEN)
392 		printf("\tcpi_open() allocating printer buffer...\n");
393 
394 	/* Allocate the driver's line buffer */
395 	sc->sc_printbuf = kmem_alloc(CPI_BUFSIZE, KM_SLEEP);
396 	sc->sc_bufbytes = 0;
397 	sc->sc_lpstate = LP_OPEN;
398 
399 	/* Statistics */
400 	sc->sc_intcount = 0;
401 	sc->sc_bytestoport = 0;
402 
403 	/* Kick off transfer */
404 	cpi_wakeup(sc);
405 
406 	/*
407 	 * Reset "interrupt {pending, under service}" bits, then
408 	 * enable Port A interrupts
409 	 */
410 	s = spltty();
411 
412 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP_IUS);
413 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_SET_IE);
414 	splx(s);
415 
416 	if (TRACE_OPEN)
417 		printf("\tcpi_open() done...\n");
418 
419 	return 0;
420 }
421 
422 int
cpi_close(dev_t device,int flag,int mode,struct lwp * l)423 cpi_close(dev_t device, int flag, int mode, struct lwp *l)
424 {
425         struct cpi_softc *sc;
426 
427 	sc = device_lookup_private(&cpi_cd, CPI_UNIT(device));
428 
429 	if (TRACE_CLOSE)
430 		printf("\tcpi_close() called (%lu hard, %lu bytes to port)\n",
431 		    sc->sc_intcount, sc->sc_bytestoport);
432 
433 	/* Flush the remaining buffer content, ignoring any errors */
434 	if (0 < sc->sc_bufbytes)
435 		(void)cpi_flush(sc);
436 
437 	callout_stop(&sc->sc_wakeupchan);
438 
439 	/* Disable Port A interrupts */
440 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IE);
441 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PCSRA, PCSR_CLR_IP_IUS);
442 
443 	sc->sc_lpstate = LP_INITIAL;
444 	kmem_free(sc->sc_printbuf, CPI_BUFSIZE);
445 
446 	return 0;
447 }
448 
449 int
cpi_write(dev_t device,struct uio * uio,int flags)450 cpi_write(dev_t device, struct uio *uio, int flags)
451 {
452 	int err;
453 	size_t numbytes;
454         struct cpi_softc *sc;
455 
456 	err = 0;
457 
458 	if (TRACE_WRITE)
459 		printf("\tcpi_write() called for %u bytes\n", uio->uio_resid);
460 
461 	sc = device_lookup_private(&cpi_cd, CPI_UNIT(device));
462 
463 	/* Send data to printer, a line buffer full at a time */
464 	while (uio->uio_resid > 0) {
465 		numbytes = uimin(CPI_BUFSIZE, uio->uio_resid);
466 		sc->sc_cp = sc->sc_printbuf;
467 		uiomove(sc->sc_cp, numbytes, uio);
468 		sc->sc_bufbytes = numbytes;
469 
470 		if (TRACE_WRITE)
471 			printf("\tQueuing %u bytes\n", numbytes);
472 		err = cpi_flush(sc);
473 		if (err) {
474 			/* Failure; adjust residual counter */
475 			if (TRACE_WRITE)
476 				printf("\tQueuing failed with %d\n", err);
477 			uio->uio_resid += sc->sc_bufbytes;
478 			sc->sc_bufbytes = 0;
479 			break;
480 		}
481 	}
482 	return err;
483 }
484 
485 int
cpi_ioctl(dev_t device,unsigned long cmd,void * data,int flag,struct lwp * l)486 cpi_ioctl(dev_t device, unsigned long cmd, void *data,
487     int flag, struct lwp *l)
488 {
489 	int err;
490 
491 	err = 0;
492 
493 	if (TRACE_IOCTL)
494 		printf("\tcpi_ioctl() called with %ld...\n", cmd);
495 
496 	switch (cmd) {
497 	default:
498 		if (TRACE_IOCTL)
499 			printf("\tcpi_ioctl() unknown ioctl %ld\n", cmd);
500 		err = ENODEV;
501 		break;
502 	}
503 	return err;
504 }
505 
506 /*
507  * Flush the print buffer that our top half uses to provide data to
508  * our bottom, interrupt-driven half.
509  */
510 static int
cpi_flush(struct cpi_softc * sc)511 cpi_flush(struct cpi_softc *sc)
512 {
513 	int err, s;
514 
515 	err = 0;
516 	while (0 < sc->sc_bufbytes) {
517 		/* Feed the printer a char, if it's ready */
518 		if ( !cpi_notready(sc)) {
519 			if (TRACE_WRITE)
520 				printf("\tcpi_flush() writes %u bytes "
521 				    "(%lu hard, %lu bytes to port)\n",
522 				    sc->sc_bufbytes, sc->sc_intcount,
523 				    sc->sc_bytestoport);
524 			s = spltty();
525 			cpi_intr(sc);
526 			splx(s);
527 		}
528 		/* XXX Sure we want to wait forever for the printer? */
529 		err = tsleep((void *)sc, PZERO | PCATCH,
530 		    "cpi_flush", (60 * hz));
531 	}
532 	return err;
533 }
534 
535 
536 static void
cpi_wakeup(void * param)537 cpi_wakeup(void *param)
538 {
539 	struct cpi_softc *sc;
540 	int s;
541 
542 	sc = param;
543 
544 	s = spltty();
545 	cpi_intr(sc);
546 	splx(s);
547 
548 	callout_reset(&sc->sc_wakeupchan, hz, cpi_wakeup, sc);
549 }
550 
551 
552 static void
cpi_lpreset(struct cpi_softc * sc)553 cpi_lpreset(struct cpi_softc *sc)
554 {
555 	uint8_t portb;		/* Centronics -RESET is on port B, bit 0 */
556 
557 	portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB);
558 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb & ~CPI_RESET);
559 	delay(100);
560 	portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB);
561 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb | CPI_RESET);
562 }
563 
564 
565 /*
566  * Centronics BUSY 		is on port B, bit 6
567  *	      SELECT		is on Port B, bit 5
568  *	      /FAULT		is on Port B, bit 1
569  *            PAPER EMPTY	is on Port C, bit 1
570  */
571 static int
cpi_notready(struct cpi_softc * sc)572 cpi_notready(struct cpi_softc *sc)
573 {
574 	uint8_t portb, portc;
575 	int is_busy, is_select, is_fault, is_paper_empty;
576 
577 	if (TRACE_STATUS)
578 		printf("\tcpi_notready() checking printer status...\n");
579 
580 	portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB);
581 	if (TRACE_STATUS)
582 		printf("\tPort B has 0x0%X\n", portb);
583 
584 	is_busy = CPI_BUSY & portb;
585 	if (TRACE_STATUS)
586 		printf("\t\tBUSY = %d\n", is_busy);
587 
588 	is_select = CPI_SELECT & portb;
589 	if (TRACE_STATUS)
590 		printf("\t\tSELECT = %d\n", is_select);
591 
592 	is_fault = CPI_FAULT & portb;
593 	if (TRACE_STATUS)
594 		printf("\t\t/FAULT = %d\n", is_fault);
595 
596 	portc = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTC);
597 	if (TRACE_STATUS)
598 		printf("\tPort C has 0x0%X\n", portc);
599 
600 	is_paper_empty = CPI_PAPER_EMPTY & portc;
601 	if (TRACE_STATUS)
602 		printf("\t\tPAPER EMPTY = %d\n", is_paper_empty);
603 
604 	return (is_busy || !is_select || !is_fault || is_paper_empty);
605 }
606 
607 static void
cpi_intr(void * arg)608 cpi_intr(void *arg)
609 {
610 	struct cpi_softc *sc;
611 
612 	sc = arg;
613 
614 	/* Printer ready for output? */
615 	if (cpi_notready(sc))
616 		return;
617 
618 	if (0 && TRACE_WRITE)
619 		printf("\tcpi_soft_intr() has %u bytes.\n", sc->sc_bufbytes);
620 
621 	/* Anything to print? */
622 	if (sc->sc_bufbytes) {
623 		/* Data byte */
624 		bus_space_write_1(sc->sc_bst, sc->sc_bsh,
625 		    CIO_PORTA, *sc->sc_cp++);
626 		sc->sc_bufbytes--;
627 		sc->sc_bytestoport++;
628 	}
629 	if (0 == sc->sc_bufbytes)
630 		/* line buffer empty, wake up our top half */
631 		wakeup((void *)sc);
632 }
633 
634 static void
cpi_tc_initclock(struct cpi_softc * sc)635 cpi_tc_initclock(struct cpi_softc *sc)
636 {
637 	uint8_t reg;
638 
639 	/*
640 	 * Set up c/t 1 and 2 as a single, free-running 32 bit counter
641 	 */
642 
643 	/* Disable counters 1 and 2 */
644 	reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR);
645 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR,
646 	    reg & ~(MCCR_CT1E | MCCR_CT2E));
647 
648 	/* Make sure interrupt enable bits are cleared */
649 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, CTCS_CLR_IE);
650 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, CTCS_CLR_IE);
651 
652 	/* Initialise counter start values, and set to continuous cycle */
653 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR1,
654 	    CTMS_CSC | CTMS_DCS_PULSE);
655 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_MSB, 0x00);
656 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_LSB, 0x00);
657 
658 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR2,
659 	    CTMS_CSC | CTMS_DCS_PULSE);
660 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_MSB, 0x00);
661 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_LSB, 0x00);
662 
663 	/* Link counters 1 and 2 */
664 	reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR);
665 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, reg | MCCR_CT1CT2);
666 
667 	/* Enable and counter pair */
668 	reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR);
669 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR,
670 	    reg | (MCCR_CT1E | MCCR_CT2E));
671 
672 	/* Start c/t 1; c/t 2 gets started by c/t 1 pulse */
673 	reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1);
674 	z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1,
675 	    CTCSR_MASK(reg | CTCS_TCB | CTCS_GCB));
676 
677 	if (TRACE_TCNTR) {
678 		printf("Before tc_init():\n");
679 		reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1);
680 		printf("Counter 1 CTCSR setup bits are 0x%03x\n", reg);
681 		printf("Counter 1 (LSW) is now 0x%05x\n",
682 		    z8536_read_counter1(sc->sc_bst, sc->sc_bsh));
683 		reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2);
684 		printf("Counter 2 CTCSR setup bits are 0x%03x\n", reg);
685 		printf("Counter 2 (MSW) is now 0x%05x\n",
686 		    z8536_read_counter2(sc->sc_bst, sc->sc_bsh));
687 
688 		delay(1000);
689 	}
690 
691 	sc->sc_timecounter.tc_get_timecount = cpi_get_timecount;
692 	sc->sc_timecounter.tc_poll_pps      = 0;
693 	sc->sc_timecounter.tc_counter_mask  = ~0u;
694 	sc->sc_timecounter.tc_frequency     = CPI_CLK_FREQ;
695 	sc->sc_timecounter.tc_name          = "Nubus CPI";
696 	sc->sc_timecounter.tc_quality       = 1000;
697 	/*
698 	 * Squirrel away the device's sc so we can talk
699 	 * to the CIO later
700 	 */
701 	sc->sc_timecounter.tc_priv          = sc;
702 	sc->sc_timecounter.tc_next          = NULL;
703 
704         tc_init(&(sc->sc_timecounter));
705 
706 	if (TRACE_TCNTR) {
707 		delay(1000);
708 
709 		printf("After tc_init():\n");
710 		reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1);
711 		printf("Counter 1 CTCSR setup bits are 0x%03x\n", reg);
712 		printf("Counter 1 (LSW) is now 0x%05x\n",
713 		    z8536_read_counter1(sc->sc_bst, sc->sc_bsh));
714 		reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2);
715 		printf("Counter 2 CTCSR setup bits are 0x%03x\n", reg);
716 		printf("Counter 2 (MSW) is now 0x%05x\n",
717 		    z8536_read_counter2(sc->sc_bst, sc->sc_bsh));
718 	}
719 }
720 
721 static u_int
cpi_get_timecount(struct timecounter * tc)722 cpi_get_timecount(struct timecounter *tc)
723 {
724         int s;
725 	uint msw, msw2, lsw;
726 	uint8_t reg;
727 	bus_space_tag_t bst;
728 	bus_space_handle_t bsh;
729 
730 	bst = ((struct cpi_softc *)tc->tc_priv)->sc_bst;
731 	bsh = ((struct cpi_softc *)tc->tc_priv)->sc_bsh;
732 	/*
733 	 * We run CIO counters 1 and 2 in an internally coupled mode,
734 	 * where the output of counter 1 (LSW) clocks counter 2 (MSW).
735 	 * The counters are buffered, and the buffers have to be
736 	 * locked before we can read out a consistent counter
737 	 * value. Reading the LSB releases the buffer lock.
738 	 *
739 	 * Unfortunately, there is no such mechanism between MSW and
740 	 * LSW of the coupled counter. To ensure a consistent
741 	 * read-out, we read the MSW, then the LSW, then re-read the
742 	 * MSW and compare with the old value. If we find that the MSW
743 	 * has just been incremented, we re-read the LSW. This avoids
744 	 * a race that could leave us with a new (just wrapped) LSW
745 	 * and an old MSW value.
746 	 *
747 	 * For simplicity, we roll the procedure into a loop - the
748 	 * rollover case is rare.
749 	 */
750 	do {
751 
752 #define delay(a)
753 
754 		/* Guard HW timer access */
755 		s = splhigh();
756 
757 		/* Lock counter 2 latch in preparation for read-out */
758 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2);
759 		delay(1);
760 		reg = bus_space_read_1(bst, bsh, CIO_CTRL);
761 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2);
762 		bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC));
763 
764 		/* Read out counter 2 MSB,then LSB (releasing the latch) */
765 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_MSB);
766 		delay(1);
767 		msw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8;
768 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_LSB);
769 		delay(1);
770 		msw |= bus_space_read_1(bst, bsh, CIO_CTRL);
771 
772 		/* Lock counter 1 latch in preparation for read-out */
773 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1);
774 		delay(1);
775 		reg = bus_space_read_1(bst, bsh, CIO_CTRL);
776 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1);
777 		bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg |CTCS_RCC));
778 
779 		/* Read out counter 1 MSB,then LSB (releasing the latch) */
780 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_MSB);
781 		delay(1);
782 		lsw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8;
783 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_LSB);
784 		delay(1);
785 		lsw |= bus_space_read_1(bst, bsh, CIO_CTRL);
786 
787 		/* Lock counter 2 latch in preparation for read-out */
788 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2);
789 		delay(1);
790 		reg = bus_space_read_1(bst, bsh, CIO_CTRL);
791 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2);
792 		bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC));
793 
794 		/* Read out counter 2 MSB,then LSB (releasing the latch) */
795 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_MSB);
796 		delay(1);
797 		msw2 = bus_space_read_1(bst, bsh, CIO_CTRL) << 8;
798 		bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_LSB);
799 		delay(1);
800 		msw2 |= bus_space_read_1(bst, bsh, CIO_CTRL);
801 
802 		splx(s);
803 
804 	} while (msw2 != msw);
805 
806 	/* timecounter expects an upward counter */
807 	return ~0u - ((msw << 16) | lsw);
808 }
809 
810 /*
811  * Z8536 CIO convenience atomic register getter/setter
812  */
813 
814 static uint
z8536_read_counter1(bus_space_tag_t bst,bus_space_handle_t bsh)815 z8536_read_counter1(bus_space_tag_t bst, bus_space_handle_t bsh)
816 {
817 	uint8_t reg;
818 	uint32_t lsw;
819 	int s;
820 
821 	s = splhigh();
822 
823 	/* Lock counter 1 latch in preparation for read-out */
824 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1);
825 	delay(1);
826 	reg = bus_space_read_1(bst, bsh, CIO_CTRL);
827 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1);
828 	bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC));
829 
830 	/* Read out counter 1 MSB,then LSB (releasing the latch) */
831 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_MSB);
832 	delay(1);
833 	lsw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8;
834 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_LSB);
835 	delay(1);
836 	lsw |= bus_space_read_1(bst, bsh, CIO_CTRL);
837 
838 	splx(s);
839 
840 	return lsw;
841 }
842 
843 static uint
z8536_read_counter2(bus_space_tag_t bst,bus_space_handle_t bsh)844 z8536_read_counter2(bus_space_tag_t bst, bus_space_handle_t bsh)
845 {
846 	uint8_t reg;
847 	uint32_t msw;
848 	int s;
849 
850 	s = splhigh();
851 
852 	/* Lock counter 2 latch in preparation for read-out */
853 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2);
854 	delay(1);
855 	reg = bus_space_read_1(bst, bsh, CIO_CTRL);
856 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2);
857 	bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC));
858 
859 	/* Read out counter 2 MSB,then LSB (releasing the latch) */
860 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_MSB);
861 	delay(1);
862 	msw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8;
863 	bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_LSB);
864 	delay(1);
865 	msw |= bus_space_read_1(bst, bsh, CIO_CTRL);
866 
867 	splx(s);
868 
869 	return msw;
870 }
871 
872 static void
z8536_reg_set(bus_space_tag_t bspace,bus_space_handle_t bhandle,uint8_t reg,uint8_t val)873 z8536_reg_set(bus_space_tag_t bspace, bus_space_handle_t bhandle,
874     uint8_t reg, uint8_t val)
875 {
876 	int s;
877 
878 	s = splhigh();
879 	bus_space_write_1(bspace, bhandle, CIO_CTRL, reg);
880 	delay(1);
881 	bus_space_write_1(bspace, bhandle, CIO_CTRL, val);
882 	splx(s);
883 }
884 
885 static uint8_t
z8536_reg_get(bus_space_tag_t bspace,bus_space_handle_t bhandle,uint8_t reg)886 z8536_reg_get(bus_space_tag_t bspace, bus_space_handle_t bhandle, uint8_t reg)
887 {
888 	int s;
889 	uint8_t val;
890 
891 	s = splhigh();
892 	bus_space_write_1(bspace, bhandle, CIO_CTRL, reg);
893 	delay(1);
894 	val = bus_space_read_1(bspace, bhandle, CIO_CTRL);
895 	splx(s);
896 
897 	return val;
898 }
899