Stream.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * Copyright (c) 2023, Jelle Raaijmakers <jelle@gmta.nl>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Stream.h"
  7. #include <AK/Optional.h>
  8. #include <Kernel/Devices/Audio/IntelHDA/Controller.h>
  9. #include <Kernel/Devices/Audio/IntelHDA/Format.h>
  10. #include <Kernel/Devices/Audio/IntelHDA/Timing.h>
  11. #include <Kernel/Memory/MemoryManager.h>
  12. namespace Kernel::Audio::IntelHDA {
  13. Stream::~Stream()
  14. {
  15. if (m_running)
  16. MUST(stop());
  17. }
  18. u32 Stream::read_control()
  19. {
  20. // 3.3.35: Input/Output/Bidirectional Stream Descriptor Control
  21. u32 control_and_status = m_stream_io_window->read32(StreamRegisterOffset::Control);
  22. return control_and_status & 0xffffffu;
  23. }
  24. void Stream::write_control(u32 control)
  25. {
  26. // 3.3.35: Input/Output/Bidirectional Stream Descriptor Control
  27. auto status = m_stream_io_window->read8(StreamRegisterOffset::Status);
  28. u32 control_and_status = (status << 24)
  29. | ((m_stream_number & 0xf) << 20)
  30. | (control & 0xfffffu);
  31. m_stream_io_window->write32(StreamRegisterOffset::Control, control_and_status);
  32. }
  33. static constexpr u8 container_size_in_bytes(u8 bit_size)
  34. {
  35. // 4.5.1: Stream Data In Memory
  36. if (bit_size > 16)
  37. return 4;
  38. else if (bit_size > 8)
  39. return 2;
  40. return 1;
  41. }
  42. ErrorOr<void> Stream::initialize_buffer()
  43. {
  44. VERIFY(m_format_parameters.sample_rate > 0);
  45. VERIFY(m_format_parameters.pcm_bits > 0);
  46. VERIFY(m_format_parameters.number_of_channels > 0);
  47. // 4.5.1: Stream Data In Memory
  48. // NOTE: we ignore the number of blocks per packet since we are only required to have an integer number
  49. // of samples per buffer, and we always have at least one packet per buffer.
  50. size_t block_size_in_bytes = container_size_in_bytes(m_format_parameters.pcm_bits) * m_format_parameters.number_of_channels;
  51. size_t number_of_blocks_in_buffer = PAGE_SIZE / block_size_in_bytes;
  52. VERIFY(number_of_blocks_in_buffer > 0);
  53. size_t number_of_blocks_required_for_cyclic_buffer_size = ceil_div(cyclic_buffer_size_in_ms * m_format_parameters.sample_rate, 1'000);
  54. size_t number_of_buffers_required_for_cyclic_buffer_size = AK::max(ceil_div(number_of_blocks_required_for_cyclic_buffer_size, number_of_blocks_in_buffer), minimum_number_of_buffers);
  55. VERIFY(number_of_buffers_required_for_cyclic_buffer_size > 0 && number_of_buffers_required_for_cyclic_buffer_size <= 256);
  56. size_t cyclic_buffer_size_in_bytes = number_of_buffers_required_for_cyclic_buffer_size * PAGE_SIZE;
  57. TRY(m_buffers.with([&](auto& buffers) -> ErrorOr<void> {
  58. buffers = TRY(MM.allocate_dma_buffer_pages(cyclic_buffer_size_in_bytes, "IntelHDA Stream Buffers"sv, Memory::Region::Access::ReadWrite));
  59. // 3.3.38 Input/Output/Bidirectional Stream Descriptor Cyclic Buffer Length
  60. m_stream_io_window->write32(StreamRegisterOffset::CyclicBufferLength, buffers->size());
  61. // 3.3.39: Input/Output/Bidirectional Stream Descriptor Last Valid Index
  62. VERIFY(number_of_buffers_required_for_cyclic_buffer_size <= 256);
  63. m_stream_io_window->write16(StreamRegisterOffset::LastValidIndex, number_of_buffers_required_for_cyclic_buffer_size - 1);
  64. // 3.6.2: Buffer Descriptor List
  65. m_buffer_descriptor_list = TRY(MM.allocate_dma_buffer_page("IntelHDA Stream BDL"sv, Memory::Region::Access::ReadWrite));
  66. auto bdl_physical_address = m_buffer_descriptor_list->physical_page(0)->paddr().get();
  67. m_stream_io_window->write32(StreamRegisterOffset::BDLLowerBaseAddress, bdl_physical_address & 0xffffffffu);
  68. m_stream_io_window->write32(StreamRegisterOffset::BDLUpperBaseAddress, bdl_physical_address >> 32);
  69. // 3.6.3: Buffer Descriptor List Entry
  70. auto* buffer_descriptor_entry = m_buffer_descriptor_list->vaddr().as_ptr();
  71. for (u8 buffer_index = 0; buffer_index < buffers->page_count(); ++buffer_index) {
  72. auto* entry = buffer_descriptor_entry + buffer_index * 0x10;
  73. *bit_cast<u64*>(entry) = buffers->physical_page(buffer_index)->paddr().get();
  74. *bit_cast<u32*>(entry + 8) = PAGE_SIZE;
  75. *bit_cast<u32*>(entry + 12) = 0;
  76. }
  77. return {};
  78. }));
  79. return {};
  80. }
  81. ErrorOr<void> Stream::reset()
  82. {
  83. // 3.3.35: Input/Output/Bidirectional Stream Descriptor Control
  84. if (m_running)
  85. TRY(stop());
  86. // Writing a 1 causes the corresponding stream to be reset. The Stream Descriptor registers
  87. // (except the SRST bit itself), FIFO's, and cadence generator for the corresponding stream
  88. // are reset.
  89. auto control = read_control();
  90. control |= StreamControlFlag::StreamReset;
  91. write_control(control);
  92. // After the stream hardware has completed sequencing into the reset state, it will report a
  93. // 1 in this bit. Software must read a 1 from this bit to verify that the stream is in reset.
  94. TRY(wait_until(frame_delay_in_microseconds(1), controller_timeout_in_microseconds, [&]() {
  95. control = read_control();
  96. return (control & StreamControlFlag::StreamReset) > 0;
  97. }));
  98. // Writing a 0 causes the corresponding stream to exit reset.
  99. control &= ~StreamControlFlag::StreamReset;
  100. write_control(control);
  101. // When the stream hardware is ready to begin operation, it will report a 0 in this bit.
  102. // Software must read a 0 from this bit before accessing any of the stream registers
  103. return wait_until(frame_delay_in_microseconds(1), controller_timeout_in_microseconds, [&]() {
  104. control = read_control();
  105. return (control & StreamControlFlag::StreamReset) == 0;
  106. });
  107. }
  108. void Stream::start()
  109. {
  110. // 3.3.35: Input/Output/Bidirectional Stream Descriptor Control
  111. VERIFY(!m_running);
  112. dbgln_if(INTEL_HDA_DEBUG, "IntelHDA: Starting stream");
  113. auto control = read_control();
  114. control |= StreamControlFlag::StreamRun;
  115. write_control(control);
  116. m_running = true;
  117. }
  118. ErrorOr<void> Stream::stop()
  119. {
  120. // 3.3.35: Input/Output/Bidirectional Stream Descriptor Control
  121. VERIFY(m_running);
  122. dbgln_if(INTEL_HDA_DEBUG, "IntelHDA: Stopping stream");
  123. auto control = read_control();
  124. control &= ~StreamControlFlag::StreamRun;
  125. write_control(control);
  126. // 4.5.4: Stopping Streams
  127. // Wait until RUN bit is 0
  128. TRY(wait_until(frame_delay_in_microseconds(1), controller_timeout_in_microseconds, [&]() {
  129. control = read_control();
  130. return (control & StreamControlFlag::StreamRun) == 0;
  131. }));
  132. m_running = false;
  133. m_buffer_position = 0;
  134. return {};
  135. }
  136. ErrorOr<void> Stream::set_format(FormatParameters format)
  137. {
  138. // Reset the stream so we can set a new buffer
  139. TRY(reset());
  140. // Write the sample rate payload
  141. auto format_payload = TRY(encode_format(format));
  142. m_stream_io_window->write16(StreamRegisterOffset::Format, format_payload);
  143. m_format_parameters = format;
  144. // Re-initialize the bufer
  145. TRY(initialize_buffer());
  146. return {};
  147. }
  148. ErrorOr<size_t> OutputStream::write(UserOrKernelBuffer const& data, size_t length)
  149. {
  150. auto wait_until_buffer_index_can_be_written = [&](u8 buffer_index) {
  151. while (m_running) {
  152. auto link_position = m_stream_io_window->read32(StreamRegisterOffset::LinkPosition);
  153. auto read_buffer_index = link_position / PAGE_SIZE;
  154. if (read_buffer_index != buffer_index)
  155. return;
  156. auto microseconds_to_wait = ((read_buffer_index + 1) * PAGE_SIZE - link_position)
  157. / m_format_parameters.number_of_channels
  158. * 8 / m_format_parameters.pcm_bits
  159. * 1'000'000 / m_format_parameters.sample_rate;
  160. dbgln_if(INTEL_HDA_DEBUG, "IntelHDA: Waiting {} µs until buffer {} becomes writeable", microseconds_to_wait, buffer_index);
  161. // NOTE: we don't care about the reason for interruption - we simply calculate the next delay
  162. [[maybe_unused]] auto block_result = Thread::current()->sleep(Time::from_microseconds(microseconds_to_wait));
  163. }
  164. };
  165. auto write_into_single_buffer = [&](UserOrKernelBuffer const& data, size_t data_offset, size_t length, size_t offset_within_buffer) -> ErrorOr<u8> {
  166. u8 buffer_index = m_buffer_position / PAGE_SIZE;
  167. VERIFY(length <= PAGE_SIZE - offset_within_buffer);
  168. wait_until_buffer_index_can_be_written(buffer_index);
  169. TRY(m_buffers.with([&](auto& buffers) -> ErrorOr<void> {
  170. // NOTE: if the buffers were reinitialized, we might point to an out of bounds page
  171. if (buffer_index >= buffers->page_count())
  172. return EAGAIN;
  173. auto* buffer = buffers->vaddr_from_page_index(buffer_index).as_ptr() + offset_within_buffer;
  174. TRY(data.read(buffer, data_offset, length));
  175. // Cycle back to position 0 when we reach the end
  176. m_buffer_position += length;
  177. VERIFY(m_buffer_position <= buffers->size());
  178. if (m_buffer_position == buffers->size())
  179. m_buffer_position = 0;
  180. return {};
  181. }));
  182. return buffer_index;
  183. };
  184. // FIXME: support PCM bit sizes other than 16
  185. VERIFY(m_format_parameters.pcm_bits == 16);
  186. // Split up input data into separate buffer writes
  187. size_t length_remaining = length;
  188. size_t data_offset = 0;
  189. u8 last_buffer_index = 0;
  190. while (length_remaining > 0) {
  191. size_t offset_within_current_buffer = m_buffer_position % PAGE_SIZE;
  192. size_t length_to_write = AK::min(length_remaining, PAGE_SIZE - offset_within_current_buffer);
  193. last_buffer_index = TRY(write_into_single_buffer(data, data_offset, length_to_write, offset_within_current_buffer));
  194. data_offset += length_to_write;
  195. length_remaining -= length_to_write;
  196. }
  197. // Start this stream if not already running
  198. // 3.3.39: LVI must be at least 1; i.e., there must be at least two valid entries in
  199. // the buffer descriptor list before DMA operations can begin.
  200. if (!m_running && last_buffer_index >= 2)
  201. start();
  202. return length;
  203. }
  204. }