remoteproc: qcom_spss: Add support for QMP message to AOP

Add spss to the list of rprocs, who usually send message up
and down notification message to AOP and  also move
out common code from qcom_q6v5_pas to qcom_common
so that it can be used by SPSS rproc driver.

Change-Id: Idbe0774c57d9959a15873e2c71a604dc98435313
Signed-off-by: Sindhura Ganda <quic_sganda@quicinc.com>
This commit is contained in:
Sindhura Ganda 2023-09-01 16:52:53 +05:30
parent 1e8cd31109
commit 30c4242337
4 changed files with 72 additions and 16 deletions

View File

@ -35,6 +35,7 @@
#define GLINK_SUBDEV_NAME "glink"
#define SMD_SUBDEV_NAME "smd"
#define SSR_SUBDEV_NAME "ssr"
#define QMP_MSG_LEN 64
#define MAX_NUM_OF_SS 10
#define MAX_REGION_NAME_LENGTH 16
@ -315,6 +316,17 @@ static void qcom_rproc_minidump(struct rproc *rproc, struct device *md_dev)
dev_coredumpv(md_dev, data, data_size, GFP_KERNEL);
}
int qcom_rproc_toggle_load_state(struct qmp *qmp, const char *name, bool enable)
{
char buf[QMP_MSG_LEN] = {};
snprintf(buf, sizeof(buf),
"{class: image, res: load_state, name: %s, val: %s}",
name, enable ? "on" : "off");
return qmp_send(qmp, buf, sizeof(buf));
}
EXPORT_SYMBOL_GPL(qcom_rproc_toggle_load_state);
void qcom_minidump(struct rproc *rproc, struct device *md_dev, unsigned int minidump_id,
rproc_dumpfn_t dumpfn, bool both_dumps)
{

View File

@ -11,6 +11,7 @@
#include "remoteproc_internal.h"
#include <linux/soc/qcom/qmi.h>
#include <linux/remoteproc/qcom_rproc.h>
#include <linux/soc/qcom/qcom_aoss.h>
static const char * const subdevice_state_string[] = {
[QCOM_SSR_BEFORE_POWERUP] = "before_powerup",
@ -65,6 +66,8 @@ typedef void (*rproc_dumpfn_t)(struct rproc *rproc, struct rproc_dump_segment *s
void qcom_minidump(struct rproc *rproc, struct device *md_dev,
unsigned int minidump_id, rproc_dumpfn_t dumpfn, bool both_dumps);
int qcom_rproc_toggle_load_state(struct qmp *qmp, const char *name, bool enable);
void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink,
const char *ssr_name);
void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);

View File

@ -43,7 +43,6 @@
#define XO_FREQ 19200000
#define PIL_TZ_AVG_BW UINT_MAX
#define PIL_TZ_PEAK_BW UINT_MAX
#define QMP_MSG_LEN 64
#define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100
@ -241,16 +240,6 @@ static void adsp_minidump(struct rproc *rproc)
trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_minidump", "exit");
}
static int adsp_toggle_load_state(struct qmp *qmp, const char *name, bool enable)
{
char buf[QMP_MSG_LEN] = {};
snprintf(buf, sizeof(buf),
"{class: image, res: load_state, name: %s, val: %s}",
name, enable ? "on" : "off");
return qmp_send(qmp, buf, sizeof(buf));
}
static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
size_t pd_count)
{
@ -686,7 +675,7 @@ static int adsp_start(struct rproc *rproc)
goto disable_active_pds;
if (adsp->qmp) {
ret = adsp_toggle_load_state(adsp->qmp, adsp->qmp_name, true);
ret = qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, true);
if (ret)
goto disable_proxy_pds;
}
@ -785,7 +774,7 @@ static int adsp_start(struct rproc *rproc)
clk_disable_unprepare(adsp->xo);
disable_load_state:
if (adsp->qmp)
adsp_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
disable_proxy_pds:
adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
disable_active_pds:
@ -843,7 +832,7 @@ static int adsp_stop(struct rproc *rproc)
scm_pas_disable_bw();
adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
if (adsp->qmp)
adsp_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
handover = qcom_q6v5_unprepare(&adsp->q6v5);
if (handover)
qcom_pas_handover(&adsp->q6v5);
@ -904,7 +893,7 @@ static int adsp_attach(struct rproc *rproc)
if (ret < 0)
goto disable_active_pds;
ret = adsp_toggle_load_state(adsp->qmp, adsp->qmp_name, true);
ret = qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, true);
if (ret)
goto disable_proxy_pds;
@ -953,7 +942,7 @@ static int adsp_attach(struct rproc *rproc)
disable_xo_clk:
clk_disable_unprepare(adsp->xo);
disable_load_state:
adsp_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
disable_proxy_pds:
adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
disable_active_pds:

