Module Name: src Committed By: hauke Date: Tue Jan 31 22:13:20 UTC 2012
Modified Files: src/sys/arch/mac68k/conf: GENERIC src/sys/arch/mac68k/nubus: cpi_nubus.c cpi_nubusvar.h src/sys/dev/ic: z8536reg.h Log Message: Employ the two free 16 bit timers of the Hurdler Centronics Parallel Interface card's Z8536 CIO for Timecounter support. Builds, should work, but not testable yet because of pmap breakage. To generate a diff of this commit: cvs rdiff -u -r1.204 -r1.205 src/sys/arch/mac68k/conf/GENERIC cvs rdiff -u -r1.5 -r1.6 src/sys/arch/mac68k/nubus/cpi_nubus.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/mac68k/nubus/cpi_nubusvar.h cvs rdiff -u -r1.2 -r1.3 src/sys/dev/ic/z8536reg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/mac68k/conf/GENERIC diff -u src/sys/arch/mac68k/conf/GENERIC:1.204 src/sys/arch/mac68k/conf/GENERIC:1.205 --- src/sys/arch/mac68k/conf/GENERIC:1.204 Sun Dec 18 05:49:29 2011 +++ src/sys/arch/mac68k/conf/GENERIC Tue Jan 31 22:13:20 2012 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.204 2011/12/18 05:49:29 dholland Exp $ +# $NetBSD: GENERIC,v 1.205 2012/01/31 22:13:20 hauke Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/mac68k/conf/std.mac68k" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.204 $" +#ident "GENERIC-$Revision: 1.205 $" maxusers 16 # estimated number of users @@ -234,7 +234,8 @@ wsmouse* at ams? # Centronics printer port # CSI Hurdler Centronics Parallel Interface -cpi* at nubus? +# CPI_CTC12_IS_TIMECOUNTER 0x01 Run counters 1+2 as timecounter +cpi* at nubus? flags 0x1 # Serial Devices Index: src/sys/arch/mac68k/nubus/cpi_nubus.c diff -u src/sys/arch/mac68k/nubus/cpi_nubus.c:1.5 src/sys/arch/mac68k/nubus/cpi_nubus.c:1.6 --- src/sys/arch/mac68k/nubus/cpi_nubus.c:1.5 Fri May 13 22:35:50 2011 +++ src/sys/arch/mac68k/nubus/cpi_nubus.c Tue Jan 31 22:13:20 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cpi_nubus.c,v 1.5 2011/05/13 22:35:50 rmind Exp $ */ +/* $NetBSD: cpi_nubus.c,v 1.6 2012/01/31 22:13:20 hauke Exp $ */ /*- * Copyright (c) 2008 Hauke Fath @@ -25,8 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c,v 1.5 2011/05/13 22:35:50 rmind Exp $"); - +__KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c,v 1.6 2012/01/31 22:13:20 hauke Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> @@ -40,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c, #include <sys/ioctl.h> #include <sys/tty.h> #include <sys/time.h> +#include <sys/timetc.h> #include <sys/kernel.h> #include <sys/syslog.h> #include <sys/errno.h> @@ -71,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c, #define M_TRACE_WRITE 0x0010 #define M_TRACE_IOCTL 0x0020 #define M_TRACE_STATUS 0x0040 +#define M_TRACE_TCNTR 0x0080 #define M_TRACE_ALL 0xFFFF #define M_TRACE_NONE 0x0000 @@ -81,12 +82,12 @@ __KERNEL_RCSID(0, "$NetBSD: cpi_nubus.c, #define TRACE_WRITE (cpi_debug_mask & M_TRACE_WRITE) #define TRACE_IOCTL (cpi_debug_mask & M_TRACE_IOCTL) #define TRACE_STATUS (cpi_debug_mask & M_TRACE_STATUS) +#define TRACE_TCNTR (cpi_debug_mask & M_TRACE_TCNTR) #define TRACE_ALL (cpi_debug_mask & M_TRACE_ALL) #define TRACE_NONE (cpi_debug_mask & M_TRACE_NONE) -uint32_t cpi_debug_mask = M_TRACE_NONE /* | M_TRACE_WRITE */ ; - -#else +uint32_t cpi_debug_mask = M_TRACE_NONE /* | M_TRACE_TCNTR | M_TRACE_WRITE */ ; +#else /* CPI_DEBUG */ #define TRACE_CONFIG 0 #define TRACE_OPEN 0 #define TRACE_CLOSE 0 @@ -94,11 +95,10 @@ uint32_t cpi_debug_mask = M_TRACE_NONE / #define TRACE_WRITE 0 #define TRACE_IOCTL 0 #define TRACE_STATUS 0 +#define TRACE_TCNTR 0 #define TRACE_ALL 0 #define TRACE_NONE 0 -#endif - -#undef USE_CIO_TIMERS /* TBD */ +#endif /* CPI_DEBUG */ /* autoconf interface */ int cpi_nubus_match(device_t, cfdata_t, void *); @@ -126,14 +126,13 @@ static void cpi_wakeup(void *); static int cpi_flush(struct cpi_softc *); static void cpi_intr(void *); -#ifdef USE_CIO_TIMERS -static void cpi_initclock(struct cpi_softc *); -static u_int cpi_get_timecount(struct timecounter *); -#endif - -static inline void z8536_reg_set(bus_space_tag_t, bus_space_handle_t, +static void cpi_tc_initclock(struct cpi_softc *); +static uint cpi_get_timecount(struct timecounter *); +static uint z8536_read_counter1(bus_space_tag_t, bus_space_handle_t); +static uint z8536_read_counter2(bus_space_tag_t, bus_space_handle_t); +static void z8536_reg_set(bus_space_tag_t, bus_space_handle_t, uint8_t, uint8_t); -static inline uint8_t z8536_reg_get(bus_space_tag_t, bus_space_handle_t, +static uint8_t z8536_reg_get(bus_space_tag_t, bus_space_handle_t, uint8_t); @@ -191,19 +190,6 @@ const uint8_t cio_init[] = { Z8536_DPPRC, 0x00, Z8536_SIOCRC, 0x00, -#ifdef USE_CIO_TIMERS - /* - * Counter/Timers 1+2 are joined to form a free-running - * 32 bit timecounter - */ - Z8536_CTMSR1, CTMS_CSC, - Z8536_CTTCR1_MSB, 0x00, - Z8536_CTTCR1_LSB, 0x00, - Z8536_CTMSR2, CTMS_CSC, - Z8536_CTTCR2_MSB, 0x00, - Z8536_CTTCR2_LSB, 0x00, -#endif /* USE_CIO_TIMERS */ - /* * We need Timer 3 for running port A in strobed mode. * @@ -215,18 +201,19 @@ const uint8_t cio_init[] = { Z8536_CTTCR3_MSB, 0x00, Z8536_CTTCR3_LSB, 0x03, - /* - * Enable ports A+B+C+CT3 - * Set timer 1 to clock timer 2, but not yet enabled. - */ - Z8536_MCCR, MCCR_PAE | MCCR_PBE | MCCR_CT1CT2 | MCCR_PC_CT3E, + /* Enable ports A+B+C+CT3 */ + Z8536_MCCR, MCCR_PAE | MCCR_PBE | MCCR_PC_CT3E, + /* Master Interrupt Enable, Disable Lower Chain, - * No Vector, port A+B+CT vectors include status */ + * No Interrupt Vector, port A+B+CT vectors include status */ Z8536_MICR, MICR_MIE | MICR_DLC | MICR_NV | MICR_PAVIS | MICR_PBVIS | MICR_CTVIS, Z8536_PDRB, 0xFE, /* Clear printer -RESET */ }; +/* CPI default options */ +/* int cpi_options = 0 | CPI_CTC12_IS_TIMECOUNTER; */ + /* * Look for Creative Systems Inc. "Hurdler Centronics Parallel Interface" @@ -254,13 +241,15 @@ cpi_nubus_attach(device_t parent, device int err, ii; sc = device_private(self); + sc->sc_options = (device_cfdata(self)->cf_flags & CPI_OPTIONS_MASK); + na = aux; sc->sc_bst = na->na_tag; memcpy(&sc->sc_slot, na->fmt, sizeof(nubus_slot)); sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot); /* - * The CIO sits on the MSB (top byte lane) of the 32 bit + * The CIO sits eight bit wide on the top byte lane of * Nubus, so map 16 byte. */ if (TRACE_CONFIG) { @@ -287,7 +276,7 @@ cpi_nubus_attach(device_t parent, device z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_reset[ii], cio_reset[ii + 1]); - delay(1000); /* Just in case */ + delay(1000); /* Give the CIO time to set itself up */ for (ii = 0; ii < sizeof(cio_init); ii += 2) { z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_init[ii], cio_init[ii + 1]); @@ -296,16 +285,13 @@ cpi_nubus_attach(device_t parent, device if (TRACE_CONFIG) printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n"); - /* XXX Get the information strings from the card's ROM */ + /* XXX Get information strings from the card ROM */ aprint_normal(": CSI Hurdler II Centronics\n"); -#ifdef USE_CIO_TIMERS - /* Attach CIO timers as timecounters */ - if (TRACE_CONFIG) - printf("\tcpi_nubus_attach() about to attach timers\n"); - - cpi_initclock(sc); -#endif /* USE_CIO_TIMERS */ + /* Attach CIO timers 1+2 as timecounter */ + if (sc->sc_options & CPI_CTC12_IS_TIMECOUNTER) { + cpi_tc_initclock(sc); + } callout_init(&sc->sc_wakeupchan, 0); /* XXX */ @@ -557,27 +543,12 @@ static void cpi_lpreset(struct cpi_softc *sc) { uint8_t portb; /* Centronics -RESET is on port B, bit 0 */ -#ifdef DIRECT_PORT_ACCESS - int s; - - s = spltty(); - portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); - bus_space_write_1(sc->sc_bst, sc->sc_bsh, - CIO_PORTB, portb & ~CPI_RESET); - delay(100); - portb = bus_space_read_1(sc->sc_bst, sc->sc_bsh, CIO_PORTB); - bus_space_write_1(sc->sc_bst, sc->sc_bsh, - CIO_PORTB, portb | CPI_RESET); - - splx(s); -#else portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb & ~CPI_RESET); delay(100); portb = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_PDRB); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_PDRB, portb | CPI_RESET); -#endif /* DIRECT_PORT_ACCESS */ } @@ -650,88 +621,245 @@ cpi_intr(void *arg) wakeup((void *)sc); } -#ifdef USE_CIO_TIMERS -/* - * Z8536 CIO timers 1 + 2 used for timecounter(9) support - */ static void -cpi_initclock(struct cpi_softc *sc) +cpi_tc_initclock(struct cpi_softc *sc) { - static struct timecounter cpi_timecounter = { - .tc_get_timecount = cpi_get_timecount, - .tc_poll_pps = 0, - .tc_counter_mask = 0x0ffffu, - .tc_frequency = CLK_FREQ, - .tc_name = "CPI Z8536 CIO", - .tc_quality = 50, - .tc_priv = NULL, - .tc_next = NULL - }; - + uint8_t reg; + /* - * Set up timers A and B as a single, free-running 32 bit counter + * Set up c/t 1 and 2 as a single, free-running 32 bit counter */ - /* Disable counters A and B */ + /* Disable counters 1 and 2 */ reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, reg & ~(MCCR_CT1E | MCCR_CT2E)); /* Make sure interrupt enable bits are cleared */ - z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, - CTCS_CLR_IE); - z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, - CTCS_CLR_IE); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, CTCS_CLR_IE); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, CTCS_CLR_IE); /* Initialise counter start values, and set to continuous cycle */ - z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR1, CTMS_CSC); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR1, + CTMS_CSC | CTMS_DCS_PULSE); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_MSB, 0x00); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR1_LSB, 0x00); - z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR2, CTMS_CSC); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTMSR2, + CTMS_CSC | CTMS_DCS_PULSE); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_MSB, 0x00); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTTCR2_LSB, 0x00); - /* Re-enable counters A and B */ + /* Link counters 1 and 2 */ + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR); + z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, reg | MCCR_CT1CT2); + + /* Enable and counter pair */ reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_MCCR); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_MCCR, - reg | MCCR_CT1E | MCCR_CT2E | MCCR_CT1CT2); + reg | (MCCR_CT1E | MCCR_CT2E)); - /* Start counters A and B */ + /* Start c/t 1; c/t 2 gets started by c/t 1 pulse */ reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1); z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1, - reg | CTCS_TCB); - reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2); - z8536_reg_set(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2, - reg | CTCS_TCB); + CTCSR_MASK(reg | CTCS_TCB | CTCS_GCB)); + + if (TRACE_TCNTR) { + printf("Before tc_init():\n"); + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1); + printf("Counter 1 CTCSR setup bits are 0x%03x\n", reg); + printf("Counter 1 (LSW) is now 0x%05x\n", + z8536_read_counter1(sc->sc_bst, sc->sc_bsh)); + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2); + printf("Counter 2 CTCSR setup bits are 0x%03x\n", reg); + printf("Counter 2 (MSW) is now 0x%05x\n", + z8536_read_counter2(sc->sc_bst, sc->sc_bsh)); + + delay(1000); + } - tc_init(&cpi_timecounter); + sc->sc_timecounter.tc_get_timecount = cpi_get_timecount; + sc->sc_timecounter.tc_poll_pps = 0; + sc->sc_timecounter.tc_counter_mask = ~0u; + sc->sc_timecounter.tc_frequency = CPI_CLK_FREQ; + sc->sc_timecounter.tc_name = "Nubus CPI"; + sc->sc_timecounter.tc_quality = 1000; + /* + * Squirrel away the device's sc so we can talk + * to the CIO later + */ + sc->sc_timecounter.tc_priv = sc; + sc->sc_timecounter.tc_next = NULL; + + tc_init(&(sc->sc_timecounter)); + + if (TRACE_TCNTR) { + delay(1000); + + printf("After tc_init():\n"); + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR1); + printf("Counter 1 CTCSR setup bits are 0x%03x\n", reg); + printf("Counter 1 (LSW) is now 0x%05x\n", + z8536_read_counter1(sc->sc_bst, sc->sc_bsh)); + reg = z8536_reg_get(sc->sc_bst, sc->sc_bsh, Z8536_CTCSR2); + printf("Counter 2 CTCSR setup bits are 0x%03x\n", reg); + printf("Counter 2 (MSW) is now 0x%05x\n", + z8536_read_counter2(sc->sc_bst, sc->sc_bsh)); + } } static u_int cpi_get_timecount(struct timecounter *tc) { - uint8_t high, high2, low; - int s; - - /* - * Make the timer access atomic + int s; + uint msw, msw2, lsw; + uint8_t reg; + bus_space_tag_t bst; + bus_space_handle_t bsh; + + bst = ((struct cpi_softc *)tc->tc_priv)->sc_bst; + bsh = ((struct cpi_softc *)tc->tc_priv)->sc_bsh; + /* + * We run CIO counters 1 and 2 in an internally coupled mode, + * where the output of counter 1 (LSW) clocks counter 2 (MSW). + * The counters are buffered, and the buffers have to be + * locked before we can read out a consistent counter + * value. Reading the LSB releases the buffer lock. + * + * Unfortunately, there is no such mechanism between MSW and + * LSW of the coupled counter. To ensure a consistent + * read-out, we read the MSW, then the LSW, then re-read the + * MSW and compare with the old value. If we find that the MSW + * has just been incremented, we re-read the LSW. This avoids + * a race that could leave us with a new (just wrapped) LSW + * and an old MSW value. * - * XXX How expensive is this? And is it really necessary? + * For simplicity, we roll the procedure into a loop - the + * rollover case is rare. */ - s = splhigh(); + do { + +#define delay(a) + + /* Guard HW timer access */ + s = splhigh(); - /* TBD */ + /* Lock counter 2 latch in preparation for read-out */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2); + delay(1); + reg = bus_space_read_1(bst, bsh, CIO_CTRL); + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2); + bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC)); + + /* Read out counter 2 MSB,then LSB (releasing the latch) */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_MSB); + delay(1); + msw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8; + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_LSB); + delay(1); + msw |= bus_space_read_1(bst, bsh, CIO_CTRL); + + /* Lock counter 1 latch in preparation for read-out */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1); + delay(1); + reg = bus_space_read_1(bst, bsh, CIO_CTRL); + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1); + bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg |CTCS_RCC)); + + /* Read out counter 1 MSB,then LSB (releasing the latch) */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_MSB); + delay(1); + lsw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8; + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_LSB); + delay(1); + lsw |= bus_space_read_1(bst, bsh, CIO_CTRL); + + /* Lock counter 2 latch in preparation for read-out */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2); + delay(1); + reg = bus_space_read_1(bst, bsh, CIO_CTRL); + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2); + bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC)); + + /* Read out counter 2 MSB,then LSB (releasing the latch) */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_MSB); + delay(1); + msw2 = bus_space_read_1(bst, bsh, CIO_CTRL) << 8; + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_LSB); + delay(1); + msw2 |= bus_space_read_1(bst, bsh, CIO_CTRL); + + splx(s); -} -#endif /* USE_CIO_TIMERS */ + } while (msw2 != msw); + /* timecounter expects an upward counter */ + return ~0u - ((msw << 16) | lsw); +} /* - * Z8536 CIO nuts and bolts + * Z8536 CIO convenience atomic register getter/setter */ -static inline void +static uint +z8536_read_counter1(bus_space_tag_t bst, bus_space_handle_t bsh) +{ + uint8_t reg; + uint32_t lsw; + int s; + + s = splhigh(); + + /* Lock counter 1 latch in preparation for read-out */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1); + delay(1); + reg = bus_space_read_1(bst, bsh, CIO_CTRL); + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR1); + bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC)); + + /* Read out counter 1 MSB,then LSB (releasing the latch) */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_MSB); + delay(1); + lsw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8; + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR1_LSB); + delay(1); + lsw |= bus_space_read_1(bst, bsh, CIO_CTRL); + + splx(s); + + return lsw; +} + +static uint +z8536_read_counter2(bus_space_tag_t bst, bus_space_handle_t bsh) +{ + uint8_t reg; + uint32_t msw; + int s; + + s = splhigh(); + + /* Lock counter 2 latch in preparation for read-out */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2); + delay(1); + reg = bus_space_read_1(bst, bsh, CIO_CTRL); + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCSR2); + bus_space_write_1(bst, bsh, CIO_CTRL, CTCSR_MASK(reg | CTCS_RCC)); + + /* Read out counter 2 MSB,then LSB (releasing the latch) */ + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_MSB); + delay(1); + msw = bus_space_read_1(bst, bsh, CIO_CTRL) << 8; + bus_space_write_1(bst, bsh, CIO_CTRL, Z8536_CTCCR2_LSB); + delay(1); + msw |= bus_space_read_1(bst, bsh, CIO_CTRL); + + splx(s); + + return msw; +} + +static void z8536_reg_set(bus_space_tag_t bspace, bus_space_handle_t bhandle, uint8_t reg, uint8_t val) { @@ -744,7 +872,7 @@ z8536_reg_set(bus_space_tag_t bspace, bu splx(s); } -static inline uint8_t +static uint8_t z8536_reg_get(bus_space_tag_t bspace, bus_space_handle_t bhandle, uint8_t reg) { int s; Index: src/sys/arch/mac68k/nubus/cpi_nubusvar.h diff -u src/sys/arch/mac68k/nubus/cpi_nubusvar.h:1.2 src/sys/arch/mac68k/nubus/cpi_nubusvar.h:1.3 --- src/sys/arch/mac68k/nubus/cpi_nubusvar.h:1.2 Fri May 23 10:46:10 2008 +++ src/sys/arch/mac68k/nubus/cpi_nubusvar.h Tue Jan 31 22:13:20 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cpi_nubusvar.h,v 1.2 2008/05/23 10:46:10 hauke Exp $ */ +/* $NetBSD: cpi_nubusvar.h,v 1.3 2012/01/31 22:13:20 hauke Exp $ */ /*- * Copyright (c) 2008 Hauke Fath @@ -62,11 +62,24 @@ enum hsk_lines { CPI_ACK = 0x04 /* PC2 */ }; +/* + * The CPI board glue logic divides the 10 MHz Nubus clock by 2, and + * feeds it to the 8536 CIO (pin 16). The CIO divides the PCLK clock + * by 2 internally before providing it to its counters. + */ +#define CPI_CLK_FREQ (10000000 / 4) + +/* CPI configuration options - we might grow more */ +enum cpi_cf_flags { + CPI_CTC12_IS_TIMECOUNTER = 0x01 +}; +#define CPI_OPTIONS_MASK (CPI_CTC12_IS_TIMECOUNTER) + struct cpi_softc { struct device sc_dev; nubus_slot sc_slot; /* Nubus slot number */ - char cardname[CPI_CARD_NAME_LEN]; + char sc_cardname[CPI_CARD_NAME_LEN]; bus_addr_t sc_basepa; /* base physical address */ bus_space_tag_t sc_bst; @@ -83,6 +96,10 @@ struct cpi_softc { u_char *sc_cp; /* Next byte to send */ u_char sc_lpstate; + + ulong sc_options; + + struct timecounter sc_timecounter; }; #endif /* CPI_NUBUSVAR_H */ Index: src/sys/dev/ic/z8536reg.h diff -u src/sys/dev/ic/z8536reg.h:1.2 src/sys/dev/ic/z8536reg.h:1.3 --- src/sys/dev/ic/z8536reg.h:1.2 Fri May 23 10:46:53 2008 +++ src/sys/dev/ic/z8536reg.h Tue Jan 31 22:13:19 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: z8536reg.h,v 1.2 2008/05/23 10:46:53 hauke Exp $ */ +/* $NetBSD: z8536reg.h,v 1.3 2012/01/31 22:13:19 hauke Exp $ */ /*- * Copyright (c) 2008 Hauke Fath @@ -118,6 +118,9 @@ #define CTCS_SET_IE 0xC0 /* Set Interrupt Enable */ #define CTCS_CLR_IE 0xE0 /* Clear Interrupt Enable */ +/* Avoid changing intr bits unintendedly */ +#define CTCSR_MASK(FLAGS) ((FLAGS) & 0x3f) + /* The port data registers are directly accessible at their own IO address */ #define Z8536_PDRA 0x0D /* Port A Data Register */ #define Z8536_PDRB 0x0E /* Port B Data Register */