bshw_machdep.c revision 240325
1/* $NecBSD: bshw_machdep.c,v 1.8.12.6 2001/06/29 06:28:05 honda Exp $ */ 2 3#include <sys/cdefs.h> 4__FBSDID("$FreeBSD: head/sys/dev/ct/bshw_machdep.c 240325 2012-09-10 18:49:49Z jhb $"); 5/* $NetBSD$ */ 6 7/*- 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. 11 * 12 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 13 * Naofumi HONDA. All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 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. 25 * 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. 37 */ 38 39#include "opt_ddb.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/bio.h> 45#include <sys/buf.h> 46#include <sys/queue.h> 47#include <sys/malloc.h> 48#include <sys/errno.h> 49 50#include <vm/vm.h> 51 52#include <machine/bus.h> 53#include <machine/md_var.h> 54 55#include <compat/netbsd/dvcfg.h> 56 57#include <cam/scsi/scsi_low.h> 58 59#include <dev/ic/wd33c93reg.h> 60#include <dev/ct/ctvar.h> 61#include <dev/ct/ct_machdep.h> 62#include <dev/ct/bshwvar.h> 63 64#include <vm/pmap.h> 65 66#define BSHW_IO_CONTROL_FLAGS 0 67 68u_int bshw_io_control = BSHW_IO_CONTROL_FLAGS; 69int bshw_data_read_bytes = 4096; 70int bshw_data_write_bytes = 4096; 71 72/********************************************************* 73 * OS dep part 74 *********************************************************/ 75typedef unsigned long vaddr_t; 76 77/********************************************************* 78 * GENERIC MACHDEP FUNCTIONS 79 *********************************************************/ 80void 81bshw_synch_setup(ct, ti) 82 struct ct_softc *ct; 83 struct targ_info *ti; 84{ 85 struct ct_bus_access_handle *chp = &ct->sc_ch; 86 struct ct_targ_info *cti = (void *) ti; 87 struct bshw_softc *bs = ct->ct_hw; 88 struct bshw *hw = bs->sc_hw; 89 90 if (hw->hw_sregaddr == 0) 91 return; 92 93 ct_cr_write_1(chp, hw->hw_sregaddr + ti->ti_id, cti->cti_syncreg); 94 if (hw->hw_flags & BSHW_DOUBLE_DMACHAN) 95 { 96 ct_cr_write_1(chp, hw->hw_sregaddr + ti->ti_id + 8, 97 cti->cti_syncreg); 98 } 99} 100 101void 102bshw_bus_reset(ct) 103 struct ct_softc *ct; 104{ 105 struct scsi_low_softc *slp = &ct->sc_sclow; 106 struct ct_bus_access_handle *chp = &ct->sc_ch; 107 struct bshw_softc *bs = ct->ct_hw; 108 struct bshw *hw = bs->sc_hw; 109 bus_addr_t offs; 110 u_int8_t regv; 111 int i; 112 113 /* open hardware busmaster mode */ 114 if (hw->hw_dma_init != NULL && ((*hw->hw_dma_init)(ct)) != 0) 115 { 116 device_printf(slp->sl_dev, 117 "change mode using external DMA (%x)\n", 118 (u_int)ct_cr_read_1(chp, 0x37)); 119 } 120 121 /* clear hardware synch registers */ 122 offs = hw->hw_sregaddr; 123 if (offs != 0) 124 { 125 for (i = 0; i < 8; i ++, offs ++) 126 { 127 ct_cr_write_1(chp, offs, 0); 128 if ((hw->hw_flags & BSHW_DOUBLE_DMACHAN) != 0) 129 ct_cr_write_1(chp, offs + 8, 0); 130 } 131 } 132 133 /* disable interrupt & assert reset */ 134 regv = ct_cr_read_1(chp, wd3s_mbank); 135 regv |= MBR_RST; 136 regv &= ~MBR_IEN; 137 ct_cr_write_1(chp, wd3s_mbank, regv); 138 139 DELAY(500000); 140 141 /* reset signal off */ 142 regv &= ~MBR_RST; 143 ct_cr_write_1(chp, wd3s_mbank, regv); 144 145 /* interrupt enable */ 146 regv |= MBR_IEN; 147 ct_cr_write_1(chp, wd3s_mbank, regv); 148} 149 150/* probe */ 151int 152bshw_read_settings(chp, bs) 153 struct ct_bus_access_handle *chp; 154 struct bshw_softc *bs; 155{ 156 static int irq_tbl[] = { 3, 5, 6, 9, 12, 13 }; 157 158 bs->sc_hostid = (ct_cr_read_1(chp, wd3s_auxc) & AUXCR_HIDM); 159 bs->sc_irq = irq_tbl[(ct_cr_read_1(chp, wd3s_auxc) >> 3) & 7]; 160 bs->sc_drq = ct_cmdp_read_1(chp) & 3; 161 return 0; 162} 163 164/********************************************************* 165 * DMA PIO TRANSFER (SMIT) 166 *********************************************************/ 167#define LC_SMIT_TIMEOUT 2 /* 2 sec: timeout for a fifo status ready */ 168#define LC_SMIT_OFFSET 0x1000 169#define LC_FSZ DEV_BSIZE 170#define LC_SFSZ 0x0c 171#define LC_REST (LC_FSZ - LC_SFSZ) 172 173#define BSHW_LC_FSET 0x36 174#define BSHW_LC_FCTRL 0x44 175#define FCTRL_EN 0x01 176#define FCTRL_WRITE 0x02 177 178#define SF_ABORT 0x08 179#define SF_RDY 0x10 180 181static __inline void bshw_lc_smit_start(struct ct_softc *, int, u_int); 182static __inline void bshw_lc_smit_stop(struct ct_softc *); 183static int bshw_lc_smit_fstat(struct ct_softc *, int, int); 184 185static __inline void 186bshw_lc_smit_stop(ct) 187 struct ct_softc *ct; 188{ 189 struct ct_bus_access_handle *chp = &ct->sc_ch; 190 191 ct_cr_write_1(chp, BSHW_LC_FCTRL, 0); 192 ct_cmdp_write_1(chp, CMDP_DMER); 193} 194 195static __inline void 196bshw_lc_smit_start(ct, count, direction) 197 struct ct_softc *ct; 198 int count; 199 u_int direction; 200{ 201 struct ct_bus_access_handle *chp = &ct->sc_ch; 202 u_int8_t pval, val; 203 204 val = ct_cr_read_1(chp, BSHW_LC_FSET); 205 cthw_set_count(chp, count); 206 207 pval = FCTRL_EN; 208 if (direction == SCSI_LOW_WRITE) 209 pval |= (val & 0xe0) | FCTRL_WRITE; 210 ct_cr_write_1(chp, BSHW_LC_FCTRL, pval); 211 ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO); 212} 213 214static int 215bshw_lc_smit_fstat(ct, wc, read) 216 struct ct_softc *ct; 217 int wc, read; 218{ 219 struct ct_bus_access_handle *chp = &ct->sc_ch; 220 u_int8_t stat; 221 222 while (wc -- > 0) 223 { 224 chp->ch_bus_weight(chp); 225 stat = ct_cmdp_read_1(chp); 226 if (read == SCSI_LOW_READ) 227 { 228 if ((stat & SF_RDY) != 0) 229 return 0; 230 if ((stat & SF_ABORT) != 0) 231 return EIO; 232 } 233 else 234 { 235 if ((stat & SF_ABORT) != 0) 236 return EIO; 237 if ((stat & SF_RDY) != 0) 238 return 0; 239 } 240 } 241 242 device_printf(ct->sc_sclow.sl_dev, "SMIT fifo status timeout\n"); 243 return EIO; 244} 245 246void 247bshw_smit_xfer_stop(ct) 248 struct ct_softc *ct; 249{ 250 struct scsi_low_softc *slp = &ct->sc_sclow; 251 struct bshw_softc *bs = ct->ct_hw; 252 struct targ_info *ti; 253 struct sc_p *sp = &slp->sl_scp; 254 u_int count; 255 256 bshw_lc_smit_stop(ct); 257 258 ti = slp->sl_Tnexus; 259 if (ti == NULL) 260 return; 261 262 if (ti->ti_phase == PH_DATA) 263 { 264 count = cthw_get_count(&ct->sc_ch); 265 if (count < bs->sc_sdatalen) 266 { 267 if (sp->scp_direction == SCSI_LOW_READ && 268 count != bs->sc_edatalen) 269 goto bad; 270 271 count = bs->sc_sdatalen - count; 272 if (count > (u_int) sp->scp_datalen) 273 goto bad; 274 275 sp->scp_data += count; 276 sp->scp_datalen -= count; 277 } 278 else if (count > bs->sc_sdatalen) 279 { 280bad: 281 device_printf(slp->sl_dev, 282 "smit_xfer_end: cnt error\n"); 283 slp->sl_error |= PDMAERR; 284 } 285 scsi_low_data_finish(slp); 286 } 287 else 288 { 289 device_printf(slp->sl_dev, "smit_xfer_end: phase miss\n"); 290 slp->sl_error |= PDMAERR; 291 } 292} 293 294int 295bshw_smit_xfer_start(ct) 296 struct ct_softc *ct; 297{ 298 struct scsi_low_softc *slp = &ct->sc_sclow; 299 struct ct_bus_access_handle *chp = &ct->sc_ch; 300 struct bshw_softc *bs = ct->ct_hw; 301 struct sc_p *sp = &slp->sl_scp; 302 struct targ_info *ti = slp->sl_Tnexus; 303 struct ct_targ_info *cti = (void *) ti; 304 u_int datalen, count, io_control; 305 int wc; 306 u_int8_t *data; 307 308 io_control = bs->sc_io_control | bshw_io_control; 309 if ((io_control & BSHW_SMIT_BLOCK) != 0) 310 return EINVAL; 311 312 if ((slp->sl_scp.scp_datalen % DEV_BSIZE) != 0) 313 return EINVAL; 314 315 datalen = sp->scp_datalen; 316 if (slp->sl_scp.scp_direction == SCSI_LOW_READ) 317 { 318 if ((io_control & BSHW_READ_INTERRUPT_DRIVEN) != 0 && 319 datalen > bshw_data_read_bytes) 320 datalen = bshw_data_read_bytes; 321 } 322 else 323 { 324 if ((io_control & BSHW_WRITE_INTERRUPT_DRIVEN) != 0 && 325 datalen > bshw_data_write_bytes) 326 datalen = bshw_data_write_bytes; 327 } 328 329 bs->sc_sdatalen = datalen; 330 data = sp->scp_data; 331 wc = LC_SMIT_TIMEOUT * 1024 * 1024; 332 333 ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA); 334 bshw_lc_smit_start(ct, datalen, sp->scp_direction); 335 336 if (sp->scp_direction == SCSI_LOW_READ) 337 { 338 do 339 { 340 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_READ)) 341 break; 342 343 count = (datalen > LC_FSZ ? LC_FSZ : datalen); 344 bus_space_read_region_4(chp->ch_memt, chp->ch_memh, 345 LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2); 346 data += count; 347 datalen -= count; 348 } 349 while (datalen > 0); 350 351 bs->sc_edatalen = datalen; 352 } 353 else 354 { 355 do 356 { 357 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_WRITE)) 358 break; 359 if (cti->cti_syncreg == 0) 360 { 361 /* XXX: 362 * If async transfer, reconfirm a scsi phase 363 * again. Unless C bus might hang up. 364 */ 365 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_WRITE)) 366 break; 367 } 368 369 count = (datalen > LC_SFSZ ? LC_SFSZ : datalen); 370 bus_space_write_region_4(chp->ch_memt, chp->ch_memh, 371 LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2); 372 data += count; 373 datalen -= count; 374 375 if (bshw_lc_smit_fstat(ct, wc, SCSI_LOW_WRITE)) 376 break; 377 378 count = (datalen > LC_REST ? LC_REST : datalen); 379 bus_space_write_region_4(chp->ch_memt, chp->ch_memh, 380 LC_SMIT_OFFSET + LC_SFSZ, 381 (u_int32_t *) data, count >> 2); 382 data += count; 383 datalen -= count; 384 } 385 while (datalen > 0); 386 } 387 return 0; 388} 389 390/********************************************************* 391 * DMA TRANSFER (BS) 392 *********************************************************/ 393static __inline void bshw_dma_write_1 \ 394 (struct ct_bus_access_handle *, bus_addr_t, u_int8_t); 395static void bshw_dmastart(struct ct_softc *); 396static void bshw_dmadone(struct ct_softc *); 397 398int 399bshw_dma_xfer_start(ct) 400 struct ct_softc *ct; 401{ 402 struct scsi_low_softc *slp = &ct->sc_sclow; 403 struct sc_p *sp = &slp->sl_scp; 404 struct ct_bus_access_handle *chp = &ct->sc_ch; 405 struct bshw_softc *bs = ct->ct_hw; 406 vaddr_t va, endva, phys, nphys; 407 u_int io_control; 408 409 io_control = bs->sc_io_control | bshw_io_control; 410 if ((io_control & BSHW_DMA_BLOCK) != 0 && sp->scp_datalen < 256) 411 return EINVAL; 412 413 ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA); 414 phys = vtophys((vaddr_t) sp->scp_data); 415 if (phys >= bs->sc_minphys) 416 { 417 /* setup segaddr */ 418 bs->sc_segaddr = bs->sc_bounce_phys; 419 /* setup seglen */ 420 bs->sc_seglen = sp->scp_datalen; 421 if (bs->sc_seglen > bs->sc_bounce_size) 422 bs->sc_seglen = bs->sc_bounce_size; 423 /* setup bufp */ 424 bs->sc_bufp = bs->sc_bounce_addr; 425 if (sp->scp_direction == SCSI_LOW_WRITE) 426 bcopy(sp->scp_data, bs->sc_bufp, bs->sc_seglen); 427 } 428 else 429 { 430 /* setup segaddr */ 431 bs->sc_segaddr = (u_int8_t *) phys; 432 /* setup seglen */ 433 endva = (vaddr_t) round_page((vaddr_t) sp->scp_data + sp->scp_datalen); 434 for (va = (vaddr_t) sp->scp_data; ; phys = nphys) 435 { 436 if ((va += PAGE_SIZE) >= endva) 437 { 438 bs->sc_seglen = sp->scp_datalen; 439 break; 440 } 441 442 nphys = vtophys(va); 443 if (phys + PAGE_SIZE != nphys || nphys >= bs->sc_minphys) 444 { 445 bs->sc_seglen = 446 (u_int8_t *) trunc_page(va) - sp->scp_data; 447 break; 448 } 449 } 450 /* setup bufp */ 451 bs->sc_bufp = NULL; 452 } 453 454 bshw_dmastart(ct); 455 cthw_set_count(chp, bs->sc_seglen); 456 ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO); 457 return 0; 458} 459 460void 461bshw_dma_xfer_stop(ct) 462 struct ct_softc *ct; 463{ 464 struct scsi_low_softc *slp = &ct->sc_sclow; 465 struct sc_p *sp = &slp->sl_scp; 466 struct bshw_softc *bs = ct->ct_hw; 467 struct targ_info *ti; 468 u_int count, transbytes; 469 470 bshw_dmadone(ct); 471 472 ti = slp->sl_Tnexus; 473 if (ti == NULL) 474 return; 475 476 if (ti->ti_phase == PH_DATA) 477 { 478 count = cthw_get_count(&ct->sc_ch); 479 if (count < (u_int) bs->sc_seglen) 480 { 481 transbytes = bs->sc_seglen - count; 482 if (bs->sc_bufp != NULL && 483 sp->scp_direction == SCSI_LOW_READ) 484 bcopy(bs->sc_bufp, sp->scp_data, transbytes); 485 486 sp->scp_data += transbytes; 487 sp->scp_datalen -= transbytes; 488 } 489 else if (count > (u_int) bs->sc_seglen) 490 { 491 device_printf(slp->sl_dev, 492 "port data %x != seglen %x\n", 493 count, bs->sc_seglen); 494 slp->sl_error |= PDMAERR; 495 } 496 497 scsi_low_data_finish(slp); 498 } 499 else 500 { 501 device_printf(slp->sl_dev, "extra DMA interrupt\n"); 502 slp->sl_error |= PDMAERR; 503 } 504 505 bs->sc_bufp = NULL; 506} 507 508/* common dma settings */ 509#undef DMA1_SMSK 510#define DMA1_SMSK (0x15) 511#undef DMA1_MODE 512#define DMA1_MODE (0x17) 513#undef DMA1_FFC 514#define DMA1_FFC (0x19) 515#undef DMA1_CHN 516#define DMA1_CHN(c) (0x01 + ((c) << 2)) 517 518#define DMA37SM_SET 0x04 519#define DMA37MD_WRITE 0x04 520#define DMA37MD_READ 0x08 521#define DMA37MD_SINGLE 0x40 522 523static bus_addr_t dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 }; 524 525static __inline void 526bshw_dma_write_1(chp, port, val) 527 struct ct_bus_access_handle *chp; 528 bus_addr_t port; 529 u_int8_t val; 530{ 531 532 CT_BUS_WEIGHT(chp); 533 outb(port, val); 534} 535 536static void 537bshw_dmastart(ct) 538 struct ct_softc *ct; 539{ 540 struct scsi_low_softc *slp = &ct->sc_sclow; 541 struct bshw_softc *bs = ct->ct_hw; 542 struct ct_bus_access_handle *chp = &ct->sc_ch; 543 int chan = bs->sc_drq; 544 bus_addr_t waport; 545 u_int8_t regv, *phys = bs->sc_segaddr; 546 u_int nbytes = bs->sc_seglen; 547 548 /* flush cpu cache */ 549 (*bs->sc_dmasync_before) (ct); 550 551 /* 552 * Program one of DMA channels 0..3. These are 553 * byte mode channels. 554 */ 555 /* set dma channel mode, and reset address ff */ 556 557 if (slp->sl_scp.scp_direction == SCSI_LOW_READ) 558 regv = DMA37MD_WRITE | DMA37MD_SINGLE | chan; 559 else 560 regv = DMA37MD_READ | DMA37MD_SINGLE | chan; 561 562 bshw_dma_write_1(chp, DMA1_MODE, regv); 563 bshw_dma_write_1(chp, DMA1_FFC, 0); 564 565 /* send start address */ 566 waport = DMA1_CHN(chan); 567 bshw_dma_write_1(chp, waport, (u_int) phys); 568 bshw_dma_write_1(chp, waport, ((u_int) phys) >> 8); 569 bshw_dma_write_1(chp, dmapageport[chan], ((u_int) phys) >> 16); 570 571 /* send count */ 572 bshw_dma_write_1(chp, waport + 2, --nbytes); 573 bshw_dma_write_1(chp, waport + 2, nbytes >> 8); 574 575 /* vendor unique hook */ 576 if (bs->sc_hw->hw_dma_start) 577 (*bs->sc_hw->hw_dma_start)(ct); 578 579 bshw_dma_write_1(chp, DMA1_SMSK, chan); 580 ct_cmdp_write_1(chp, CMDP_DMES); 581} 582 583static void 584bshw_dmadone(ct) 585 struct ct_softc *ct; 586{ 587 struct bshw_softc *bs = ct->ct_hw; 588 struct ct_bus_access_handle *chp = &ct->sc_ch; 589 590 bshw_dma_write_1(chp, DMA1_SMSK, (bs->sc_drq | DMA37SM_SET)); 591 ct_cmdp_write_1(chp, CMDP_DMER); 592 593 /* vendor unique hook */ 594 if (bs->sc_hw->hw_dma_stop) 595 (*bs->sc_hw->hw_dma_stop) (ct); 596 597 /* flush cpu cache */ 598 (*bs->sc_dmasync_after) (ct); 599} 600 601/********************************************** 602 * VENDOR UNIQUE DMA FUNCS 603 **********************************************/ 604static int bshw_dma_init_sc98(struct ct_softc *); 605static void bshw_dma_start_sc98(struct ct_softc *); 606static void bshw_dma_stop_sc98(struct ct_softc *); 607static int bshw_dma_init_texa(struct ct_softc *); 608static void bshw_dma_start_elecom(struct ct_softc *); 609static void bshw_dma_stop_elecom(struct ct_softc *); 610 611static int 612bshw_dma_init_texa(ct) 613 struct ct_softc *ct; 614{ 615 struct ct_bus_access_handle *chp = &ct->sc_ch; 616 u_int8_t regval; 617 618 if ((regval = ct_cr_read_1(chp, 0x37)) & 0x08) 619 return 0; 620 621 ct_cr_write_1(chp, 0x37, regval | 0x08); 622 regval = ct_cr_read_1(chp, 0x3f); 623 ct_cr_write_1(chp, 0x3f, regval | 0x08); 624 return 1; 625} 626 627static int 628bshw_dma_init_sc98(ct) 629 struct ct_softc *ct; 630{ 631 struct ct_bus_access_handle *chp = &ct->sc_ch; 632 633 if (ct_cr_read_1(chp, 0x37) & 0x08) 634 return 0; 635 636 /* If your card is SC98 with bios ver 1.01 or 1.02 under no PCI */ 637 ct_cr_write_1(chp, 0x37, 0x1a); 638 ct_cr_write_1(chp, 0x3f, 0x1a); 639#if 0 640 /* only valid for IO */ 641 ct_cr_write_1(chp, 0x40, 0xf4); 642 ct_cr_write_1(chp, 0x41, 0x9); 643 ct_cr_write_1(chp, 0x43, 0xff); 644 ct_cr_write_1(chp, 0x46, 0x4e); 645 646 ct_cr_write_1(chp, 0x48, 0xf4); 647 ct_cr_write_1(chp, 0x49, 0x9); 648 ct_cr_write_1(chp, 0x4b, 0xff); 649 ct_cr_write_1(chp, 0x4e, 0x4e); 650#endif 651 return 1; 652} 653 654static void 655bshw_dma_start_sc98(ct) 656 struct ct_softc *ct; 657{ 658 struct ct_bus_access_handle *chp = &ct->sc_ch; 659 660 ct_cr_write_1(chp, 0x73, 0x32); 661 ct_cr_write_1(chp, 0x74, 0x23); 662} 663 664static void 665bshw_dma_stop_sc98(ct) 666 struct ct_softc *ct; 667{ 668 struct ct_bus_access_handle *chp = &ct->sc_ch; 669 670 ct_cr_write_1(chp, 0x73, 0x43); 671 ct_cr_write_1(chp, 0x74, 0x34); 672} 673 674static void 675bshw_dma_start_elecom(ct) 676 struct ct_softc *ct; 677{ 678 struct ct_bus_access_handle *chp = &ct->sc_ch; 679 u_int8_t tmp = ct_cr_read_1(chp, 0x4c); 680 681 ct_cr_write_1(chp, 0x32, tmp & 0xdf); 682} 683 684static void 685bshw_dma_stop_elecom(ct) 686 struct ct_softc *ct; 687{ 688 struct ct_bus_access_handle *chp = &ct->sc_ch; 689 u_int8_t tmp = ct_cr_read_1(chp, 0x4c); 690 691 ct_cr_write_1(chp, 0x32, tmp | 0x20); 692} 693 694static struct bshw bshw_generic = { 695 BSHW_SYNC_RELOAD, 696 697 0, 698 699 NULL, 700 NULL, 701 NULL, 702}; 703 704static struct bshw bshw_sc98 = { 705 BSHW_DOUBLE_DMACHAN, 706 707 0x60, 708 709 bshw_dma_init_sc98, 710 bshw_dma_start_sc98, 711 bshw_dma_stop_sc98, 712}; 713 714static struct bshw bshw_texa = { 715 BSHW_DOUBLE_DMACHAN, 716 717 0x60, 718 719 bshw_dma_init_texa, 720 NULL, 721 NULL, 722}; 723 724static struct bshw bshw_elecom = { 725 0, 726 727 0x38, 728 729 NULL, 730 bshw_dma_start_elecom, 731 bshw_dma_stop_elecom, 732}; 733 734static struct bshw bshw_lc_smit = { 735 BSHW_SMFIFO | BSHW_DOUBLE_DMACHAN, 736 737 0x60, 738 739 NULL, 740 NULL, 741 NULL, 742}; 743 744static struct bshw bshw_lha20X = { 745 BSHW_DOUBLE_DMACHAN, 746 747 0x60, 748 749 NULL, 750 NULL, 751 NULL, 752}; 753 754/* hw tabs */ 755static dvcfg_hw_t bshw_hwsel_array[] = { 756/* 0x00 */ &bshw_generic, 757/* 0x01 */ &bshw_sc98, 758/* 0x02 */ &bshw_texa, 759/* 0x03 */ &bshw_elecom, 760/* 0x04 */ &bshw_lc_smit, 761/* 0x05 */ &bshw_lha20X, 762}; 763 764struct dvcfg_hwsel bshw_hwsel = { 765 DVCFG_HWSEL_SZ(bshw_hwsel_array), 766 bshw_hwsel_array 767}; 768