View File

@ -56,6 +56,7 @@ struct spss_data {
int pas_id;
const char *ssr_name;
bool auto_boot;
const char *qmp_name;
};
struct qcom_spss {
@ -76,6 +77,9 @@ struct qcom_spss {
size_t mem_size;
int generic_irq;
const char *qmp_name;
struct qmp *qmp;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_ssr ssr_subdev;
struct qcom_sysmon *sysmon_subdev;
@ -421,6 +425,8 @@ static int spss_stop(struct rproc *rproc)
panic("Panicking, remoteproc %s failed to shutdown.\n", rproc->name);
mask_scsr_irqs(spss);
if (spss->qmp)
qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, false);
/* Set state as OFFLINE */
rproc->state = RPROC_OFFLINE;
@ -440,6 +446,17 @@ static int spss_attach(struct rproc *rproc)
spss_stop(rproc);
return ret;
}
/* signal AOP about spss status.*/
if (spss->qmp) {
ret = qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, true);
if (ret) {
dev_err(spss->dev, "Failed to signal AOP about spss status [%d]\n", ret);
spss_stop(rproc);
return ret;
}
}
/* If booted successfully then wait for init_done*/
unmask_scsr_irqs(spss);
@ -455,6 +472,10 @@ static int spss_attach(struct rproc *rproc)
ret = ret ? 0 : -ETIMEDOUT;
/* if attach fails, signal AOP about spss status.*/
if (ret && spss->qmp)
qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, false);
return ret;
}
@ -476,6 +497,7 @@ static int spss_start(struct rproc *rproc)
{
struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
int ret = 0;
int status = 0;
ret = clk_prepare_enable(spss->xo);
if (ret)
@ -485,6 +507,16 @@ static int spss_start(struct rproc *rproc)
if (ret)
goto disable_xo_clk;
/* Signal AOP about spss status. */
if (spss->qmp) {
status = qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, true);
if (status) {
dev_err(spss->dev,
"Failed to signal AOP about spss status [%d]\n", status);
goto disable_xo_clk;
}
}
ret = qcom_scm_pas_auth_and_reset(spss->pas_id);
if (ret)
panic("Panicking, auth and reset failed for remoteproc %s\n", rproc->name);
@ -499,6 +531,14 @@ static int spss_start(struct rproc *rproc)
dev_err(spss->dev, "start timed out\n");
ret = ret ? 0 : -ETIMEDOUT;
/* if SPSS fails to start, signal AOP about spss status. */
if (ret && spss->qmp) {
status = qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, false);
if (status)
dev_err(spss->dev,
"Failed to signal AOP about spss status [%d]\n", status);
}
disable_regulator(&spss->cx);
disable_xo_clk:
clk_disable_unprepare(spss->xo);
@ -668,6 +708,7 @@ static int qcom_spss_probe(struct platform_device *pdev)
struct rproc *rproc;
const char *fw_name;
int ret;
bool signal_aop;
desc = of_device_get_match_data(&pdev->dev);
if (!desc)
@ -690,6 +731,7 @@ static int qcom_spss_probe(struct platform_device *pdev)
init_completion(&spss->start_done);
platform_set_drvdata(pdev, spss);
rproc->auto_boot = desc->auto_boot;
spss->qmp_name = desc->qmp_name;
rproc->recovery_disabled = true;
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
@ -718,6 +760,15 @@ static int qcom_spss_probe(struct platform_device *pdev)
if (ret)
goto deinit_wakeup_source;
signal_aop = of_property_read_bool(pdev->dev.of_node,
"qcom,signal-aop");
if (signal_aop) {
spss->qmp = qmp_get(spss->dev);
if (IS_ERR_OR_NULL(spss->qmp))
goto deinit_wakeup_source;
}
qcom_add_glink_spss_subdev(rproc, &spss->glink_subdev, "spss");
qcom_add_ssr_subdev(rproc, &spss->ssr_subdev, desc->ssr_name);
spss->sysmon_subdev = qcom_add_sysmon_subdev(rproc, desc->ssr_name, -EINVAL);
@ -770,6 +821,7 @@ static const struct spss_data spss_resource_init = {
.pas_id = 14,
.ssr_name = "spss",
.auto_boot = false,
.qmp_name = "spss",
};
static const struct of_device_id spss_of_match[] = {