1 /* $NecBSD: bshw_machdep.c,v 1.8.12.6 2001/06/29 06:28:05 honda Exp $ */
8 * [NetBSD for NEC PC-98 series]
9 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
10 * NetBSD/pc98 porting staff. All rights reserved.
12 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
13 * Naofumi HONDA. All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #if defined(__FreeBSD__) && __FreeBSD_version > 500001
46 #endif /* __ FreeBSD__ */
48 #include <sys/queue.h>
49 #include <sys/malloc.h>
50 #include <sys/errno.h>
55 #include <sys/device.h>
57 #include <machine/bus.h>
58 #include <machine/intr.h>
60 #include <dev/scsipi/scsi_all.h>
61 #include <dev/scsipi/scsipi_all.h>
62 #include <dev/scsipi/scsiconf.h>
63 #include <dev/scsipi/scsi_disk.h>
65 #include <machine/dvcfg.h>
66 #include <machine/physio_proc.h>
68 #include <i386/Cbus/dev/scsi_low.h>
70 #include <dev/ic/wd33c93reg.h>
71 #include <i386/Cbus/dev/ct/ctvar.h>
72 #include <i386/Cbus/dev/ct/ct_machdep.h>
73 #include <i386/Cbus/dev/ct/bshwvar.h>
74 #endif /* __NetBSD__ */
77 #include <machine/bus.h>
78 #include <machine/clock.h>
79 #include <machine/md_var.h>
81 #include <compat/netbsd/dvcfg.h>
82 #include <compat/netbsd/physio_proc.h>
84 #include <cam/scsi/scsi_low.h>
86 #include <dev/ic/wd33c93reg.h>
87 #include <dev/ct/ctvar.h>
88 #include <dev/ct/ct_machdep.h>
89 #include <dev/ct/bshwvar.h>
92 #endif /* __FreeBSD__ */
94 #define BSHW_IO_CONTROL_FLAGS 0
96 u_int bshw_io_control = BSHW_IO_CONTROL_FLAGS;
97 int bshw_data_read_bytes = 4096;
98 int bshw_data_write_bytes = 4096;
100 /*********************************************************
102 *********************************************************/
104 #define BSHW_PAGE_SIZE NBPG
105 #endif /* __NetBSD__ */
108 #define BSHW_PAGE_SIZE PAGE_SIZE
109 typedef unsigned long vaddr_t;
110 #endif /* __FreeBSD__ */
112 /*********************************************************
113 * GENERIC MACHDEP FUNCTIONS
114 *********************************************************/
116 bshw_synch_setup(ct, ti)
118 struct targ_info *ti;
120 struct ct_bus_access_handle *chp = &ct->sc_ch;
121 struct ct_targ_info *cti = (void *) ti;
122 struct bshw_softc *bs = ct->ct_hw;
123 struct bshw *hw = bs->sc_hw;
125 if (hw->hw_sregaddr == 0)
128 ct_cr_write_1(chp, hw->hw_sregaddr + ti->ti_id, cti->cti_syncreg);
129 if (hw->hw_flags & BSHW_DOUBLE_DMACHAN)
131 ct_cr_write_1(chp, hw->hw_sregaddr + ti->ti_id + 8,
140 struct scsi_low_softc *slp = &ct->sc_sclow;
141 struct ct_bus_access_handle *chp = &ct->sc_ch;
142 struct bshw_softc *bs = ct->ct_hw;
143 struct bshw *hw = bs->sc_hw;
148 /* open hardware busmaster mode */
149 if (hw->hw_dma_init != NULL && ((*hw->hw_dma_init)(ct)) != 0)
151 printf("%s: change mode using external DMA (%x)\n",
152 slp->sl_xname, (u_int)ct_cr_read_1(chp, 0x37));
155 /* clear hardware synch registers */
156 offs = hw->hw_sregaddr;
159 for (i = 0; i < 8; i ++, offs ++)
161 ct_cr_write_1(chp, offs, 0);
162 if ((hw->hw_flags & BSHW_DOUBLE_DMACHAN) != 0)
163 ct_cr_write_1(chp, offs + 8, 0);
167 /* disable interrupt & assert reset */
168 regv = ct_cr_read_1(chp, wd3s_mbank);
171 ct_cr_write_1(chp, wd3s_mbank, regv);
173 SCSI_LOW_DELAY(500000);
175 /* reset signal off */
177 ct_cr_write_1(chp, wd3s_mbank, regv);
179 /* interrupt enable */
181 ct_cr_write_1(chp, wd3s_mbank, regv);
186 bshw_read_settings(chp, bs)
187 struct ct_bus_access_handle *chp;
188 struct bshw_softc *bs;
190 static int irq_tbl[] = { 3, 5, 6, 9, 12, 13 };
192 bs->sc_hostid = (ct_cr_read_1(chp, wd3s_auxc) & AUXCR_HIDM);
193 bs->sc_irq = irq_tbl[(ct_cr_read_1(chp, wd3s_auxc) >> 3) & 7];
194 bs->sc_drq = ct_cmdp_read_1(chp) & 3;
198 /*********************************************************
199 * DMA PIO TRANSFER (SMIT)
200 *********************************************************/
201 #define LC_SMIT_TIMEOUT 2 /* 2 sec: timeout for a fifo status ready */
202 #define LC_SMIT_OFFSET 0x1000
203 #define LC_FSZ DEV_BSIZE
205 #define LC_REST (LC_FSZ - LC_SFSZ)
207 #define BSHW_LC_FSET 0x36
208 #define BSHW_LC_FCTRL 0x44
209 #define FCTRL_EN 0x01
210 #define FCTRL_WRITE 0x02
212 #define SF_ABORT 0x08
215 static __inline void bshw_lc_smit_start(struct ct_softc *, int, u_int);
216 static __inline void bshw_lc_smit_stop(struct ct_softc *);
217 static int bshw_lc_smit_fstat(struct ct_softc *, int, int);
220 bshw_lc_smit_stop(ct)
223 struct ct_bus_access_handle *chp = &ct->sc_ch;
225 ct_cr_write_1(chp, BSHW_LC_FCTRL, 0);
226 ct_cmdp_write_1(chp, CMDP_DMER);
230 bshw_lc_smit_start(ct, count, direction)
235 struct ct_bus_access_handle *chp = &ct->sc_ch;
238 val = ct_cr_read_1(chp, BSHW_LC_FSET);
239 cthw_set_count(chp, count);
242 if (direction == SCSI_LOW_WRITE)
243 pval |= (val & 0xe0) | FCTRL_WRITE;
244 ct_cr_write_1(chp, BSHW_LC_FCTRL, pval);
245 ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO);
249 bshw_lc_smit_fstat(ct, wc, read)
253 struct ct_bus_access_handle *chp = &ct->sc_ch;
258 chp->ch_bus_weight(chp);
259 stat = ct_cmdp_read_1(chp);
260 if (read == SCSI_LOW_READ)
262 if ((stat & SF_RDY) != 0)
264 if ((stat & SF_ABORT) != 0)
269 if ((stat & SF_ABORT) != 0)
271 if ((stat & SF_RDY) != 0)
276 printf("%s: SMIT fifo status timeout\n", ct->sc_sclow.sl_xname);
281 bshw_smit_xfer_stop(ct)
284 struct scsi_low_softc *slp = &ct->sc_sclow;
285 struct bshw_softc *bs = ct->ct_hw;
286 struct targ_info *ti;
287 struct sc_p *sp = &slp->sl_scp;
290 bshw_lc_smit_stop(ct);
296 if (ti->ti_phase == PH_DATA)
298 count = cthw_get_count(&ct->sc_ch);
299 if (count < bs->sc_sdatalen)
301 if (sp->scp_direction == SCSI_LOW_READ &&
302 count != bs->sc_edatalen)
305 count = bs->sc_sdatalen - count;
306 if (count > (u_int) sp->scp_datalen)
309 sp->scp_data += count;
310 sp->scp_datalen -= count;
312 else if (count > bs->sc_sdatalen)
315 printf("%s: smit_xfer_end: cnt error\n", slp->sl_xname);
316 slp->sl_error |= PDMAERR;
318 scsi_low_data_finish(slp);
322 printf("%s: smit_xfer_end: phase miss\n", slp->sl_xname);
323 slp->sl_error |= PDMAERR;
328 bshw_smit_xfer_start(ct)
331 struct scsi_low_softc *slp = &ct->sc_sclow;
332 struct ct_bus_access_handle *chp = &ct->sc_ch;
333 struct bshw_softc *bs = ct->ct_hw;
334 struct sc_p *sp = &slp->sl_scp;
335 struct targ_info *ti = slp->sl_Tnexus;
336 struct ct_targ_info *cti = (void *) ti;
337 u_int datalen, count, io_control;
341 io_control = bs->sc_io_control | bshw_io_control;
342 if ((io_control & BSHW_SMIT_BLOCK) != 0)
345 if ((slp->sl_scp.scp_datalen % DEV_BSIZE) != 0)
348 datalen = sp->scp_datalen;
349 if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
351 if ((io_control & BSHW_READ_INTERRUPT_DRIVEN) != 0 &&
352 datalen > bshw_data_read_bytes)
353 datalen = bshw_data_read_bytes;
357 if ((io_control & BSHW_WRITE_INTERRUPT_DRIVEN) != 0 &&
358 datalen > bshw_data_write_bytes)
359 datalen = bshw_data_write_bytes;
362 bs->sc_sdatalen = datalen;
364 wc = LC_SMIT_TIMEOUT * 1024 * 1024;
366 ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA);
367 bshw_lc_smit_start(ct, datalen, sp->scp_direction);
369 if (sp->scp_direction == SCSI_LOW_READ)
373 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_READ))
376 count = (datalen > LC_FSZ ? LC_FSZ : datalen);
377 bus_space_read_region_4(chp->ch_memt, chp->ch_memh,
378 LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2);
384 bs->sc_edatalen = datalen;
390 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_WRITE))
392 if (cti->cti_syncreg == 0)
395 * If async transfer, reconfirm a scsi phase
396 * again. Unless C bus might hang up.
398 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_WRITE))
402 count = (datalen > LC_SFSZ ? LC_SFSZ : datalen);
403 bus_space_write_region_4(chp->ch_memt, chp->ch_memh,
404 LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2);
408 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_WRITE))
411 count = (datalen > LC_REST ? LC_REST : datalen);
412 bus_space_write_region_4(chp->ch_memt, chp->ch_memh,
413 LC_SMIT_OFFSET + LC_SFSZ,
414 (u_int32_t *) data, count >> 2);
423 /*********************************************************
425 *********************************************************/
426 static __inline void bshw_dma_write_1 \
427 (struct ct_bus_access_handle *, bus_addr_t, u_int8_t);
428 static void bshw_dmastart(struct ct_softc *);
429 static void bshw_dmadone(struct ct_softc *);
432 bshw_dma_xfer_start(ct)
435 struct scsi_low_softc *slp = &ct->sc_sclow;
436 struct sc_p *sp = &slp->sl_scp;
437 struct ct_bus_access_handle *chp = &ct->sc_ch;
438 struct bshw_softc *bs = ct->ct_hw;
439 vaddr_t va, endva, phys, nphys;
442 io_control = bs->sc_io_control | bshw_io_control;
443 if ((io_control & BSHW_DMA_BLOCK) != 0 && sp->scp_datalen < 256)
446 ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA);
447 phys = vtophys((vaddr_t) sp->scp_data);
448 if (phys >= bs->sc_minphys)
451 bs->sc_segaddr = bs->sc_bounce_phys;
453 bs->sc_seglen = sp->scp_datalen;
454 if (bs->sc_seglen > bs->sc_bounce_size)
455 bs->sc_seglen = bs->sc_bounce_size;
457 bs->sc_bufp = bs->sc_bounce_addr;
458 if (sp->scp_direction == SCSI_LOW_WRITE)
459 bcopy(sp->scp_data, bs->sc_bufp, bs->sc_seglen);
464 bs->sc_segaddr = (u_int8_t *) phys;
466 endva = (vaddr_t) round_page((vaddr_t) sp->scp_data + sp->scp_datalen);
467 for (va = (vaddr_t) sp->scp_data; ; phys = nphys)
469 if ((va += BSHW_PAGE_SIZE) >= endva)
471 bs->sc_seglen = sp->scp_datalen;
476 if (phys + BSHW_PAGE_SIZE != nphys || nphys >= bs->sc_minphys)
479 (u_int8_t *) trunc_page(va) - sp->scp_data;
488 cthw_set_count(chp, bs->sc_seglen);
489 ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO);
494 bshw_dma_xfer_stop(ct)
497 struct scsi_low_softc *slp = &ct->sc_sclow;
498 struct sc_p *sp = &slp->sl_scp;
499 struct bshw_softc *bs = ct->ct_hw;
500 struct targ_info *ti;
501 u_int count, transbytes;
509 if (ti->ti_phase == PH_DATA)
511 count = cthw_get_count(&ct->sc_ch);
512 if (count < (u_int) bs->sc_seglen)
514 transbytes = bs->sc_seglen - count;
515 if (bs->sc_bufp != NULL &&
516 sp->scp_direction == SCSI_LOW_READ)
517 bcopy(bs->sc_bufp, sp->scp_data, transbytes);
519 sp->scp_data += transbytes;
520 sp->scp_datalen -= transbytes;
522 else if (count > (u_int) bs->sc_seglen)
524 printf("%s: port data %x != seglen %x\n",
525 slp->sl_xname, count, bs->sc_seglen);
526 slp->sl_error |= PDMAERR;
529 scsi_low_data_finish(slp);
533 printf("%s: extra DMA interrupt\n", slp->sl_xname);
534 slp->sl_error |= PDMAERR;
540 /* common dma settings */
542 #define DMA1_SMSK (0x15)
544 #define DMA1_MODE (0x17)
546 #define DMA1_FFC (0x19)
548 #define DMA1_CHN(c) (0x01 + ((c) << 2))
550 #define DMA37SM_SET 0x04
551 #define DMA37MD_WRITE 0x04
552 #define DMA37MD_READ 0x08
553 #define DMA37MD_SINGLE 0x40
555 static bus_addr_t dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
558 bshw_dma_write_1(chp, port, val)
559 struct ct_bus_access_handle *chp;
572 struct scsi_low_softc *slp = &ct->sc_sclow;
573 struct bshw_softc *bs = ct->ct_hw;
574 struct ct_bus_access_handle *chp = &ct->sc_ch;
575 int chan = bs->sc_drq;
577 u_int8_t regv, *phys = bs->sc_segaddr;
578 u_int nbytes = bs->sc_seglen;
580 /* flush cpu cache */
581 (*bs->sc_dmasync_before) (ct);
584 * Program one of DMA channels 0..3. These are
585 * byte mode channels.
587 /* set dma channel mode, and reset address ff */
589 if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
590 regv = DMA37MD_WRITE | DMA37MD_SINGLE | chan;
592 regv = DMA37MD_READ | DMA37MD_SINGLE | chan;
594 bshw_dma_write_1(chp, DMA1_MODE, regv);
595 bshw_dma_write_1(chp, DMA1_FFC, 0);
597 /* send start address */
598 waport = DMA1_CHN(chan);
599 bshw_dma_write_1(chp, waport, (u_int) phys);
600 bshw_dma_write_1(chp, waport, ((u_int) phys) >> 8);
601 bshw_dma_write_1(chp, dmapageport[chan], ((u_int) phys) >> 16);
604 bshw_dma_write_1(chp, waport + 2, --nbytes);
605 bshw_dma_write_1(chp, waport + 2, nbytes >> 8);
607 /* vendor unique hook */
608 if (bs->sc_hw->hw_dma_start)
609 (*bs->sc_hw->hw_dma_start)(ct);
611 bshw_dma_write_1(chp, DMA1_SMSK, chan);
612 ct_cmdp_write_1(chp, CMDP_DMES);
619 struct bshw_softc *bs = ct->ct_hw;
620 struct ct_bus_access_handle *chp = &ct->sc_ch;
622 bshw_dma_write_1(chp, DMA1_SMSK, (bs->sc_drq | DMA37SM_SET));
623 ct_cmdp_write_1(chp, CMDP_DMER);
625 /* vendor unique hook */
626 if (bs->sc_hw->hw_dma_stop)
627 (*bs->sc_hw->hw_dma_stop) (ct);
629 /* flush cpu cache */
630 (*bs->sc_dmasync_after) (ct);
633 /**********************************************
634 * VENDOR UNIQUE DMA FUNCS
635 **********************************************/
636 static int bshw_dma_init_sc98(struct ct_softc *);
637 static void bshw_dma_start_sc98(struct ct_softc *);
638 static void bshw_dma_stop_sc98(struct ct_softc *);
639 static int bshw_dma_init_texa(struct ct_softc *);
640 static void bshw_dma_start_elecom(struct ct_softc *);
641 static void bshw_dma_stop_elecom(struct ct_softc *);
644 bshw_dma_init_texa(ct)
647 struct ct_bus_access_handle *chp = &ct->sc_ch;
650 if ((regval = ct_cr_read_1(chp, 0x37)) & 0x08)
653 ct_cr_write_1(chp, 0x37, regval | 0x08);
654 regval = ct_cr_read_1(chp, 0x3f);
655 ct_cr_write_1(chp, 0x3f, regval | 0x08);
660 bshw_dma_init_sc98(ct)
663 struct ct_bus_access_handle *chp = &ct->sc_ch;
665 if (ct_cr_read_1(chp, 0x37) & 0x08)
668 /* If your card is SC98 with bios ver 1.01 or 1.02 under no PCI */
669 ct_cr_write_1(chp, 0x37, 0x1a);
670 ct_cr_write_1(chp, 0x3f, 0x1a);
672 /* only valid for IO */
673 ct_cr_write_1(chp, 0x40, 0xf4);
674 ct_cr_write_1(chp, 0x41, 0x9);
675 ct_cr_write_1(chp, 0x43, 0xff);
676 ct_cr_write_1(chp, 0x46, 0x4e);
678 ct_cr_write_1(chp, 0x48, 0xf4);
679 ct_cr_write_1(chp, 0x49, 0x9);
680 ct_cr_write_1(chp, 0x4b, 0xff);
681 ct_cr_write_1(chp, 0x4e, 0x4e);
687 bshw_dma_start_sc98(ct)
690 struct ct_bus_access_handle *chp = &ct->sc_ch;
692 ct_cr_write_1(chp, 0x73, 0x32);
693 ct_cr_write_1(chp, 0x74, 0x23);
697 bshw_dma_stop_sc98(ct)
700 struct ct_bus_access_handle *chp = &ct->sc_ch;
702 ct_cr_write_1(chp, 0x73, 0x43);
703 ct_cr_write_1(chp, 0x74, 0x34);
707 bshw_dma_start_elecom(ct)
710 struct ct_bus_access_handle *chp = &ct->sc_ch;
711 u_int8_t tmp = ct_cr_read_1(chp, 0x4c);
713 ct_cr_write_1(chp, 0x32, tmp & 0xdf);
717 bshw_dma_stop_elecom(ct)
720 struct ct_bus_access_handle *chp = &ct->sc_ch;
721 u_int8_t tmp = ct_cr_read_1(chp, 0x4c);
723 ct_cr_write_1(chp, 0x32, tmp | 0x20);
726 static struct bshw bshw_generic = {
736 static struct bshw bshw_sc98 = {
746 static struct bshw bshw_texa = {
756 static struct bshw bshw_elecom = {
762 bshw_dma_start_elecom,
763 bshw_dma_stop_elecom,
766 static struct bshw bshw_lc_smit = {
767 BSHW_SMFIFO | BSHW_DOUBLE_DMACHAN,
776 static struct bshw bshw_lha20X = {
787 static dvcfg_hw_t bshw_hwsel_array[] = {
788 /* 0x00 */ &bshw_generic,
789 /* 0x01 */ &bshw_sc98,
790 /* 0x02 */ &bshw_texa,
791 /* 0x03 */ &bshw_elecom,
792 /* 0x04 */ &bshw_lc_smit,
793 /* 0x05 */ &bshw_lha20X,
796 struct dvcfg_hwsel bshw_hwsel = {
797 DVCFG_HWSEL_SZ(bshw_hwsel_array),