AC97.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * Copyright (c) 2021-2022, Jelle Raaijmakers <jelle@gmta.nl>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Format.h>
  7. #include <Kernel/Arch/Delay.h>
  8. #include <Kernel/Devices/Audio/AC97.h>
  9. #include <Kernel/Devices/DeviceManagement.h>
  10. #include <Kernel/InterruptDisabler.h>
  11. #include <Kernel/Memory/AnonymousVMObject.h>
  12. namespace Kernel {
  13. static constexpr int buffer_descriptor_list_max_entries = 32;
  14. static constexpr u16 pcm_default_sample_rate = 44100;
  15. static constexpr u16 pcm_fixed_sample_rate = 48000;
  16. // Valid output range - with double-rate enabled, sample rate can go up to 96kHZ
  17. static constexpr u16 pcm_sample_rate_minimum = 8000;
  18. static constexpr u16 pcm_sample_rate_maximum = 48000;
  19. UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<AC97>> AC97::try_create(PCI::DeviceIdentifier const& pci_device_identifier)
  20. {
  21. auto mixer_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0));
  22. auto bus_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR1));
  23. auto pcm_out_channel_io_window = TRY(bus_io_window->create_from_io_window_with_offset(NativeAudioBusChannel::PCMOutChannel));
  24. auto pcm_out_channel = TRY(AC97Channel::create_with_parent_pci_device(pci_device_identifier.address(), "PCMOut"sv, move(pcm_out_channel_io_window)));
  25. auto ac97 = adopt_nonnull_lock_ref_or_enomem(new (nothrow) AC97(pci_device_identifier, move(pcm_out_channel), move(mixer_io_window), move(bus_io_window)));
  26. if (!ac97.is_error())
  27. TRY(ac97.value()->initialize());
  28. return ac97;
  29. }
  30. UNMAP_AFTER_INIT AC97::AC97(PCI::DeviceIdentifier const& pci_device_identifier, NonnullOwnPtr<AC97Channel> pcm_out_channel, NonnullOwnPtr<IOWindow> mixer_io_window, NonnullOwnPtr<IOWindow> bus_io_window)
  31. : PCI::Device(const_cast<PCI::DeviceIdentifier&>(pci_device_identifier))
  32. , IRQHandler(pci_device_identifier.interrupt_line().value())
  33. , m_mixer_io_window(move(mixer_io_window))
  34. , m_bus_io_window(move(bus_io_window))
  35. , m_pcm_out_channel(move(pcm_out_channel))
  36. {
  37. }
  38. UNMAP_AFTER_INIT AC97::~AC97() = default;
  39. bool AC97::handle_irq(RegisterState const&)
  40. {
  41. auto pcm_out_status = m_pcm_out_channel->io_window().read16(AC97Channel::Register::Status);
  42. dbgln_if(AC97_DEBUG, "AC97 @ {}: interrupt received - status: {:#05b}", device_identifier().address(), pcm_out_status);
  43. bool is_dma_halted = (pcm_out_status & AudioStatusRegisterFlag::DMAControllerHalted) > 0;
  44. bool current_equals_last_valid = (pcm_out_status & AudioStatusRegisterFlag::CurrentEqualsLastValid) > 0;
  45. bool is_completion_interrupt = (pcm_out_status & AudioStatusRegisterFlag::BufferCompletionInterruptStatus) > 0;
  46. bool is_fifo_error = (pcm_out_status & AudioStatusRegisterFlag::FIFOError) > 0;
  47. VERIFY(!is_fifo_error);
  48. // If there is no buffer completion, we're not going to do anything
  49. if (!is_completion_interrupt)
  50. return false;
  51. // On interrupt, we need to reset PCM interrupt flags by setting their bits
  52. pcm_out_status = AudioStatusRegisterFlag::LastValidBufferCompletionInterrupt
  53. | AudioStatusRegisterFlag::BufferCompletionInterruptStatus
  54. | AudioStatusRegisterFlag::FIFOError;
  55. m_pcm_out_channel->io_window().write16(AC97Channel::Register::Status, pcm_out_status);
  56. if (is_dma_halted) {
  57. VERIFY(current_equals_last_valid);
  58. m_pcm_out_channel->handle_dma_stopped();
  59. }
  60. if (!m_irq_queue.is_empty())
  61. m_irq_queue.wake_all();
  62. return true;
  63. }
  64. UNMAP_AFTER_INIT ErrorOr<void> AC97::initialize()
  65. {
  66. dbgln_if(AC97_DEBUG, "AC97 @ {}: mixer base: {:#04x}", device_identifier().address(), m_mixer_io_window);
  67. dbgln_if(AC97_DEBUG, "AC97 @ {}: bus base: {:#04x}", device_identifier().address(), m_bus_io_window);
  68. // Read out AC'97 codec revision and vendor
  69. auto extended_audio_id = m_mixer_io_window->read16(NativeAudioMixerRegister::ExtendedAudioID);
  70. m_codec_revision = static_cast<AC97Revision>(((extended_audio_id & ExtendedAudioMask::Revision) >> 10) & 0b11);
  71. dbgln_if(AC97_DEBUG, "AC97 @ {}: codec revision {:#02b}", device_identifier().address(), to_underlying(m_codec_revision));
  72. if (m_codec_revision == AC97Revision::Reserved)
  73. return ENOTSUP;
  74. // Report vendor / device ID
  75. u32 vendor_id = m_mixer_io_window->read16(NativeAudioMixerRegister::VendorID1) << 16 | m_mixer_io_window->read16(NativeAudioMixerRegister::VendorID2);
  76. dmesgln_pci(*this, "Vendor ID: {:#8x}", vendor_id);
  77. // Bus cold reset, enable interrupts
  78. enable_pin_based_interrupts();
  79. PCI::enable_bus_mastering(device_identifier());
  80. auto control = m_bus_io_window->read32(NativeAudioBusRegister::GlobalControl);
  81. control |= GlobalControlFlag::GPIInterruptEnable;
  82. control |= GlobalControlFlag::AC97ColdReset;
  83. m_bus_io_window->write32(NativeAudioBusRegister::GlobalControl, control);
  84. // Reset mixer
  85. m_mixer_io_window->write16(NativeAudioMixerRegister::Reset, 1);
  86. // Enable variable and double rate PCM audio if supported
  87. auto extended_audio_status = m_mixer_io_window->read16(NativeAudioMixerRegister::ExtendedAudioStatusControl);
  88. if ((extended_audio_id & ExtendedAudioMask::VariableRatePCMAudio) > 0) {
  89. extended_audio_status |= ExtendedAudioStatusControlFlag::VariableRateAudio;
  90. m_variable_rate_pcm_supported = true;
  91. }
  92. if (!m_variable_rate_pcm_supported) {
  93. extended_audio_status &= ~ExtendedAudioStatusControlFlag::DoubleRateAudio;
  94. } else if ((extended_audio_id & ExtendedAudioMask::DoubleRatePCMAudio) > 0) {
  95. extended_audio_status |= ExtendedAudioStatusControlFlag::DoubleRateAudio;
  96. m_double_rate_pcm_enabled = true;
  97. }
  98. m_mixer_io_window->write16(NativeAudioMixerRegister::ExtendedAudioStatusControl, extended_audio_status);
  99. TRY(set_pcm_output_sample_rate(m_variable_rate_pcm_supported ? pcm_default_sample_rate : pcm_fixed_sample_rate));
  100. // Left and right volume of 0 means attenuation of 0 dB
  101. set_master_output_volume(0, 0, Muted::No);
  102. set_pcm_output_volume(0, 0, Muted::No);
  103. m_pcm_out_channel->reset();
  104. enable_irq();
  105. return {};
  106. }
  107. void AC97::set_master_output_volume(u8 left_channel, u8 right_channel, Muted mute)
  108. {
  109. u16 volume_value = ((right_channel & 63) << 0)
  110. | ((left_channel & 63) << 8)
  111. | ((mute == Muted::Yes ? 1 : 0) << 15);
  112. m_mixer_io_window->write16(NativeAudioMixerRegister::SetMasterOutputVolume, volume_value);
  113. }
  114. ErrorOr<void> AC97::set_pcm_output_sample_rate(u32 sample_rate)
  115. {
  116. if (m_sample_rate == sample_rate)
  117. return {};
  118. auto const double_rate_shift = m_double_rate_pcm_enabled ? 1 : 0;
  119. auto shifted_sample_rate = sample_rate >> double_rate_shift;
  120. if (!m_variable_rate_pcm_supported && shifted_sample_rate != pcm_fixed_sample_rate)
  121. return ENOTSUP;
  122. if (shifted_sample_rate < pcm_sample_rate_minimum || shifted_sample_rate > pcm_sample_rate_maximum)
  123. return ENOTSUP;
  124. m_mixer_io_window->write16(NativeAudioMixerRegister::PCMFrontDACRate, shifted_sample_rate);
  125. m_sample_rate = static_cast<u32>(m_mixer_io_window->read16(NativeAudioMixerRegister::PCMFrontDACRate)) << double_rate_shift;
  126. dmesgln_pci(*this, "PCM front DAC rate set to {} Hz", m_sample_rate);
  127. // Setting the sample rate stops a running DMA engine, so restart it
  128. if (m_pcm_out_channel->dma_running())
  129. m_pcm_out_channel->start_dma();
  130. return {};
  131. }
  132. void AC97::set_pcm_output_volume(u8 left_channel, u8 right_channel, Muted mute)
  133. {
  134. u16 volume_value = ((right_channel & 31) << 0)
  135. | ((left_channel & 31) << 8)
  136. | ((mute == Muted::Yes ? 1 : 0) << 15);
  137. m_mixer_io_window->write16(NativeAudioMixerRegister::SetPCMOutputVolume, volume_value);
  138. }
  139. LockRefPtr<AudioChannel> AC97::audio_channel(u32 index) const
  140. {
  141. if (index == 0)
  142. return m_audio_channel;
  143. return {};
  144. }
  145. void AC97::detect_hardware_audio_channels(Badge<AudioManagement>)
  146. {
  147. m_audio_channel = AudioChannel::must_create(*this, 0);
  148. }
  149. ErrorOr<void> AC97::set_pcm_output_sample_rate(size_t channel_index, u32 samples_per_second_rate)
  150. {
  151. if (channel_index != 0)
  152. return ENODEV;
  153. TRY(set_pcm_output_sample_rate(samples_per_second_rate));
  154. return {};
  155. }
  156. ErrorOr<u32> AC97::get_pcm_output_sample_rate(size_t channel_index)
  157. {
  158. if (channel_index != 0)
  159. return Error::from_errno(ENODEV);
  160. return m_sample_rate;
  161. }
  162. ErrorOr<size_t> AC97::write(size_t channel_index, UserOrKernelBuffer const& data, size_t length)
  163. {
  164. if (channel_index != 0)
  165. return Error::from_errno(ENODEV);
  166. if (!m_output_buffer)
  167. m_output_buffer = TRY(MM.allocate_dma_buffer_pages(m_output_buffer_page_count * PAGE_SIZE, "AC97 Output buffer"sv, Memory::Region::Access::Write));
  168. if (!m_buffer_descriptor_list) {
  169. size_t buffer_descriptor_list_size = buffer_descriptor_list_max_entries * sizeof(BufferDescriptorListEntry);
  170. buffer_descriptor_list_size = TRY(Memory::page_round_up(buffer_descriptor_list_size));
  171. m_buffer_descriptor_list = TRY(MM.allocate_dma_buffer_pages(buffer_descriptor_list_size, "AC97 Buffer Descriptor List"sv, Memory::Region::Access::Write));
  172. }
  173. Checked<size_t> remaining = length;
  174. size_t offset = 0;
  175. while (remaining > static_cast<size_t>(0)) {
  176. TRY(write_single_buffer(data, offset, min(remaining.value(), PAGE_SIZE)));
  177. offset += PAGE_SIZE;
  178. remaining.saturating_sub(PAGE_SIZE);
  179. }
  180. return length;
  181. }
  182. ErrorOr<void> AC97::write_single_buffer(UserOrKernelBuffer const& data, size_t offset, size_t length)
  183. {
  184. VERIFY(length <= PAGE_SIZE);
  185. {
  186. // Block until we can write into an unused buffer
  187. InterruptDisabler disabler;
  188. do {
  189. auto pcm_out_status = m_pcm_out_channel->io_window().read16(AC97Channel::Register::Status);
  190. auto current_index = m_pcm_out_channel->io_window().read8(AC97Channel::Register::CurrentIndexValue);
  191. int last_valid_index = m_pcm_out_channel->io_window().read8(AC97Channel::Register::LastValidIndex);
  192. auto head_distance = last_valid_index - current_index;
  193. if (head_distance < 0)
  194. head_distance += buffer_descriptor_list_max_entries;
  195. if (m_pcm_out_channel->dma_running())
  196. ++head_distance;
  197. // Current index has _passed_ last valid index - move our list index up
  198. if (head_distance > m_output_buffer_page_count) {
  199. m_buffer_descriptor_list_index = current_index + 1;
  200. break;
  201. }
  202. // There is room for our data
  203. if (head_distance < m_output_buffer_page_count)
  204. break;
  205. dbgln_if(AC97_DEBUG, "AC97 @ {}: waiting on interrupt - status: {:#05b} CI: {} LVI: {}", device_identifier().address(), pcm_out_status, current_index, last_valid_index);
  206. m_irq_queue.wait_forever("AC97"sv);
  207. } while (m_pcm_out_channel->dma_running());
  208. }
  209. // Copy data from userspace into one of our buffers
  210. TRY(data.read(m_output_buffer->vaddr_from_page_index(m_output_buffer_page_index).as_ptr(), offset, length));
  211. // Write the next entry to the buffer descriptor list
  212. u16 number_of_samples = length / sizeof(u16);
  213. auto list_entries = reinterpret_cast<BufferDescriptorListEntry*>(m_buffer_descriptor_list->vaddr().get());
  214. auto list_entry = &list_entries[m_buffer_descriptor_list_index];
  215. list_entry->buffer_pointer = static_cast<u32>(m_output_buffer->physical_page(m_output_buffer_page_index)->paddr().get());
  216. list_entry->control_and_length = number_of_samples | BufferDescriptorListEntryFlags::InterruptOnCompletion;
  217. auto buffer_address = static_cast<u32>(m_buffer_descriptor_list->physical_page(0)->paddr().get());
  218. m_pcm_out_channel->set_last_valid_index(buffer_address, m_buffer_descriptor_list_index);
  219. if (!m_pcm_out_channel->dma_running())
  220. m_pcm_out_channel->start_dma();
  221. m_output_buffer_page_index = (m_output_buffer_page_index + 1) % m_output_buffer_page_count;
  222. m_buffer_descriptor_list_index = (m_buffer_descriptor_list_index + 1) % buffer_descriptor_list_max_entries;
  223. return {};
  224. }
  225. ErrorOr<NonnullOwnPtr<AC97::AC97Channel>> AC97::AC97Channel::create_with_parent_pci_device(PCI::Address pci_device_address, StringView name, NonnullOwnPtr<IOWindow> channel_io_base)
  226. {
  227. return adopt_nonnull_own_or_enomem(new (nothrow) AC97::AC97Channel(pci_device_address, name, move(channel_io_base)));
  228. }
  229. void AC97::AC97Channel::handle_dma_stopped()
  230. {
  231. dbgln_if(AC97_DEBUG, "AC97 @ {}: channel {}: DMA engine has stopped", m_device_pci_address, name());
  232. m_dma_running.with([this](auto& dma_running) {
  233. // NOTE: QEMU might send spurious interrupts while we're not running, so we don't want to panic here.
  234. if (!dma_running)
  235. dbgln("AC97 @ {}: received DMA interrupt while it wasn't running", m_device_pci_address);
  236. dma_running = false;
  237. });
  238. }
  239. void AC97::AC97Channel::reset()
  240. {
  241. dbgln_if(AC97_DEBUG, "AC97 @ {}: channel {}: resetting", m_device_pci_address, name());
  242. m_channel_io_window->write8(Register::Control, AudioControlRegisterFlag::ResetRegisters);
  243. while ((m_channel_io_window->read8(Register::Control) & AudioControlRegisterFlag::ResetRegisters) > 0)
  244. microseconds_delay(50);
  245. m_dma_running.with([](auto& dma_running) {
  246. dma_running = false;
  247. });
  248. }
  249. void AC97::AC97Channel::set_last_valid_index(u32 buffer_address, u8 last_valid_index)
  250. {
  251. dbgln_if(AC97_DEBUG, "AC97 @ {}: channel {}: setting buffer address: {:#x} LVI: {}", m_device_pci_address, name(), buffer_address, last_valid_index);
  252. m_channel_io_window->write32(Register::BufferDescriptorListBaseAddress, buffer_address);
  253. m_channel_io_window->write8(Register::LastValidIndex, last_valid_index);
  254. }
  255. void AC97::AC97Channel::start_dma()
  256. {
  257. dbgln_if(AC97_DEBUG, "AC97 @ {}: channel {}: starting DMA engine", m_device_pci_address, name());
  258. auto control = m_channel_io_window->read8(Register::Control);
  259. control |= AudioControlRegisterFlag::RunPauseBusMaster;
  260. control |= AudioControlRegisterFlag::FIFOErrorInterruptEnable;
  261. control |= AudioControlRegisterFlag::InterruptOnCompletionEnable;
  262. m_channel_io_window->write8(Register::Control, control);
  263. m_dma_running.with([](auto& dma_running) {
  264. dma_running = true;
  265. });
  266. }
  267. }