1. 20 Apr, 2023 2 commits
  2. 19 Apr, 2023 2 commits
  3. 18 Apr, 2023 12 commits
  4. 17 Apr, 2023 13 commits
  5. 14 Apr, 2023 2 commits
  6. 13 Apr, 2023 2 commits
  7. 12 Apr, 2023 7 commits
    • Mark Brown's avatar
      ASoC: cs35l56: Add system suspend handling · 27ff688a
      Mark Brown authored
      Merge series from Richard Fitzgerald <rf@opensource.cirrus.com>:
      
      This set of patches adds handling for system suspend.
      Patches 1..4 make some code changes that simplify the
      suspend implementation, mainly to avoid race conditions.
      
      There are two seperate aspects to suspend, and these have
      been done as two patches:
      - the main suspend-resume handling,
      - re-loading the firmware if necessary after resume.
      27ff688a
    • Richard Fitzgerald's avatar
      ASoC: cs35l56: Re-patch firmware after system suspend · 59322d35
      Richard Fitzgerald authored
      Check during cs35l56_system_resume() whether the firmware patch must
      be applied again.
      
      The FIRMWARE_MISSING flag in the PROTECTION_STATUS register indicates
      whether the firmware has been patched.
      
      In non-secure mode the FIRMWARE_MISSING flag is cleared at the end of
      dsp_work(). If it is set after system-resume we know that dsp_work()
      must be run again.
      
      In secure mode the pre-OS loader will have done the secure patching
      and cleared the FIRMWARE_MISSING flag. So this flag does not tell us
      whether firmware memory was lost. But the driver could only be
      downloading non-secure tunings, which is always safe to do.
      
      If the driver has control of RESET we will have asserted it during
      suspend so the firmware patch will have been lost. The driver would only
      have control of RESET in non-secure mode.
      Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
      Link: https://lore.kernel.org/r/168122674550.26.8545058503709956172@mailman-core.alsa-project.orgSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      59322d35
    • Richard Fitzgerald's avatar
      ASoC: cs35l56: Remove quick-cancelling of dsp_work() · 39a594dc
      Richard Fitzgerald authored
      Delete the 'removing' flag and don't kick init_completion to make a
      quick cancel of dsp_work(). Just let it timeout on the wait for the
      completion.
      
      Simplify the code to standard cancelling or flushing of the work.
      This avoids introducing corner cases from a layer of custom signalling.
      It also avoids potential race conditions when system-suspend handling
      is added.
      
      Unless the hardware is broken, the dsp_work() will already have started
      and passed the completion before the driver would want to cancel it.
      Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
      Link: https://lore.kernel.org/r/168122674746.26.16881587647873355224@mailman-core.alsa-project.orgSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      39a594dc
    • Richard Fitzgerald's avatar
      ASoC: cs35l56: Add basic system suspend handling · f9dc6b87
      Richard Fitzgerald authored
      This adds the main handling for system suspend but does not handle
      re-patching the firmware after system resume.
      
      This is a multi-stage suspend and resume because if there is a
      RESET line it is almost certain that it will be shared by all the
      amps. So every amp must have done its suspend before we can
      assert RESET. Likewise we must de-assert RESET before the amps
      can resume.
      
      It's preferable to assert RESET before we turning off regulators, and
      while they power up.
      
      The actual suspend and resume is done by using the pair
      pm_runtime_force_suspend() and pm_runtime_force_resume() to
      re-use our runtime suspend/resume sequences.
      
      pm_runtime_force_suspend() will disable our pm_runtime. If we were
      runtime-resumed it calls our runtime_suspend().
      
      pm_runtime_force_resume() re-enables pm_runtime and if we were
      originally runtime-resumed before the pm_runtime_force_suspend()
      it calls our runtime_resume(). Otherwise it leaves us
      runtime-suspended.
      
      The general process is therefore:
      
       suspend() -> finish dsp_work and then run our runtime_suspend
       suspend_late() -> assert RESET and turn off supplies
       resume_early() -> enable supplies and de-assert RESET
       resume() -> pm_runtime_force_resume()
      
      In addition, to prevent the IRQ handler running in the period
      between pm_runtime_force_suspend() and pm_runtime_force_resume()
      the parent IRQ is temporarily disabled:
       - from suspend until suspend_noirq
       - from resume_noirq until resume
      Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
      Link: https://lore.kernel.org/r/20230411152528.329803-6-rf@opensource.cirrus.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      f9dc6b87
    • Richard Fitzgerald's avatar
      ASoC: cs35l56: Always wait for firmware boot in runtime-resume · f00abadd
      Richard Fitzgerald authored
      When we are resuming from a system suspend the CS35L56 has probably
      been hard reset (usually a power-on reset). So we must wait for the
      firmware to boot. On SoundWire we also need it to re-initialize before
      we can read the registers to check the CS35L56 state.
      
      The simplest way to handle this is for runtime-resume to always wait
      for firmware boot. If the firmware is already booted the overhead is
      only one register read.
      
      The system-resume will have to runtime-resume the driver anyway before
      attempting any register access. So this will automatically include the
      wait for initialization on SoundWire.
      Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
      Link: https://lore.kernel.org/r/20230411152528.329803-5-rf@opensource.cirrus.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      f00abadd
    • Richard Fitzgerald's avatar
      ASoC: cs35l56: Skip first init_completion wait in dsp_work if init_done · 7816e340
      Richard Fitzgerald authored
      At the start of dsp_work() only wait for init_completion if !init_done.
      This allows system suspend to re-queue dsp_work() without having to
      do a dummy complete() of init_completion.
      
      A dummy completion in system suspend would have to be conditional on
      init_done. But that would create a possible race condition between our
      system resume and cs35l56_init() in the corner case that we suspend right
      after the SoundWire core has enumerated and reported ATTACHED.
      
      It is safer and simpler to have cs35l56_init() as the only place that
      init_completion is completed, and dsp_work() as the only place that
      it is consumed.
      Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
      Link: https://lore.kernel.org/r/20230411152528.329803-4-rf@opensource.cirrus.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      7816e340
    • Richard Fitzgerald's avatar
      ASoC: cs35l56: Use DAPM widget for firmware PLAY/PAUSE · 7b98a1ef
      Richard Fitzgerald authored
      If we use a DAPM widget instead of mute_stream() to send the
      PLAY command we can issue the plays to multiple amps in parallel.
      With mute_stream each codec driver instance is called one at a
      time so we get N * PS0 delay time.
      
      DAPM does each stage on every widget in a card before moving to
      the next stage. So all amps will do the PRE_PMU then all will do
      the POST_PMU. The PLAY is sent in the PRE_PMU so that they all
      power-up in parallel. After the PS0 wait in the first POST_PMU
      all the other amps will also be ready so there won't be any extra
      delay, or it will be negligible.
      
      There's also no point waiting for the MBOX ack in the PRE_PMU.
      We won't see a PS0 state in POST_PMU if it didn't ack the PLAY
      command. So we can save a little extra time.
      Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
      Link: https://lore.kernel.org/r/20230411152528.329803-3-rf@opensource.cirrus.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      7b98a1ef