debugfs_create_bool("booted", 0444, root, &dsp->booted);
debugfs_create_bool("running", 0444, root, &dsp->running);
+ debugfs_create_bool("hibernating", 0444, root, &dsp->hibernating);
debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id);
debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version);
lockdep_assert_held(&dsp->pwr_lock);
- if (!dsp->running)
+ if (!dsp->running || dsp->hibernating)
return -EPERM;
ret = cs_dsp_coeff_base_reg(ctl, ®, 0);
}
ctl->set = 1;
- if (ctl->enabled && ctl->dsp->running)
+ if (ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating)
ret = cs_dsp_coeff_write_ctrl_raw(ctl, off, buf, len);
if (ret < 0)
return -EINVAL;
if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
- if (ctl->enabled && ctl->dsp->running)
+ if (ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating)
return cs_dsp_coeff_read_ctrl_raw(ctl, off, buf, len);
else
return -EPERM;
} else {
- if (!ctl->flags && ctl->enabled && ctl->dsp->running)
+ if (!ctl->flags && ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating)
ret = cs_dsp_coeff_read_ctrl_raw(ctl, 0, ctl->cache, ctl->len);
if (buf != ctl->cache)
return ret;
}
+
+/**
+ * cs_dsp_hibernate() - Disable or enable all controls for a DSP
+ * @dsp: pointer to DSP structure
+ * @hibernate: whether to set controls to cache only mode
+ *
+ * When @hibernate is true, the DSP is entering hibernation mode where the
+ * regmap is inaccessible, and all controls become cache only.
+ * When @hibernate is false, the DSP has exited hibernation mode. If the DSP
+ * is running, all controls are re-synced to the DSP.
+ *
+ */
+void cs_dsp_hibernate(struct cs_dsp *dsp, bool hibernate)
+{
+ mutex_lock(&dsp->pwr_lock);
+
+ if (!dsp->running) {
+ cs_dsp_dbg(dsp, "Cannot hibernate, DSP not running\n");
+ goto out;
+ }
+
+ if (dsp->hibernating == hibernate)
+ goto out;
+
+ cs_dsp_dbg(dsp, "Set hibernating to %d\n", hibernate);
+ dsp->hibernating = hibernate;
+
+ if (!dsp->hibernating && dsp->running) {
+ int ret = cs_dsp_coeff_sync_controls(dsp);
+
+ if (ret)
+ cs_dsp_err(dsp, "Error syncing controls: %d\n", ret);
+ }
+out:
+ mutex_unlock(&dsp->pwr_lock);
+}
+EXPORT_SYMBOL_NS_GPL(cs_dsp_hibernate, "FW_CS_DSP");
+
struct cs_dsp_coeff_parsed_alg {
int id;
const u8 *name;
goto err_ena;
dsp->booted = true;
+ dsp->hibernating = false;
/* Start the core running */
regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
dsp->ops->disable_core(dsp);
dsp->booted = true;
+ dsp->hibernating = false;
mutex_unlock(&dsp->pwr_lock);