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