1 /* $NecBSD: bshw.c,v 1.1 1997/07/18 09:19:03 kmatsuda Exp $ */
4 * [NetBSD for NEC PC98 series]
5 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
34 * $FreeBSD: src/sys/i386/isa/bs/bshw.c,v 1.7.2.1 2001/07/26 02:32:18 nyan Exp $
38 #include <dev/isa/isadmareg.h>
39 #include <i386/Cbus/dev/bs/bsif.h>
40 #include <i386/Cbus/dev/bs/bshw.lst>
44 #include <i386/isa/ic/i8237.h>
45 #include <i386/isa/bs/bsif.h>
46 #include <i386/isa/bs/bshw.lst>
47 #include <machine/clock.h>
51 static struct bs_softc *gbsc;
53 /**************************************************
55 **************************************************/
56 static void bshw_force_bsmode __P((struct bs_softc *));
58 /**************************************************
60 **************************************************/
61 static int irq_tbl[] = { 3, 5, 6, 9, 12, 13 };
63 /**************************************************
65 **************************************************/
66 #define RS (BSSAT | BSSMIT | BSLINK | BSREAD)
67 #define WS (BSSAT | BSSMIT | BSLINK)
68 #define EOK (BSERROROK)
70 u_int8_t bshw_cmd[256] = {
71 /* 0 1 2 3 4 5 6 7 8 9 A B C E D F */
72 /*0*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,RS ,0 ,WS ,0 ,0 ,0 ,0 ,0 ,
73 /*1*/0 ,0 ,EOK,0 ,0 ,0 ,0 ,0 ,0 ,0 ,EOK,0 ,0 ,0 ,0 ,0 ,
74 /*2*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,RS ,0 ,WS ,0 ,0 ,0 ,0 ,0 ,
75 /*3*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
76 /*4*/0 ,0 ,EOK,EOK,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
77 /*5*/0 ,0 ,0 ,0 ,EOK,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
78 /*6*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
79 /*7*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
80 /*8*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
81 /*9*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
82 /*A*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
83 /*B*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
84 /*C*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
85 /*D*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
86 /*E*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
87 /*F*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
94 /**********************************************
96 **********************************************/
98 bshw_force_bsmode(bsc)
102 if (bsc->sc_flags & BSBSMODE)
104 bsc->sc_flags |= BSBSMODE;
107 * If you have memory over 16M, some stupid boards always force to
108 * use the io polling mode. Check such a case and change mode into
109 * bus master DMA. However this depends heavily on the board's
113 if (bsc->sc_hw->dma_init && ((*bsc->sc_hw->dma_init)(bsc)))
114 printf("%s change mode using external DMA (%x)\n",
115 bsc->sc_dvname, (u_int)read_wd33c93(bsc, 0x37));
118 #define RESET_DEFAULT 2000
122 struct bs_softc *bsc;
132 bshw_get_auxstat(bsc);
133 bshw_get_busstat(bsc);
135 write_wd33c93(bsc, wd3s_oid, IDR_EHP | bsc->sc_cspeed | bsc->sc_hostid);
136 write_wd33c93(bsc, wd3s_cmd, WD3S_RESET);
138 for (ct = RESET_DEFAULT; ct > 0; ct--)
140 aux = bshw_get_auxstat(bsc);
141 if (aux != 0xff && (aux & STR_INT))
143 if (bshw_get_busstat(bsc) == 0)
146 write_wd33c93(bsc, wd3s_cmd, WD3S_RESET);
157 bshw_force_bsmode(bsc);
159 write_wd33c93(bsc, wd3s_tout, BSHW_SEL_TIMEOUT);
160 write_wd33c93(bsc, wd3s_sid, SIDR_RESEL);
161 bsc->sc_flags |= BSDMATRANSFER;
162 write_wd33c93(bsc, wd3s_ctrl, CR_DEFAULT);
163 write_wd33c93(bsc, wd3s_synch, 0);
165 bshw_get_auxstat(bsc);
166 bsc->sc_busstat = bshw_get_busstat(bsc);
172 /* scsi bus hard reset */
173 #define TWIDDLEWAIT 10000
175 static char tw_chars[] = "|/-\\";
177 /* this is some jokes */
183 cnputc(tw_chars[tw_pos++]);
184 tw_pos %= (sizeof(tw_chars) - 1);
188 static void bshw_set_vsp __P((struct bs_softc *, u_int, u_int8_t));
191 bshw_set_vsp(bsc, chan, spva)
192 struct bs_softc *bsc;
196 struct bshw *hw = bsc->sc_hw;
198 if (hw->sregaddr == 0)
201 write_wd33c93(bsc, hw->sregaddr + chan, spva);
202 if (hw->hw_flags & BSHW_DOUBLE_DMACHAN)
203 write_wd33c93(bsc, hw->sregaddr + chan + 8, spva);
208 struct bs_softc *bsc;
210 struct targ_info *ti;
213 if (bsc->sc_RSTdelay == 0)
214 bsc->sc_RSTdelay = 6 * 1000 * 1000;
218 * second time reset will be requested by hardware failuer.
220 bsc->sc_RSTdelay = 12 * 1000 * 1000;
224 write_wd33c93(bsc, wd3s_mbank, (bsc->sc_membank | MBR_RST) & ~MBR_IEN);
226 write_wd33c93(bsc, wd3s_mbank, (bsc->sc_membank) & ~MBR_IEN);
229 for (lpc = 0; lpc < 2; lpc ++)
232 for (i = 0; i <= bsc->sc_RSTdelay / TWIDDLEWAIT; i++)
236 (void) read_wd33c93(bsc, wd3s_auxc);
240 if ((read_wd33c93(bsc, wd3s_auxc) & AUXCR_RRST) == 0)
243 printf("\nreset state still continue, wait ...");
246 for (i = 0; i < NTARGETS; i++)
248 if ((ti = bsc->sc_ti[i]) != NULL)
251 bshw_set_vsp(bsc, i, 0);
258 bshw_board_probe(bsc, drq, irq)
259 struct bs_softc *bsc;
266 bshw_print_port(bsc);
267 #endif /* SHOW_PORT */
269 bsc->sc_hostid = (read_wd33c93(bsc, wd3s_auxc) & AUXCR_HIDM);
271 if ((*irq) == IRQUNK)
272 *irq = irq_tbl[(read_wd33c93(bsc, wd3s_auxc) >> 3) & 7];
274 if ((*drq) == DRQUNK)
275 *drq = BUS_IOR(cmd_port) & 3;
277 bsc->sc_dmachan = *drq;
278 bsc->sc_irq = (*irq);
280 bsc->sc_membank = read_wd33c93(bsc, wd3s_mbank);
281 bsc->sc_membank &= ~MBR_RST;
282 bsc->sc_membank |= MBR_IEN;
284 bsc->sc_cspeed = (read_wd33c93(bsc, wd3s_oid) & (~IDR_IDM));
285 switch (BSC_CHIP_CLOCK(bsc->sc_cfgflags))
291 bsc->sc_cspeed &= ~(IDR_FS_12_15 | IDR_FS_16_20);
295 bsc->sc_cspeed &= ~(IDR_FS_12_15 | IDR_FS_16_20);
296 bsc->sc_cspeed |= IDR_FS_12_15;
300 bsc->sc_cspeed &= ~(IDR_FS_12_15 | IDR_FS_16_20);
301 bsc->sc_cspeed |= IDR_FS_16_20;
305 /* XXX: host id fixed(7) */
308 if (bshw_chip_reset(bsc))
316 * Assume the board clock rate must be 20Mhz (always satisfied, maybe)!
317 * Only 10M/s 6.6M/s 5.0M/s 3.3M/s for synchronus transfer speed set.
319 #define ILLEGAL_SYNCH
321 /* A 10 6.6 5.0 4.0 3.3 2.8 2.5 2.0 M/s */
322 /* X 100 150 200 250 300 350 400 500 ns */
323 static u_int bshw_scsi_period[] =
324 {0, 25, 37, 50, 62, 75, 87, 100, 125};
325 static u_int8_t bshw_chip_pval[] =
326 {0, 0xa0, 0xb0, 0x20, 0xd0, 0x30, 0xf0, 0x40, 0x50};
327 #else /* !ILLEGAL_SYNCH */
328 /* A 10 6.6 5.0 3.3 2.5 M/s */
329 /* X 100 150 200 300 400 ns */
330 static u_int bshw_scsi_period[] =
331 {0, 25, 37, 50, 75, 100};
332 static u_int8_t bshw_chip_pval[] =
333 {0, 0xa0, 0xb0, 0x20, 0x30, 0x40};
334 #endif /* !ILLEGAL_SYNCH */
337 bshw_adj_syncdata(sdp)
338 struct syncdata *sdp;
342 if (sdp->offset == 0 || sdp->period < 25 || sdp->period > 100)
343 sdp->offset = sdp->period = 0;
346 for (i = 0; sdp->period > bshw_scsi_period[i] + 2; i ++)
348 sdp->period = bshw_scsi_period[i];
353 bshw_set_synchronous(bsc, ti)
354 struct bs_softc *bsc;
355 struct targ_info *ti;
361 bshw_adj_syncdata(&sd);
362 for (i = 0; sd.period != bshw_scsi_period[i]; i++)
365 ti->ti_sync = ((sd.offset & 0x0f) | bshw_chip_pval[i]);
366 bshw_set_vsp(bsc, ti->ti_id, ti->ti_sync);
368 if (bsc->sc_nexus == ti)
369 bshw_set_sync_reg(bsc, ti->ti_sync);
374 bshw_setup_ctrl_reg(bsc, flags)
375 struct bs_softc *bsc;
380 regval = (flags & BS_SCSI_NOPARITY) ? CR_DEFAULT : CR_DEFAULT_HP;
381 if (bsc->sc_flags & BSDMATRANSFER)
383 write_wd33c93(bsc, wd3s_ctrl, regval);
388 bshw_issue_satcmd(bsc, cb, link)
389 struct bs_softc *bsc;
395 BUS_IOW(addr_port, wd3s_cdb);
396 for (i = 0; i < cb->cmdlen - 1; i++)
397 BUS_IOW(ctrl_port, cb->cmd[i]);
398 BUS_IOW(ctrl_port, cb->cmd[i] | (link ? 1 : 0));
404 struct bs_softc *bsc;
408 write_wd33c93(bsc, wd3s_mbank, bsc->sc_membank & (~MBR_IEN));
413 struct bs_softc *bsc;
416 if ((--bsc->sc_hwlock) <= 0)
417 write_wd33c93(bsc, wd3s_mbank, bsc->sc_membank);
420 /**********************************************
422 **********************************************/
424 #include <i386/Cbus/dev/bs/bshw_dma.c>
425 #include <i386/Cbus/dev/bs/bshw_pdma.c>
428 #include <i386/isa/bs/bshw_dma.c>
429 #include <i386/isa/bs/bshw_pdma.c>
432 /**********************************************
434 **********************************************/
438 struct bs_softc * bsc;
447 for (j = 0; j <= 0x70; j += 0x10)
449 printf("port %x: ", port);
450 for (i = 0; i < 0x10; i++)
451 printf("%x ", (u_int) read_wd33c93(bsc, port++));