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