Commit c99fafdf authored by Kai Vehmanen's avatar Kai Vehmanen Committed by Takashi Iwai

ASoC: SOF: Intel: hda: release display power at link_power

The i915 display power is requested both by controller (for init
and link reset) as well as by codec driver (for codec control).

There's an additional constraint that on some platforms frequent changes
to display power state may cause visible flicker. To avoid this, the SOF
hda controller requests display power whenever it is active and only
releases it when runtime suspended.

This patch utilizes the new hdac_bus link_power op to plug
into HDA link state changes. By monitoring link state changes,
we can keep the controller side display power wakeref until
the codec driver has completed its work, and only release
the wakeref when codec driver is suspended.
Signed-off-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Acked-by: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210205184630.1938761-4-kai.vehmanen@linux.intel.comSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 87fc20e4
......@@ -9,6 +9,7 @@
#include <linux/io.h>
#include <sound/hdaudio.h>
#include <sound/hda_i915.h>
#include "../sof-priv.h"
#include "hda.h"
......@@ -20,10 +21,32 @@
#endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
static void sof_hda_bus_link_power(struct hdac_device *codec, bool enable)
{
struct hdac_bus *bus = codec->bus;
bool oldstate = test_bit(codec->addr, &bus->codec_powered);
snd_hdac_ext_bus_link_power(codec, enable);
if (enable == oldstate)
return;
/*
* Both codec driver and controller can hold references to
* display power. To avoid unnecessary power-up/down cycles,
* controller doesn't immediately release its reference.
*
* If the codec driver powers down the link, release
* the controller reference as well.
*/
if (codec->addr == HDA_IDISP_ADDR && !enable)
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
}
static const struct hdac_bus_ops bus_core_ops = {
.command = snd_hdac_bus_send_cmd,
.get_response = snd_hdac_bus_get_response,
.link_power = snd_hdac_ext_bus_link_power,
.link_power = sof_hda_bus_link_power,
};
#endif
......
......@@ -388,7 +388,8 @@
#define SSP_SET_SFRM_SLAVE BIT(24)
#define SSP_SET_SLAVE (SSP_SET_SCLK_SLAVE | SSP_SET_SFRM_SLAVE)
#define HDA_IDISP_CODEC(x) ((x) & BIT(2))
#define HDA_IDISP_ADDR 2
#define HDA_IDISP_CODEC(x) ((x) & BIT(HDA_IDISP_ADDR))
struct sof_intel_dsp_bdl {
__le32 addr_l;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment