Commit 1fb82ee8 authored by Bjorn Andersson's avatar Bjorn Andersson
Browse files

remoteproc: qcom: Introduce sysmon



The sysmon client communicates either via a dedicated SMD/GLINK channel
or via QMI encoded messages over IPCROUTER with remote processors in
order to perform graceful shutdown and inform about other remote
processors shutting down.

Acked-By: default avatarChris Lew <clew@codeaurora.org>
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 880f5b38
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ config QCOM_ADSP_PIL
	depends on QCOM_SMEM
	depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
	depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
	depends on QCOM_SYSMON || QCOM_SYSMON=n
	select MFD_SYSCON
	select QCOM_MDT_LOADER
	select QCOM_RPROC_COMMON
@@ -108,6 +109,7 @@ config QCOM_Q6V5_PIL
	depends on QCOM_SMEM
	depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
	depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
	depends on QCOM_SYSMON || QCOM_SYSMON=n
	select MFD_SYSCON
	select QCOM_RPROC_COMMON
	select QCOM_SCM
@@ -115,12 +117,27 @@ config QCOM_Q6V5_PIL
	  Say y here to support the Qualcomm Peripherial Image Loader for the
	  Hexagon V5 based remote processors.

config QCOM_SYSMON
	tristate "Qualcomm sysmon driver"
	depends on RPMSG
	depends on ARCH_QCOM
	select QCOM_QMI_HELPERS
	help
	  The sysmon driver implements a sysmon QMI client and a handler for
	  the sys_mon SMD and GLINK channel, which are used for graceful
	  shutdown, retrieving failure information and propagating information
	  about other subsystems being shut down.

	  Say y here if your system runs firmware on any other subsystems, e.g.
	  modem or DSP.

config QCOM_WCNSS_PIL
	tristate "Qualcomm WCNSS Peripheral Image Loader"
	depends on OF && ARCH_QCOM
	depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
	depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
	depends on QCOM_SMEM
	depends on QCOM_SYSMON || QCOM_SYSMON=n
	select QCOM_MDT_LOADER
	select QCOM_RPROC_COMMON
	select QCOM_SCM
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYSTONE_REMOTEPROC) += keystone_remoteproc.o
obj-$(CONFIG_QCOM_ADSP_PIL)		+= qcom_adsp_pil.o
obj-$(CONFIG_QCOM_RPROC_COMMON)		+= qcom_common.o
obj-$(CONFIG_QCOM_Q6V5_PIL)		+= qcom_q6v5_pil.o
obj-$(CONFIG_QCOM_SYSMON)		+= qcom_sysmon.o
obj-$(CONFIG_QCOM_WCNSS_PIL)		+= qcom_wcnss_pil.o
qcom_wcnss_pil-y			+= qcom_wcnss.o
qcom_wcnss_pil-y			+= qcom_wcnss_iris.o
+12 −0
Original line number Diff line number Diff line
@@ -38,7 +38,10 @@ struct adsp_data {
	const char *firmware_name;
	int pas_id;
	bool has_aggre2_clk;

	const char *ssr_name;
	const char *sysmon_name;
	int ssctl_id;
};

struct qcom_adsp {
@@ -75,6 +78,7 @@ struct qcom_adsp {
	struct qcom_rproc_glink glink_subdev;
	struct qcom_rproc_subdev smd_subdev;
	struct qcom_rproc_ssr ssr_subdev;
	struct qcom_sysmon *sysmon;
};

static int adsp_load(struct rproc *rproc, const struct firmware *fw)
@@ -398,6 +402,9 @@ static int adsp_probe(struct platform_device *pdev)
	qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
	qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
					      desc->sysmon_name,
					      desc->ssctl_id);

	ret = rproc_add(rproc);
	if (ret)
@@ -419,6 +426,7 @@ static int adsp_remove(struct platform_device *pdev)
	rproc_del(adsp->rproc);

	qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
	qcom_remove_sysmon_subdev(adsp->sysmon);
	qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
	rproc_free(adsp->rproc);
@@ -432,6 +440,8 @@ static const struct adsp_data adsp_resource_init = {
		.pas_id = 1,
		.has_aggre2_clk = false,
		.ssr_name = "lpass",
		.sysmon_name = "adsp",
		.ssctl_id = 0x14,
};

static const struct adsp_data slpi_resource_init = {
@@ -440,6 +450,8 @@ static const struct adsp_data slpi_resource_init = {
		.pas_id = 12,
		.has_aggre2_clk = true,
		.ssr_name = "dsps",
		.sysmon_name = "slpi",
		.ssctl_id = 0x16,
};

static const struct of_device_id adsp_of_match[] = {
+21 −0
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@

#include <linux/remoteproc.h>
#include "remoteproc_internal.h"
#include <linux/soc/qcom/qmi.h>

struct qcom_sysmon;

struct qcom_rproc_glink {
	struct rproc_subdev subdev;
@@ -39,4 +42,22 @@ void qcom_add_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr,
			 const char *ssr_name);
void qcom_remove_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr);

#if IS_ENABLED(CONFIG_QCOM_SYSMON)
struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
					   const char *name,
					   int ssctl_instance);
void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon);
#else
static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
							 const char *name,
							 int ssctl_instance)
{
	return NULL;
}

static inline void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon)
{
}
#endif

#endif
+3 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ struct q6v5 {

	struct qcom_rproc_subdev smd_subdev;
	struct qcom_rproc_ssr ssr_subdev;
	struct qcom_sysmon *sysmon;
	bool need_mem_protection;
	int mpss_perm;
	int mba_perm;
@@ -1209,6 +1210,7 @@ static int q6v5_probe(struct platform_device *pdev)
	qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
	qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
	qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
	qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);

	ret = rproc_add(rproc);
	if (ret)
@@ -1228,6 +1230,7 @@ static int q6v5_remove(struct platform_device *pdev)

	rproc_del(qproc->rproc);

	qcom_remove_sysmon_subdev(qproc->sysmon);
	qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev);
	qcom_remove_ssr_subdev(qproc->rproc, &qproc->ssr_subdev);
	rproc_free(qproc->rproc);
Loading