1 /* $FreeBSD: src/sys/i386/isa/bs/bshw_dma.c,v 1.6.6.1 2000/10/21 07:44:26 nyan Exp $ */
2 /* $NecBSD: bshw_dma.c,v 1.3 1997/07/26 06:03:16 honda Exp $ */
5 * [NetBSD for NEC PC98 series]
6 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
36 /*********************************************************
38 *********************************************************/
39 static void bshw_dmastart __P((struct bs_softc *));
40 static void bshw_dmadone __P((struct bs_softc *));
42 /**********************************************
43 * UPPER INTERFACE FUNCS (all funcs exported)
44 **********************************************/
46 bshw_dmaabort(bsc, ti)
53 bshw_set_count(bsc, 0);
58 struct targ_info *tmpti;
60 for (i = 0; i < NTARGETS; i++)
61 if ((tmpti = bsc->sc_ti[i]) != NULL)
62 tmpti->ti_scsp.seglen = 0;
65 ti->ti_scsp.seglen = 0;
70 bs_dma_xfer(ti, direction)
74 vm_offset_t va, endva, phys, nphys;
75 struct bs_softc *bsc = ti->ti_bsc;
76 struct sc_p *sp = &bsc->sc_p;
78 bsc->sc_dmadir = direction;
79 bshw_set_dma_trans(bsc, ti->ti_cfgflags);
83 phys = vtophys((vm_offset_t) sp->data);
87 sp->segaddr = ti->bounce_phys;
89 sp->seglen = sp->datalen;
90 if (sp->seglen > ti->bounce_size)
91 sp->seglen = ti->bounce_size;
93 sp->bufp = ti->bounce_addr;
94 if (bsc->sc_dmadir != BSHW_READ)
95 bcopy(sp->data, sp->bufp, sp->seglen);
97 bs_bounce_used[ti->ti_id]++;
98 #endif /* BS_STATICS */
103 sp->segaddr = (u_int8_t *) phys;
105 endva = (vm_offset_t)round_page((unsigned long)(sp->data + sp->datalen));
106 for (va = (vm_offset_t) sp->data; ; phys = nphys)
108 if ((va += BSHW_NBPG) >= endva)
110 sp->seglen = sp->datalen;
115 if (phys + BSHW_NBPG != nphys || nphys >= RAM_END)
118 (u_int8_t *) trunc_page(va) - sp->data;
128 bshw_set_count(bsc, sp->seglen);
133 struct targ_info *ti;
135 struct bs_softc *bsc = ti->ti_bsc;
136 struct sc_p *sp = &bsc->sc_p;
137 u_int count, transbytes;
140 if (ti->ti_phase == DATAPHASE)
142 count = bshw_get_count(bsc);
143 if (count < (u_int) sp->seglen)
145 transbytes = sp->seglen - count;
148 if (bsc->sc_dmadir == BSHW_READ)
149 bcopy(sp->bufp, sp->data, transbytes);
150 sp->bufp += transbytes;
153 sp->segaddr += transbytes;
154 sp->data += transbytes;
155 sp->datalen -= transbytes;
158 else if (count == (u_int) sp->seglen)
163 bs_printf(ti, "xfer_end", "strange count");
164 printf("port data %x seglen %x\n", count, sp->seglen);
167 bs_printf(ti, "xfer_end", "extra dma interrupt");
169 ti->ti_error |= BSDMAABNORMAL;
170 sp->seglen = ti->ti_scsp.seglen = 0; /* XXX */
173 /**********************************************
175 **********************************************/
176 static u_int8_t dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
178 /* common dma settings */
180 #define DMA1_SMSK (0x15)
182 #define DMA1_MODE (0x17)
184 #define DMA1_FFC (0x19)
186 #define DMA37SM_SET 0x04
188 #define DMA1_CHN(c) (0x01 + ((c) << 2))
192 struct bs_softc *bsc;
194 int chan = bsc->sc_dmachan;
196 u_int8_t *phys = bsc->sc_p.segaddr;
197 u_int nbytes = bsc->sc_p.seglen;
200 * Program one of DMA channels 0..3. These are
201 * byte mode channels.
203 /* set dma channel mode, and reset address ff */
205 if (need_pre_dma_flush)
207 #else /* NetBSD/pc98 */
208 if (bsc->sc_dmadir & BSHW_READ)
209 cpu_cf_preRead(curcpu);
211 cpu_cf_preWrite(curcpu);
214 if (bsc->sc_dmadir & BSHW_READ)
215 outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_WRITE | chan);
217 outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_READ | chan);
220 /* send start address */
221 waport = DMA1_CHN(chan);
222 outb(waport, (u_int) phys);
223 outb(waport, ((u_int) phys) >> 8);
224 outb(dmapageport[chan], ((u_int) phys) >> 16);
227 outb(waport + 2, --nbytes);
228 outb(waport + 2, nbytes >> 8);
230 /* vendor unique hook */
231 if (bsc->sc_hw->dma_start)
232 (*bsc->sc_hw->dma_start)(bsc);
234 outb(DMA1_SMSK, chan);
235 BUS_IOW(cmd_port, CMDP_DMES);
237 bsc->sc_flags |= BSDMASTART;
242 struct bs_softc *bsc;
245 outb(DMA1_SMSK, (bsc->sc_dmachan | DMA37SM_SET));
246 BUS_IOW(cmd_port, CMDP_DMER);
248 /* vendor unique hook */
249 if (bsc->sc_hw->dma_stop)
250 (*bsc->sc_hw->dma_stop)(bsc);
253 if (need_post_dma_flush)
256 if (bsc->sc_dmadir & BSHW_READ)
257 cpu_cf_postRead(curcpu);
259 cpu_cf_postWrite(curcpu);
262 bsc->sc_flags &= (~BSDMASTART);
265 /**********************************************
266 * VENDOR UNIQUE DMA FUNCS
267 **********************************************/
269 bshw_dma_init_texa(bsc)
270 struct bs_softc *bsc;
274 if ((regval = read_wd33c93(bsc, 0x37)) & 0x08)
277 write_wd33c93(bsc, 0x37, regval | 0x08);
278 regval = read_wd33c93(bsc, 0x3f);
279 write_wd33c93(bsc, 0x3f, regval | 0x08);
284 bshw_dma_init_sc98(bsc)
285 struct bs_softc *bsc;
288 if (read_wd33c93(bsc, 0x37) & 0x08)
291 /* If your card is SC98 with bios ver 1.01 or 1.02 under no PCI */
292 write_wd33c93(bsc, 0x37, 0x1a);
293 write_wd33c93(bsc, 0x3f, 0x1a);
295 /* only valid for IO */
296 write_wd33c93(bsc, 0x40, 0xf4);
297 write_wd33c93(bsc, 0x41, 0x9);
298 write_wd33c93(bsc, 0x43, 0xff);
299 write_wd33c93(bsc, 0x46, 0x4e);
301 write_wd33c93(bsc, 0x48, 0xf4);
302 write_wd33c93(bsc, 0x49, 0x9);
303 write_wd33c93(bsc, 0x4b, 0xff);
304 write_wd33c93(bsc, 0x4e, 0x4e);
310 bshw_dma_start_sc98(bsc)
311 struct bs_softc *bsc;
314 write_wd33c93(bsc, 0x73, 0x32);
315 write_wd33c93(bsc, 0x74, 0x23);
319 bshw_dma_stop_sc98(bsc)
320 struct bs_softc *bsc;
323 write_wd33c93(bsc, 0x73, 0x43);
324 write_wd33c93(bsc, 0x74, 0x34);
328 bshw_dma_start_elecom(bsc)
329 struct bs_softc *bsc;
331 u_int8_t tmp = read_wd33c93(bsc, 0x4c);
333 write_wd33c93(bsc, 0x32, tmp & 0xdf);
337 bshw_dma_stop_elecom(bsc)
338 struct bs_softc *bsc;
340 u_int8_t tmp = read_wd33c93(bsc, 0x4c);
342 write_wd33c93(bsc, 0x32, tmp | 0x20);