* No longer enable interrupts for all possible streams - they are now enabled
on a per-stream basis in hda_stream_start(). * Also, don't turn on interrupt generation in the stream before starting the stream. * Create space for the DMA position update and set it in the controller, not yet tested. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24144 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -195,6 +195,7 @@ struct hda_controller {
|
|||||||
area_id rb_area;
|
area_id rb_area;
|
||||||
corb_t* corb;
|
corb_t* corb;
|
||||||
rirb_t* rirb;
|
rirb_t* rirb;
|
||||||
|
uint32* stream_positions;
|
||||||
|
|
||||||
hda_codec* codecs[HDA_MAX_CODECS];
|
hda_codec* codecs[HDA_MAX_CODECS];
|
||||||
hda_codec* active_codec;
|
hda_codec* active_codec;
|
||||||
|
|||||||
@@ -99,10 +99,14 @@ hda_stream_start(hda_controller* controller, hda_stream* stream)
|
|||||||
if (stream->buffer_ready_sem < B_OK)
|
if (stream->buffer_ready_sem < B_OK)
|
||||||
return stream->buffer_ready_sem;
|
return stream->buffer_ready_sem;
|
||||||
|
|
||||||
OREG8(controller, stream->off, CTL0) |= CTL0_RUN;
|
REG32(controller, INTCTL) |= 1 << (stream->off / HDAC_SDSIZE);
|
||||||
|
OREG8(controller, stream->off, CTL0) |= CTL0_IOCE | CTL0_FEIE | CTL0_DEIE
|
||||||
|
| CTL0_RUN;
|
||||||
|
|
||||||
|
#if 0
|
||||||
while (!(OREG8(controller, stream->off, CTL0) & CTL0_RUN))
|
while (!(OREG8(controller, stream->off, CTL0) & CTL0_RUN))
|
||||||
snooze(1);
|
snooze(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
stream->running = true;
|
stream->running = true;
|
||||||
|
|
||||||
@@ -145,10 +149,14 @@ hda_stream_check_intr(hda_controller* controller, hda_stream* stream)
|
|||||||
status_t
|
status_t
|
||||||
hda_stream_stop(hda_controller* controller, hda_stream* stream)
|
hda_stream_stop(hda_controller* controller, hda_stream* stream)
|
||||||
{
|
{
|
||||||
OREG8(controller, stream->off, CTL0) &= ~CTL0_RUN;
|
OREG8(controller, stream->off, CTL0) &= ~(CTL0_IOCE | CTL0_FEIE | CTL0_DEIE
|
||||||
|
| CTL0_RUN);
|
||||||
|
REG32(controller, INTCTL) &= ~(1 << (stream->off / HDAC_SDSIZE));
|
||||||
|
|
||||||
|
#if 0
|
||||||
while ((OREG8(controller, stream->off, CTL0) & CTL0_RUN) != 0)
|
while ((OREG8(controller, stream->off, CTL0) & CTL0_RUN) != 0)
|
||||||
snooze(1);
|
snooze(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
stream->running = false;
|
stream->running = false;
|
||||||
delete_sem(stream->buffer_ready_sem);
|
delete_sem(stream->buffer_ready_sem);
|
||||||
@@ -287,10 +295,11 @@ dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld *************
|
|||||||
OREG32(audioGroup->codec->controller, stream->off, CBL)
|
OREG32(audioGroup->codec->controller, stream->off, CBL)
|
||||||
= stream->sample_size * stream->num_channels * stream->num_buffers
|
= stream->sample_size * stream->num_channels * stream->num_buffers
|
||||||
* stream->buffer_length;
|
* stream->buffer_length;
|
||||||
OREG8(audioGroup->codec->controller, stream->off, CTL0)
|
|
||||||
= CTL0_IOCE | CTL0_FEIE | CTL0_DEIE;
|
|
||||||
OREG8(audioGroup->codec->controller, stream->off, CTL2) = stream->id << 4;
|
OREG8(audioGroup->codec->controller, stream->off, CTL2) = stream->id << 4;
|
||||||
|
|
||||||
|
REG32(audioGroup->codec->controller, DMA_POSITION_BASE_LOWER)
|
||||||
|
|= DMA_POSITION_ENABLED;
|
||||||
|
|
||||||
verb[0] = MAKE_VERB(audioGroup->codec->addr, stream->io_widget,
|
verb[0] = MAKE_VERB(audioGroup->codec->addr, stream->io_widget,
|
||||||
VID_SET_CONVERTER_FORMAT, format);
|
VID_SET_CONVERTER_FORMAT, format);
|
||||||
verb[1] = MAKE_VERB(audioGroup->codec->addr, stream->io_widget,
|
verb[1] = MAKE_VERB(audioGroup->codec->addr, stream->io_widget,
|
||||||
@@ -429,10 +438,10 @@ hda_hw_start(hda_controller* controller)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
hda_hw_corb_rirb_init(hda_controller* controller)
|
hda_hw_corb_rirb_pos_init(hda_controller* controller)
|
||||||
{
|
{
|
||||||
uint32 memSize, rirbOffset;
|
uint32 memSize, rirbOffset, posOffset;
|
||||||
uint8 corbSize, rirbSize;
|
uint8 corbSize, rirbSize, posSize;
|
||||||
status_t rc = B_OK;
|
status_t rc = B_OK;
|
||||||
physical_entry pe;
|
physical_entry pe;
|
||||||
|
|
||||||
@@ -464,12 +473,17 @@ hda_hw_corb_rirb_init(hda_controller* controller)
|
|||||||
|
|
||||||
/* Determine rirb offset in memory and total size of corb+alignment+rirb */
|
/* Determine rirb offset in memory and total size of corb+alignment+rirb */
|
||||||
rirbOffset = (controller->corb_length * sizeof(corb_t) + 0x7f) & ~0x7f;
|
rirbOffset = (controller->corb_length * sizeof(corb_t) + 0x7f) & ~0x7f;
|
||||||
memSize = (rirbOffset + controller->rirb_length * sizeof(rirb_t)
|
posOffset = (rirbOffset + controller->rirb_length * sizeof(rirb_t) + 0x7f)
|
||||||
+ B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
& 0x7f;
|
||||||
|
posSize = 8 * (controller->num_input_streams
|
||||||
|
+ controller->num_output_streams + controller->num_bidir_streams);
|
||||||
|
|
||||||
|
memSize = (posOffset + posSize + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||||
|
|
||||||
/* Allocate memory area */
|
/* Allocate memory area */
|
||||||
controller->rb_area = create_area("hda_corb_rirb", (void**)&controller->corb,
|
controller->rb_area = create_area("hda corb/rirb/pos",
|
||||||
B_ANY_KERNEL_ADDRESS, memSize, B_CONTIGUOUS, 0);
|
(void**)&controller->corb, B_ANY_KERNEL_ADDRESS, memSize,
|
||||||
|
B_CONTIGUOUS, 0);
|
||||||
if (controller->rb_area < 0)
|
if (controller->rb_area < 0)
|
||||||
return controller->rb_area;
|
return controller->rb_area;
|
||||||
|
|
||||||
@@ -483,7 +497,16 @@ hda_hw_corb_rirb_init(hda_controller* controller)
|
|||||||
|
|
||||||
/* Program CORB/RIRB for these locations */
|
/* Program CORB/RIRB for these locations */
|
||||||
REG32(controller, CORBLBASE) = (uint32)pe.address;
|
REG32(controller, CORBLBASE) = (uint32)pe.address;
|
||||||
|
REG32(controller, CORBUBASE) = 0;
|
||||||
REG32(controller, RIRBLBASE) = (uint32)pe.address + rirbOffset;
|
REG32(controller, RIRBLBASE) = (uint32)pe.address + rirbOffset;
|
||||||
|
REG32(controller, RIRBUBASE) = 0;
|
||||||
|
|
||||||
|
/* Program DMA position update */
|
||||||
|
REG32(controller, DMA_POSITION_BASE_LOWER) = (uint32)pe.address + posOffset;
|
||||||
|
REG32(controller, DMA_POSITION_BASE_UPPER) = 0;
|
||||||
|
|
||||||
|
controller->stream_positions = (uint32*)
|
||||||
|
((uint8*)controller->corb + posOffset);
|
||||||
|
|
||||||
/* Reset CORB read pointer */
|
/* Reset CORB read pointer */
|
||||||
/* NOTE: See HDA011 for corrected procedure! */
|
/* NOTE: See HDA011 for corrected procedure! */
|
||||||
@@ -556,15 +579,15 @@ hda_hw_init(hda_controller* controller)
|
|||||||
if (rc != B_OK)
|
if (rc != B_OK)
|
||||||
goto reset_failed;
|
goto reset_failed;
|
||||||
|
|
||||||
/* Setup CORB/RIRB */
|
/* Setup CORB/RIRB/DMA POS */
|
||||||
rc = hda_hw_corb_rirb_init(controller);
|
rc = hda_hw_corb_rirb_pos_init(controller);
|
||||||
if (rc != B_OK)
|
if (rc != B_OK)
|
||||||
goto corb_rirb_failed;
|
goto corb_rirb_failed;
|
||||||
|
|
||||||
REG16(controller, WAKEEN) = 0x7fff;
|
REG16(controller, WAKEEN) = 0x7fff;
|
||||||
|
|
||||||
/* Enable controller interrupts */
|
/* Enable controller interrupts */
|
||||||
REG32(controller, INTCTL) = INTCTL_GIE | INTCTL_CIE | 0xffff;
|
REG32(controller, INTCTL) = INTCTL_GIE | INTCTL_CIE;
|
||||||
|
|
||||||
/* Wait for codecs to warm up */
|
/* Wait for codecs to warm up */
|
||||||
snooze(1000);
|
snooze(1000);
|
||||||
@@ -641,6 +664,10 @@ hda_hw_uninit(hda_controller* controller)
|
|||||||
REG8(controller, CORBCTL) = 0;
|
REG8(controller, CORBCTL) = 0;
|
||||||
REG8(controller, RIRBCTL) = 0;
|
REG8(controller, RIRBCTL) = 0;
|
||||||
|
|
||||||
|
REG32(controller, CORBLBASE) = 0;
|
||||||
|
REG32(controller, RIRBLBASE) = 0;
|
||||||
|
REG32(controller, DMA_POSITION_BASE_LOWER) = 0;
|
||||||
|
|
||||||
/* Disable interrupts and remove interrupt handler */
|
/* Disable interrupts and remove interrupt handler */
|
||||||
REG32(controller, INTCTL) = 0;
|
REG32(controller, INTCTL) = 0;
|
||||||
REG32(controller, GCTL) &= ~GCTL_CRST;
|
REG32(controller, GCTL) &= ~GCTL_CRST;
|
||||||
|
|||||||
@@ -96,6 +96,10 @@
|
|||||||
#define RIRBSIZE_SZ_16E (1 << 0)
|
#define RIRBSIZE_SZ_16E (1 << 0)
|
||||||
#define RIRBSIZE_SZ_256E (1 << 1)
|
#define RIRBSIZE_SZ_256E (1 << 1)
|
||||||
|
|
||||||
|
#define HDAC_DMA_POSITION_BASE_LOWER 0x70 /* 32bits */
|
||||||
|
#define HDAC_DMA_POSITION_BASE_UPPER 0x74 /* 32bits */
|
||||||
|
#define DMA_POSITION_ENABLED 1
|
||||||
|
|
||||||
#define HDAC_SDBASE 0x80
|
#define HDAC_SDBASE 0x80
|
||||||
#define HDAC_SDSIZE 0x20
|
#define HDAC_SDSIZE 0x20
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user