Home | History | Annotate | Line # | Download | only in dev
      1  1.32     isaki /*	$NetBSD: mfp.c,v 1.32 2024/01/06 05:31:19 isaki Exp $	*/
      2   1.2   minoura 
      3   1.5   minoura /*-
      4   1.2   minoura  * Copyright (c) 1998 NetBSD Foundation, Inc.
      5   1.2   minoura  * All rights reserved.
      6   1.2   minoura  *
      7   1.2   minoura  * Redistribution and use in source and binary forms, with or without
      8   1.2   minoura  * modification, are permitted provided that the following conditions
      9   1.2   minoura  * are met:
     10   1.2   minoura  * 1. Redistributions of source code must retain the above copyright
     11   1.2   minoura  *    notice, this list of conditions and the following disclaimer.
     12   1.2   minoura  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.2   minoura  *    notice, this list of conditions and the following disclaimer in the
     14   1.2   minoura  *    documentation and/or other materials provided with the distribution.
     15   1.2   minoura  *
     16   1.5   minoura  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17   1.5   minoura  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18   1.5   minoura  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19   1.5   minoura  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20   1.5   minoura  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21   1.5   minoura  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22   1.5   minoura  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23   1.5   minoura  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24   1.5   minoura  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25   1.5   minoura  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26   1.5   minoura  * POSSIBILITY OF SUCH DAMAGE.
     27   1.2   minoura  */
     28   1.2   minoura 
     29   1.2   minoura /*
     30   1.2   minoura  * MC68901 MFP (multi function periferal) driver for NetBSD/x68k
     31   1.2   minoura  */
     32   1.2   minoura 
     33   1.2   minoura /*
     34  1.11       wiz  * MFP is used as keyboard controller, which may be used before
     35   1.2   minoura  * ordinary initialization.
     36   1.2   minoura  */
     37  1.10     lukem 
     38  1.10     lukem #include <sys/cdefs.h>
     39  1.32     isaki __KERNEL_RCSID(0, "$NetBSD: mfp.c,v 1.32 2024/01/06 05:31:19 isaki Exp $");
     40   1.2   minoura 
     41   1.2   minoura #include <sys/param.h>
     42   1.2   minoura #include <sys/systm.h>
     43   1.2   minoura #include <sys/device.h>
     44   1.2   minoura 
     45   1.2   minoura #include <machine/bus.h>
     46   1.2   minoura #include <machine/cpu.h>
     47  1.22     isaki #include <machine/autoconf.h>
     48   1.2   minoura 
     49   1.2   minoura #include <arch/x68k/dev/intiovar.h>
     50   1.2   minoura #include <arch/x68k/dev/mfp.h>
     51   1.2   minoura 
     52  1.23     isaki static int  mfp_match(device_t, cfdata_t, void *);
     53  1.23     isaki static void mfp_attach(device_t, device_t, void *);
     54  1.21     isaki static int  mfp_search(device_t, cfdata_t, const int *, void *);
     55  1.14       chs static void mfp_init(void);
     56  1.14       chs static void mfp_calibrate_delay(void);
     57   1.2   minoura 
     58  1.23     isaki CFATTACH_DECL_NEW(mfp, sizeof(struct mfp_softc),
     59   1.9   thorpej     mfp_match, mfp_attach, NULL, NULL);
     60   1.2   minoura 
     61  1.12       chs static int mfp_attached;
     62  1.12       chs 
     63  1.18     isaki static int
     64  1.23     isaki mfp_match(device_t parent, cfdata_t cf, void *aux)
     65   1.2   minoura {
     66   1.2   minoura 	struct intio_attach_args *ia = aux;
     67   1.2   minoura 
     68   1.2   minoura 	/* mfp0 */
     69  1.19     isaki 	if (strcmp(ia->ia_name, "mfp") != 0)
     70   1.2   minoura 		return 0;
     71  1.12       chs 	if (mfp_attached)
     72   1.2   minoura 		return (0);
     73   1.2   minoura 
     74   1.2   minoura 	if (ia->ia_addr == INTIOCF_ADDR_DEFAULT)
     75   1.2   minoura 		ia->ia_addr = MFP_ADDR;
     76   1.2   minoura 	if (ia->ia_intr == INTIOCF_INTR_DEFAULT)
     77   1.2   minoura 		ia->ia_addr = MFP_INTR;
     78   1.2   minoura 
     79   1.2   minoura 	/* fixed address */
     80   1.2   minoura 	if (ia->ia_addr != MFP_ADDR)
     81   1.2   minoura 		return (0);
     82   1.2   minoura 	if (ia->ia_intr != MFP_INTR)
     83   1.2   minoura 		return (0);
     84   1.2   minoura 
     85   1.2   minoura 	return (1);
     86   1.2   minoura }
     87   1.2   minoura 
     88   1.2   minoura 
     89  1.18     isaki static void
     90  1.23     isaki mfp_attach(device_t parent, device_t self, void *aux)
     91   1.2   minoura {
     92  1.23     isaki 	struct mfp_softc *sc = device_private(self);
     93   1.2   minoura 	struct intio_attach_args *ia = aux;
     94  1.26  christos 	int r __diagused;
     95  1.22     isaki 
     96  1.23     isaki 	aprint_normal("\n");
     97  1.22     isaki 	mfp_attached = 1;
     98   1.2   minoura 
     99  1.25   tsutsui 	/* mfp_init() is already called via early config_console() */
    100  1.22     isaki 	sc->sc_bst = ia->ia_bst;
    101  1.22     isaki 	sc->sc_intr = ia->ia_intr;
    102  1.22     isaki 	ia->ia_size = 0x30;
    103  1.22     isaki 	r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE);
    104   1.2   minoura #ifdef DIAGNOSTIC
    105  1.22     isaki 	if (r)
    106  1.22     isaki 		panic("IO map for MFP corruption??");
    107   1.2   minoura #endif
    108  1.22     isaki 	bus_space_map(ia->ia_bst, ia->ia_addr, 0x2000, 0, &sc->sc_bht);
    109  1.28   thorpej 	config_search(self, NULL,
    110  1.29   thorpej 	    CFARGS(.search = mfp_search));
    111   1.2   minoura }
    112   1.2   minoura 
    113  1.21     isaki static int
    114  1.21     isaki mfp_search(device_t parent, cfdata_t cf, const int *loc, void *aux)
    115  1.21     isaki {
    116  1.28   thorpej 	if (config_probe(parent, cf, __UNCONST(cf->cf_name)))
    117  1.28   thorpej 		config_attach(parent, cf, __UNCONST(cf->cf_name), NULL,
    118  1.29   thorpej 		    CFARGS_NONE);
    119  1.21     isaki 	return 0;
    120  1.21     isaki }
    121  1.21     isaki 
    122  1.22     isaki void
    123  1.22     isaki mfp_config_console(void)
    124  1.22     isaki {
    125  1.22     isaki 	mfp_init();
    126  1.22     isaki 	mfp_calibrate_delay();
    127  1.22     isaki }
    128  1.22     isaki 
    129   1.2   minoura static void
    130  1.14       chs mfp_init(void)
    131   1.2   minoura {
    132   1.2   minoura 	mfp_set_vr(MFP_INTR);
    133   1.2   minoura 
    134   1.2   minoura 	/* stop all interrupts */
    135   1.2   minoura 	mfp_set_iera(0);
    136   1.2   minoura 	mfp_set_ierb(0);
    137  1.20     isaki 
    138  1.20     isaki 	/* make MSCTRL 'High', XXX where should I do it? */
    139  1.20     isaki 	mfp_send_usart(0x41);
    140   1.2   minoura 
    141   1.2   minoura 	/* Timer A settings */
    142   1.2   minoura 	mfp_set_tacr(MFP_TIMERA_RESET | MFP_TIMERA_STOP);
    143   1.2   minoura 
    144   1.2   minoura 	/* Timer B settings: used for USART clock */
    145   1.2   minoura 	mfp_set_tbcr(MFP_TIMERB_RESET | MFP_TIMERB_STOP);
    146   1.2   minoura 
    147   1.2   minoura 	/* Timer C/D settings */
    148   1.2   minoura 	mfp_set_tcdcr(0);
    149   1.4   minoura }
    150   1.4   minoura 
    151   1.4   minoura extern int delay_divisor;
    152   1.4   minoura 
    153   1.4   minoura static void
    154   1.4   minoura mfp_calibrate_delay(void)
    155   1.4   minoura {
    156   1.4   minoura 	/*
    157   1.4   minoura 	 * Stolen from mvme68k.
    158   1.4   minoura 	 */
    159   1.4   minoura 	/*
    160   1.4   minoura 	 * X68k provides 4MHz clock (= 0.25usec) for MFP timer C.
    161   1.4   minoura 	 * 10000usec = 0.25usec * 200 * 200
    162   1.4   minoura 	 * Our slowest clock is 20MHz (?).  Its delay_divisor value
    163   1.4   minoura 	 * should be about 102.  Start from 140 here.
    164   1.4   minoura 	 */
    165   1.4   minoura 	for (delay_divisor = 140; delay_divisor > 0; delay_divisor--) {
    166   1.4   minoura 		mfp_set_tcdr(255-0);
    167   1.4   minoura 		mfp_set_tcdcr(0x70); /* 1/200 delay mode */
    168  1.32     isaki 		_delay(10000);
    169   1.4   minoura 		mfp_set_tcdcr(0); /* stop timer */
    170   1.4   minoura 		if ((255 - mfp_get_tcdr()) > 200)
    171   1.4   minoura 			break;	/* got it! */
    172   1.4   minoura 		/* retry! */
    173   1.4   minoura 	}
    174   1.2   minoura }
    175   1.2   minoura 
    176   1.2   minoura /*
    177   1.2   minoura  * MFP utility functions
    178   1.2   minoura  */
    179   1.2   minoura 
    180   1.2   minoura /*
    181   1.2   minoura  * wait for built-in display hsync.
    182   1.2   minoura  * should be called before writing to frame buffer.
    183   1.2   minoura  * might be called before realconfig.
    184   1.2   minoura  */
    185   1.2   minoura void
    186  1.14       chs mfp_wait_for_hsync(void)
    187   1.2   minoura {
    188   1.2   minoura 	/* wait for CRT HSYNC */
    189   1.2   minoura 	while (mfp_get_gpip() & MFP_GPIP_HSYNC)
    190  1.17     perry 		__asm("nop");
    191   1.2   minoura 	while (!(mfp_get_gpip() & MFP_GPIP_HSYNC))
    192  1.17     perry 		__asm("nop");
    193   1.2   minoura }
    194   1.2   minoura 
    195   1.2   minoura /*
    196   1.2   minoura  * send COMMAND to the MFP USART.
    197   1.2   minoura  * USART is attached to the keyboard.
    198   1.2   minoura  * might be called before realconfig.
    199   1.2   minoura  */
    200  1.18     isaki int
    201  1.14       chs mfp_send_usart(int command)
    202   1.2   minoura {
    203   1.2   minoura 	while (!(mfp_get_tsr() & MFP_TSR_BE));
    204   1.2   minoura 	mfp_set_udr(command);
    205   1.2   minoura 
    206   1.2   minoura 	return 0;
    207   1.2   minoura }
    208   1.2   minoura 
    209   1.2   minoura int
    210   1.6       wiz mfp_receive_usart(void)
    211   1.2   minoura {
    212   1.2   minoura 	while (!(mfp_get_rsr() & MFP_RSR_BF))
    213  1.17     perry 		__asm("nop");
    214   1.2   minoura 	return mfp_get_udr();
    215   1.2   minoura }
    216