Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a83e3b4c authored by Vinod Koul's avatar Vinod Koul Committed by Mark Brown
Browse files

ASoC: Intel: Skylake: Add D0i3 mode ref counting



For device opened/closed, we check the D0i3 capability for the device
and invoke skl_tplg_d0i3_get/put, which counts the use case based on the
mode supported.

These counters are then used to decide if the device can enter D0i3 mode
of streaming or non-streaming or no D0i3.

Signed-off-by: default avatarJayachandran B <jayachandran.b@intel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 6bd9dcf3
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -610,10 +610,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
	if (ret)
		return ret;

	/* set the D0i3 check */
	skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;

	skl->cores.count = 2;
	skl->boot_complete = false;
	init_waitqueue_head(&skl->boot_wait);
	skl->is_first_boot = true;
	INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3);
	skl->d0i3.state = SKL_DSP_D0I3_NONE;

	if (dsp)
		*dsp = skl;
+9 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
	struct hdac_ext_stream *stream;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct skl_dma_params *dma_params;
	struct skl *skl = get_skl_ctx(dai->dev);
	struct skl_module_cfg *mconfig;

	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);

@@ -177,6 +179,9 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
	skl_set_suspend_active(substream, dai, true);
	snd_pcm_set_sync(substream);

	mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
	skl_tplg_d0i3_get(skl, mconfig->d0i3_caps);

	return 0;
}

@@ -302,6 +307,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
	struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
	struct skl_dma_params *dma_params = NULL;
	struct skl *skl = ebus_to_skl(ebus);
	struct skl_module_cfg *mconfig;

	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);

@@ -325,6 +331,9 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
		skl->skl_sst->miscbdcg_disabled = false;
	}

	mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
	skl_tplg_d0i3_put(skl, mconfig->d0i3_caps);

	kfree(dma_params);
}

+17 −0
Original line number Diff line number Diff line
@@ -306,6 +306,23 @@ static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
		header->primary | SKL_ADSP_REG_HIPCI_BUSY);
}

int skl_ipc_check_D0i0(struct sst_dsp *dsp, bool state)
{
	int ret;

	/* check D0i3 support */
	if (!dsp->fw_ops.set_state_D0i0)
		return 0;

	/* Attempt D0i0 or D0i3 based on state */
	if (state)
		ret = dsp->fw_ops.set_state_D0i0(dsp);
	else
		ret = dsp->fw_ops.set_state_D0i3(dsp);

	return ret;
}

static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
				u64 ipc_header)
{
+2 −0
Original line number Diff line number Diff line
@@ -187,6 +187,8 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc,
		struct skl_ipc_d0ix_msg *msg);

int skl_ipc_check_D0i0(struct sst_dsp *dsp, bool state);

void skl_ipc_int_enable(struct sst_dsp *dsp);
void skl_ipc_op_int_enable(struct sst_dsp *ctx);
void skl_ipc_op_int_disable(struct sst_dsp *ctx);
+38 −0
Original line number Diff line number Diff line
@@ -36,6 +36,44 @@
#define SKL_IN_DIR_BIT_MASK		BIT(0)
#define SKL_PIN_COUNT_MASK		GENMASK(7, 4)

void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps)
{
	struct skl_d0i3_data *d0i3 =  &skl->skl_sst->d0i3;

	switch (caps) {
	case SKL_D0I3_NONE:
		d0i3->non_d0i3++;
		break;

	case SKL_D0I3_STREAMING:
		d0i3->streaming++;
		break;

	case SKL_D0I3_NON_STREAMING:
		d0i3->non_streaming++;
		break;
	}
}

void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps)
{
	struct skl_d0i3_data *d0i3 =  &skl->skl_sst->d0i3;

	switch (caps) {
	case SKL_D0I3_NONE:
		d0i3->non_d0i3--;
		break;

	case SKL_D0I3_STREAMING:
		d0i3->streaming--;
		break;

	case SKL_D0I3_NON_STREAMING:
		d0i3->non_streaming--;
		break;
	}
}

/*
 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
 * ignore. This helpers checks if the SKL driver handles this widget type
Loading