hda: wait between set and unset of the GLOBAL_CONTROL_RESET bit.
* the spec requires 521us, 1000us is generally used. * also only uninit streams, corb and rirb when a codec reset is in progress (seen in zircon). linux instead clears HDAC_STATE_STATUS.
This commit is contained in:
parent
3131c13005
commit
10baa577a9
@ -356,6 +356,10 @@ hda_interrupt_handler(hda_controller* controller)
|
||||
static status_t
|
||||
reset_controller(hda_controller* controller)
|
||||
{
|
||||
uint32 control = controller->Read32(HDAC_GLOBAL_CONTROL);
|
||||
if ((control & GLOBAL_CONTROL_RESET) != 0) {
|
||||
controller->Write32(HDAC_INTR_CONTROL, 0);
|
||||
|
||||
// stop streams
|
||||
|
||||
for (uint32 i = 0; i < controller->num_input_streams; i++) {
|
||||
@ -400,9 +404,10 @@ reset_controller(hda_controller* controller)
|
||||
controller->Write32(HDAC_DMA_POSITION_BASE_LOWER, 0);
|
||||
controller->Write32(HDAC_DMA_POSITION_BASE_UPPER, 0);
|
||||
|
||||
// Set reset bit - it must be asserted for at least 100us
|
||||
control = controller->Read32(HDAC_GLOBAL_CONTROL);
|
||||
}
|
||||
|
||||
uint32 control = controller->Read32(HDAC_GLOBAL_CONTROL);
|
||||
// Set reset bit - it must be asserted for at least 100us
|
||||
controller->Write32(HDAC_GLOBAL_CONTROL, control & ~GLOBAL_CONTROL_RESET);
|
||||
|
||||
for (int timeout = 0; timeout < 10; timeout++) {
|
||||
@ -417,6 +422,9 @@ reset_controller(hda_controller* controller)
|
||||
return B_BUSY;
|
||||
}
|
||||
|
||||
// Wait for codec PLL to lock at least 100us, section 5.5.1.2
|
||||
snooze(1000);
|
||||
|
||||
// Unset reset bit
|
||||
|
||||
control = controller->Read32(HDAC_GLOBAL_CONTROL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user