Mon Nov 27 10:21:26 2017 UTC ()
Pull up following revision(s) (requested by jmcneill in ticket #391):
	sys/dev/hdaudio/hdaudio.c: revision 1.7
	sys/dev/hdaudio/hdaudio.c: revision 1.8
Always access CORBCTL using hda_read1/hda_write1 (it is an 8-bit wide reg).
Reported by Michal Necasek.
Always go through RIRB startup process, initialize RIRB interrupt count
register, and ack RIRBs as we process them in polling mode.
XXX pullup


(martin)
diff -r1.4.10.2 -r1.4.10.3 src/sys/dev/hdaudio/hdaudio.c

cvs diff -r1.4.10.2 -r1.4.10.3 src/sys/dev/hdaudio/hdaudio.c (expand / switch to unified diff)

--- src/sys/dev/hdaudio/hdaudio.c 2017/11/24 08:35:34 1.4.10.2
+++ src/sys/dev/hdaudio/hdaudio.c 2017/11/27 10:21:26 1.4.10.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: hdaudio.c,v 1.4.10.2 2017/11/24 08:35:34 martin Exp $ */ 1/* $NetBSD: hdaudio.c,v 1.4.10.3 2017/11/27 10:21:26 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk> 4 * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
5 * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca> 5 * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca>
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Precedence Technologies Ltd 9 * by Precedence Technologies Ltd
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.4.10.2 2017/11/24 08:35:34 martin Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.4.10.3 2017/11/27 10:21:26 martin Exp $");
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/device.h> 38#include <sys/device.h>
39#include <sys/conf.h> 39#include <sys/conf.h>
40#include <sys/bus.h> 40#include <sys/bus.h>
41#include <sys/kmem.h> 41#include <sys/kmem.h>
42#include <sys/module.h> 42#include <sys/module.h>
43 43
44#include "hdaudiovar.h" 44#include "hdaudiovar.h"
45#include "hdaudioreg.h" 45#include "hdaudioreg.h"
46#include "hdaudioio.h" 46#include "hdaudioio.h"
@@ -337,26 +337,29 @@ hdaudio_command(struct hdaudio_codec *co @@ -337,26 +337,29 @@ hdaudio_command(struct hdaudio_codec *co
337 337
338uint32_t 338uint32_t
339hdaudio_command_unlocked(struct hdaudio_codec *co, int nid, uint32_t control, 339hdaudio_command_unlocked(struct hdaudio_codec *co, int nid, uint32_t control,
340 uint32_t param) 340 uint32_t param)
341{ 341{
342 struct hdaudio_softc *sc = co->co_host; 342 struct hdaudio_softc *sc = co->co_host;
343 uint32_t result; 343 uint32_t result;
344 344
345 hda_trace(sc, "cmd : request %08X %08X (%02X)\n", 345 hda_trace(sc, "cmd : request %08X %08X (%02X)\n",
346 control, param, nid); 346 control, param, nid);
347 hdaudio_corb_enqueue(sc, co->co_addr, nid, control, param); 347 hdaudio_corb_enqueue(sc, co->co_addr, nid, control, param);
348 result = hdaudio_rirb_dequeue(sc, false); 348 result = hdaudio_rirb_dequeue(sc, false);
349 349
 350 /* Clear response interrupt status */
 351 hda_write1(sc, HDAUDIO_MMIO_RIRBSTS, hda_read1(sc, HDAUDIO_MMIO_RIRBSTS));
 352
350 return result; 353 return result;
351} 354}
352 355
353static int 356static int
354hdaudio_corb_setsize(struct hdaudio_softc *sc) 357hdaudio_corb_setsize(struct hdaudio_softc *sc)
355{ 358{
356 uint8_t corbsize; 359 uint8_t corbsize;
357 bus_size_t bufsize = 0; 360 bus_size_t bufsize = 0;
358 361
359 /* 362 /*
360 * The size of the CORB is programmable to 2, 16, or 256 entries 363 * The size of the CORB is programmable to 2, 16, or 256 entries
361 * by using the CORBSIZE register. Choose a size based on the 364 * by using the CORBSIZE register. Choose a size based on the
362 * controller capabilities, preferring a larger size when possible. 365 * controller capabilities, preferring a larger size when possible.
@@ -418,54 +421,54 @@ hdaudio_corb_config(struct hdaudio_softc @@ -418,54 +421,54 @@ hdaudio_corb_config(struct hdaudio_softc
418 return 0; 421 return 0;
419} 422}
420 423
421static int 424static int
422hdaudio_corb_stop(struct hdaudio_softc *sc) 425hdaudio_corb_stop(struct hdaudio_softc *sc)
423{ 426{
424 uint8_t corbctl; 427 uint8_t corbctl;
425 int retry = HDAUDIO_CORB_TIMEOUT; 428 int retry = HDAUDIO_CORB_TIMEOUT;
426 429
427 /* Stop the CORB if necessary */ 430 /* Stop the CORB if necessary */
428 corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL); 431 corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
429 if (corbctl & HDAUDIO_CORBCTL_RUN) { 432 if (corbctl & HDAUDIO_CORBCTL_RUN) {
430 corbctl &= ~HDAUDIO_CORBCTL_RUN; 433 corbctl &= ~HDAUDIO_CORBCTL_RUN;
431 hda_write4(sc, HDAUDIO_MMIO_CORBCTL, corbctl); 434 hda_write1(sc, HDAUDIO_MMIO_CORBCTL, corbctl);
432 do { 435 do {
433 hda_delay(10); 436 hda_delay(10);
434 corbctl = hda_read4(sc, HDAUDIO_MMIO_CORBCTL); 437 corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
435 } while (--retry > 0 && (corbctl & HDAUDIO_CORBCTL_RUN) != 0); 438 } while (--retry > 0 && (corbctl & HDAUDIO_CORBCTL_RUN) != 0);
436 if (retry == 0) { 439 if (retry == 0) {
437 hda_error(sc, "timeout stopping CORB\n"); 440 hda_error(sc, "timeout stopping CORB\n");
438 return ETIME; 441 return ETIME;
439 } 442 }
440 } 443 }
441 444
442 return 0; 445 return 0;
443} 446}
444 447
445static int 448static int
446hdaudio_corb_start(struct hdaudio_softc *sc) 449hdaudio_corb_start(struct hdaudio_softc *sc)
447{ 450{
448 uint8_t corbctl; 451 uint8_t corbctl;
449 int retry = HDAUDIO_CORB_TIMEOUT; 452 int retry = HDAUDIO_CORB_TIMEOUT;
450 453
451 /* Start the CORB if necessary */ 454 /* Start the CORB if necessary */
452 corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL); 455 corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
453 if ((corbctl & HDAUDIO_CORBCTL_RUN) == 0) { 456 if ((corbctl & HDAUDIO_CORBCTL_RUN) == 0) {
454 corbctl |= HDAUDIO_CORBCTL_RUN; 457 corbctl |= HDAUDIO_CORBCTL_RUN;
455 hda_write4(sc, HDAUDIO_MMIO_CORBCTL, corbctl); 458 hda_write1(sc, HDAUDIO_MMIO_CORBCTL, corbctl);
456 do { 459 do {
457 hda_delay(10); 460 hda_delay(10);
458 corbctl = hda_read4(sc, HDAUDIO_MMIO_CORBCTL); 461 corbctl = hda_read1(sc, HDAUDIO_MMIO_CORBCTL);
459 } while (--retry > 0 && (corbctl & HDAUDIO_CORBCTL_RUN) == 0); 462 } while (--retry > 0 && (corbctl & HDAUDIO_CORBCTL_RUN) == 0);
460 if (retry == 0) { 463 if (retry == 0) {
461 hda_error(sc, "timeout starting CORB\n"); 464 hda_error(sc, "timeout starting CORB\n");
462 return ETIME; 465 return ETIME;
463 } 466 }
464 } 467 }
465 468
466 return 0; 469 return 0;
467} 470}
468 471
469static int 472static int
470hdaudio_rirb_stop(struct hdaudio_softc *sc) 473hdaudio_rirb_stop(struct hdaudio_softc *sc)
471{ 474{
@@ -487,40 +490,41 @@ hdaudio_rirb_stop(struct hdaudio_softc * @@ -487,40 +490,41 @@ hdaudio_rirb_stop(struct hdaudio_softc *
487 return ETIME; 490 return ETIME;
488 } 491 }
489 } 492 }
490 493
491 return 0; 494 return 0;
492} 495}
493 496
494static int 497static int
495hdaudio_rirb_start(struct hdaudio_softc *sc) 498hdaudio_rirb_start(struct hdaudio_softc *sc)
496{ 499{
497 uint8_t rirbctl; 500 uint8_t rirbctl;
498 int retry = HDAUDIO_RIRB_TIMEOUT; 501 int retry = HDAUDIO_RIRB_TIMEOUT;
499 502
500 /* Start the RIRB if necessary */ 503 /* Set the RIRB interrupt count */
 504 hda_write2(sc, HDAUDIO_MMIO_RINTCNT, 1);
 505
 506 /* Start the RIRB */
501 rirbctl = hda_read1(sc, HDAUDIO_MMIO_RIRBCTL); 507 rirbctl = hda_read1(sc, HDAUDIO_MMIO_RIRBCTL);
502 if ((rirbctl & (HDAUDIO_RIRBCTL_RUN|HDAUDIO_RIRBCTL_INT_EN)) == 0) { 508 rirbctl |= HDAUDIO_RIRBCTL_RUN;
503 rirbctl |= HDAUDIO_RIRBCTL_RUN; 509 rirbctl |= HDAUDIO_RIRBCTL_INT_EN;
504 rirbctl |= HDAUDIO_RIRBCTL_INT_EN; 510 hda_write1(sc, HDAUDIO_MMIO_RIRBCTL, rirbctl);
505 hda_write1(sc, HDAUDIO_MMIO_RIRBCTL, rirbctl); 511 do {
506 do { 512 hda_delay(10);
507 hda_delay(10); 513 rirbctl = hda_read1(sc, HDAUDIO_MMIO_RIRBCTL);
508 rirbctl = hda_read1(sc, HDAUDIO_MMIO_RIRBCTL); 514 } while (--retry > 0 && (rirbctl & HDAUDIO_RIRBCTL_RUN) == 0);
509 } while (--retry > 0 && (rirbctl & HDAUDIO_RIRBCTL_RUN) == 0); 515 if (retry == 0) {
510 if (retry == 0) { 516 hda_error(sc, "timeout starting RIRB\n");
511 hda_error(sc, "timeout starting RIRB\n"); 517 return ETIME;
512 return ETIME; 
513 } 
514 } 518 }
515 519
516 return 0; 520 return 0;
517} 521}
518 522
519static int 523static int
520hdaudio_rirb_setsize(struct hdaudio_softc *sc) 524hdaudio_rirb_setsize(struct hdaudio_softc *sc)
521{ 525{
522 uint8_t rirbsize; 526 uint8_t rirbsize;
523 bus_size_t bufsize = 0; 527 bus_size_t bufsize = 0;
524 528
525 /* 529 /*
526 * The size of the RIRB is programmable to 2, 16, or 256 entries 530 * The size of the RIRB is programmable to 2, 16, or 256 entries
@@ -548,47 +552,36 @@ hdaudio_rirb_setsize(struct hdaudio_soft @@ -548,47 +552,36 @@ hdaudio_rirb_setsize(struct hdaudio_soft
548 (int)bufsize, rirbsize >> 4); 552 (int)bufsize, rirbsize >> 4);
549#endif 553#endif
550 554
551 sc->sc_rirb.dma_size = bufsize; 555 sc->sc_rirb.dma_size = bufsize;
552 sc->sc_rirb.dma_sizereg = rirbsize; 556 sc->sc_rirb.dma_sizereg = rirbsize;
553 557
554 return 0; 558 return 0;
555} 559}
556 560
557static int 561static int
558hdaudio_rirb_config(struct hdaudio_softc *sc) 562hdaudio_rirb_config(struct hdaudio_softc *sc)
559{ 563{
560 uint32_t rirbubase, rirblbase; 564 uint32_t rirbubase, rirblbase;
561 uint32_t rirbwp; 
562 int retry = HDAUDIO_RIRB_TIMEOUT; 
563 565
564 /* Program command buffer base address and size */ 566 /* Program command buffer base address and size */
565 rirblbase = (uint32_t)DMA_DMAADDR(&sc->sc_rirb); 567 rirblbase = (uint32_t)DMA_DMAADDR(&sc->sc_rirb);
566 rirbubase = (uint32_t)(((uint64_t)DMA_DMAADDR(&sc->sc_rirb)) >> 32); 568 rirbubase = (uint32_t)(((uint64_t)DMA_DMAADDR(&sc->sc_rirb)) >> 32);
567 hda_write4(sc, HDAUDIO_MMIO_RIRBLBASE, rirblbase); 569 hda_write4(sc, HDAUDIO_MMIO_RIRBLBASE, rirblbase);
568 hda_write4(sc, HDAUDIO_MMIO_RIRBUBASE, rirbubase); 570 hda_write4(sc, HDAUDIO_MMIO_RIRBUBASE, rirbubase);
569 hda_write1(sc, HDAUDIO_MMIO_RIRBSIZE, sc->sc_rirb.dma_sizereg); 571 hda_write1(sc, HDAUDIO_MMIO_RIRBSIZE, sc->sc_rirb.dma_sizereg);
570 572
571 /* Clear the write pointer */ 573 /* Clear the write pointer */
572 hda_write2(sc, HDAUDIO_MMIO_RIRBWP, HDAUDIO_RIRBWP_WP_RESET); 574 hda_write2(sc, HDAUDIO_MMIO_RIRBWP, HDAUDIO_RIRBWP_WP_RESET);
573 hda_write2(sc, HDAUDIO_MMIO_RIRBWP, 0); 
574 do { 
575 hda_delay(10); 
576 rirbwp = hda_read2(sc, HDAUDIO_MMIO_RIRBWP); 
577 } while (--retry > 0 && (rirbwp & HDAUDIO_RIRBWP_WP_RESET) != 0); 
578 if (retry == 0) { 
579 hda_error(sc, "timeout resetting RIRB\n"); 
580 return ETIME; 
581 } 
582 sc->sc_rirbrp = 0; 575 sc->sc_rirbrp = 0;
583 576
584 return 0; 577 return 0;
585} 578}
586 579
587static int 580static int
588hdaudio_reset(struct hdaudio_softc *sc) 581hdaudio_reset(struct hdaudio_softc *sc)
589{ 582{
590 int retry = HDAUDIO_RESET_TIMEOUT; 583 int retry = HDAUDIO_RESET_TIMEOUT;
591 uint32_t gctl; 584 uint32_t gctl;
592 int err; 585 int err;
593 586
594 if ((err = hdaudio_rirb_stop(sc)) != 0) { 587 if ((err = hdaudio_rirb_stop(sc)) != 0) {