2019-05-29 07:08:45 +08:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Dominik Bozek <dominikx.bozek@intel.com>
|
|
|
|
Date: Fri, 17 May 2019 10:47:00 +0200
|
|
|
|
Subject: [PATCH] SoC: Intel: Skylake: BXT: Stop polling FwStauts after halt
|
|
|
|
|
|
|
|
Implementation of skl_dsp_fw_ops.load_fw() reuse generic function
|
|
|
|
sst_dsp_register_poll(). But this function shouldn't be used for
|
|
|
|
polling states in FwStatus. FW may notify halt state earlier and
|
|
|
|
further polling for particular state is waist of the time.
|
|
|
|
This patch add function dedicated to poll FwStatus.
|
|
|
|
|
|
|
|
Change-Id: I23783a507ccd71fd514f0a0e2246c40e406b7c47
|
|
|
|
Tracked-On: ACI-5767
|
|
|
|
Tracked-On: OAM-80502
|
|
|
|
Signed-off-by: Dominik Bozek <dominikx.bozek@intel.com>
|
|
|
|
---
|
|
|
|
sound/soc/intel/skylake/bxt-sst.c | 67 ++++++++++++++++++++++++++++++-
|
|
|
|
1 file changed, 65 insertions(+), 2 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
|
2020-05-05 09:02:46 +08:00
|
|
|
index b158883ef..887a43bcd 100644
|
2019-05-29 07:08:45 +08:00
|
|
|
--- a/sound/soc/intel/skylake/bxt-sst.c
|
|
|
|
+++ b/sound/soc/intel/skylake/bxt-sst.c
|
|
|
|
@@ -144,6 +144,69 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
+int sst_fw_status_poll(struct sst_dsp *ctx, u32 module, u32 state,
|
|
|
|
+ u32 time, char *operation)
|
|
|
|
+{
|
|
|
|
+ union {
|
|
|
|
+ struct {
|
|
|
|
+ u32 state:24;
|
|
|
|
+ u32 waits:4;
|
|
|
|
+ u32 module:3;
|
|
|
|
+ u32 halted:1;
|
|
|
|
+ };
|
|
|
|
+ u32 raw;
|
|
|
|
+ } fwsts;
|
|
|
|
+ unsigned long timeout;
|
|
|
|
+ int k = 0, s;
|
|
|
|
+ int ret;
|
|
|
|
+ char *state_desc;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * split the loop into sleeps of varying resolution.
|
|
|
|
+ * By observation, FW responds in 10 to 20ms.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ timeout = jiffies + msecs_to_jiffies(time);
|
|
|
|
+
|
|
|
|
+ fwsts.raw = sst_dsp_shim_read_unlocked(ctx, BXT_ADSP_FW_STATUS);
|
|
|
|
+ while (!fwsts.halted
|
|
|
|
+ && (fwsts.module == module)
|
|
|
|
+ && (fwsts.state != state)
|
|
|
|
+ && time_before(jiffies, timeout)) {
|
|
|
|
+
|
|
|
|
+ k++;
|
|
|
|
+ switch (k) {
|
|
|
|
+ case 1:
|
|
|
|
+ case 12:
|
|
|
|
+ s = 10000;
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ s = 1000;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ usleep_range(s, s+100);
|
|
|
|
+
|
|
|
|
+ fwsts.raw = sst_dsp_shim_read_unlocked(ctx, BXT_ADSP_FW_STATUS);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!fwsts.halted && (fwsts.module == module)
|
|
|
|
+ && (fwsts.state == state)) {
|
|
|
|
+ state_desc = "success";
|
|
|
|
+ ret = 0;
|
|
|
|
+ } else if (fwsts.halted || fwsts.module != module) {
|
|
|
|
+ state_desc = "unexpected state";
|
|
|
|
+ ret = -EPROTO;
|
|
|
|
+ } else {
|
|
|
|
+ state_desc = "timeout";
|
|
|
|
+ ret = -ETIME;
|
|
|
|
+ }
|
|
|
|
+ dev_dbg(ctx->dev, "FW Status=%08x %s %s\n", fwsts.raw,
|
|
|
|
+ operation, state_desc);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* First boot sequence has some extra steps. Core 0 waits for power
|
|
|
|
* status on core 1, so power up core 1 also momentarily, keep it in
|
|
|
|
@@ -210,7 +273,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
|
|
|
|
skl_ipc_op_int_enable(ctx);
|
|
|
|
|
|
|
|
/* Step 7: Wait for ROM init */
|
|
|
|
- ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
|
|
|
|
+ ret = sst_fw_status_poll(ctx, 0,
|
|
|
|
SKL_FW_INIT, BXT_ROM_INIT_TIMEOUT, "ROM Load");
|
|
|
|
if (ret < 0) {
|
|
|
|
dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret);
|
|
|
|
@@ -234,7 +297,7 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
|
|
|
|
|
|
|
|
ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag,
|
|
|
|
SNDRV_PCM_STREAM_PLAYBACK);
|
|
|
|
- ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
|
|
|
|
+ ret = sst_fw_status_poll(ctx, 0,
|
|
|
|
BXT_ROM_INIT, BXT_BASEFW_TIMEOUT, "Firmware boot");
|
|
|
|
|
|
|
|
ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag,
|
|
|
|
--
|
|
|
|
https://clearlinux.org
|
|
|
|
|