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

Commit 163b4edb authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ARM: dts: msm: Enable ADSP audio PDR for sm8150"

parents 3b8a2994 80ff83e7
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@ Optional properties:
- qcom,adsp-remoteheap-vmid:  FastRPC remote heap VMID list
- qcom,adsp-remoteheap-vmid:  FastRPC remote heap VMID list
- qcom,secure-context-bank		:	Bool indicating secure FastRPC context bank.
- qcom,secure-context-bank		:	Bool indicating secure FastRPC context bank.
- qcom,fastrpc-legacy-remote-heap	:	Bool indicating hypervisor is not supported.
- qcom,fastrpc-legacy-remote-heap	:	Bool indicating hypervisor is not supported.
- qcom,fastrpc-adsp-audio-pdr:  Flag to enable ADSP Audio PDR


Optional subnodes:
Optional subnodes:
- qcom,msm_fastrpc_compute_cb :	Child nodes representing the compute context
- qcom,msm_fastrpc_compute_cb :	Child nodes representing the compute context
+1 −0
Original line number Original line Diff line number Diff line
@@ -2313,6 +2313,7 @@


	qcom,msm_fastrpc {
	qcom,msm_fastrpc {
		compatible = "qcom,msm-fastrpc-compute";
		compatible = "qcom,msm-fastrpc-compute";
		qcom,fastrpc-adsp-audio-pdr;
		qcom,rpc-latency-us = <611>;
		qcom,rpc-latency-us = <611>;


		qcom,msm_fastrpc_compute_cb1 {
		qcom,msm_fastrpc_compute_cb1 {
+176 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,8 @@
#include <linux/rpmsg.h>
#include <linux/rpmsg.h>
#include <soc/qcom/subsystem_notif.h>
#include <soc/qcom/subsystem_notif.h>
#include <soc/qcom/subsystem_restart.h>
#include <soc/qcom/subsystem_restart.h>
#include <soc/qcom/service-notifier.h>
#include <soc/qcom/service-locator.h>
#include <linux/scatterlist.h>
#include <linux/scatterlist.h>
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/uaccess.h>
@@ -61,6 +63,9 @@
#define VMID_ADSP_Q6    6
#define VMID_ADSP_Q6    6
#define DEBUGFS_SIZE 1024
#define DEBUGFS_SIZE 1024


#define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME   "audio_pdr_adsprpc"
#define AUDIO_PDR_ADSP_SERVICE_NAME              "avs/audio"

#define RPC_TIMEOUT	(5 * HZ)
#define RPC_TIMEOUT	(5 * HZ)
#define BALIGN		128
#define BALIGN		128
#define NUM_CHANNELS	4	/* adsp, mdsp, slpi, cdsp*/
#define NUM_CHANNELS	4	/* adsp, mdsp, slpi, cdsp*/
@@ -112,6 +117,9 @@
			(int64_t *)(perf_ptr + offset)\
			(int64_t *)(perf_ptr + offset)\
				: (int64_t *)NULL) : (int64_t *)NULL)
				: (int64_t *)NULL) : (int64_t *)NULL)


static int fastrpc_audio_pdr_notifier_cb(struct notifier_block *nb,
					unsigned long code,
					void *data);
static struct dentry *debugfs_root;
static struct dentry *debugfs_root;
static struct dentry *debugfs_global_file;
static struct dentry *debugfs_global_file;


@@ -227,12 +235,23 @@ struct fastrpc_session_ctx {
	int used;
	int used;
};
};


struct fastrpc_static_pd {
	char *spdname;
	struct notifier_block pdrnb;
	struct notifier_block get_service_nb;
	void *pdrhandle;
	int pdrcount;
	int prevpdrcount;
	int ispdup;
};

struct fastrpc_channel_ctx {
struct fastrpc_channel_ctx {
	char *name;
	char *name;
	char *subsys;
	char *subsys;
	struct rpmsg_device *chan;
	struct rpmsg_device *chan;
	struct device *dev;
	struct device *dev;
	struct fastrpc_session_ctx session[NUM_SESSIONS];
	struct fastrpc_session_ctx session[NUM_SESSIONS];
	struct fastrpc_static_pd spd[NUM_SESSIONS];
	struct completion work;
	struct completion work;
	struct completion workport;
	struct completion workport;
	struct notifier_block nb;
	struct notifier_block nb;
@@ -331,6 +350,7 @@ struct fastrpc_file {
	int cid;
	int cid;
	int ssrcount;
	int ssrcount;
	int pd;
	int pd;
	char *spdname;
	int file_close;
	int file_close;
	struct fastrpc_apps *apps;
	struct fastrpc_apps *apps;
	struct hlist_head perf;
	struct hlist_head perf;
@@ -348,6 +368,14 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {
	{
	{
		.name = "adsprpc-smd",
		.name = "adsprpc-smd",
		.subsys = "adsp",
		.subsys = "adsp",
		.spd = {
			{
				.spdname =
					AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
				.pdrnb.notifier_call =
						fastrpc_audio_pdr_notifier_cb,
			}
		},
	},
	},
	{
	{
		.name = "mdsprpc-smd",
		.name = "mdsprpc-smd",
@@ -1150,6 +1178,21 @@ static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
	spin_unlock(&me->hlock);
	spin_unlock(&me->hlock);


}
}

static void fastrpc_notify_pdr_drivers(struct fastrpc_apps *me, char *spdname)
{
	struct fastrpc_file *fl;
	struct hlist_node *n;

	spin_lock(&me->hlock);
	hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
		if (fl->spdname && !strcmp(spdname, fl->spdname))
			fastrpc_notify_users(fl);
	}
	spin_unlock(&me->hlock);

}

static void context_list_ctor(struct fastrpc_ctx_lst *me)
static void context_list_ctor(struct fastrpc_ctx_lst *me)
{
{
	INIT_HLIST_HEAD(&me->interrupted);
	INIT_HLIST_HEAD(&me->interrupted);
@@ -1738,7 +1781,28 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
	return err;
	return err;
}
}


static int fastrpc_get_adsp_session(char *name, int *session)
{
	struct fastrpc_apps *me = &gfa;
	int err = 0, i;

	for (i = 0; i < NUM_SESSIONS; i++) {
		if (!me->channel[0].spd[i].spdname)
			continue;
		if (!strcmp(name, me->channel[0].spd[i].spdname))
			break;
	}
	VERIFY(err, i < NUM_SESSIONS);
	if (err)
		goto bail;
	*session = i;
bail:
	return err;
}

static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl);
static int fastrpc_channel_open(struct fastrpc_file *fl);
static int fastrpc_channel_open(struct fastrpc_file *fl);
static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl);
static int fastrpc_init_process(struct fastrpc_file *fl,
static int fastrpc_init_process(struct fastrpc_file *fl,
				struct fastrpc_ioctl_init_attrs *uproc)
				struct fastrpc_ioctl_init_attrs *uproc)
{
{
@@ -1878,6 +1942,12 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
		inbuf.pgid = current->tgid;
		inbuf.pgid = current->tgid;
		inbuf.namelen = init->filelen;
		inbuf.namelen = init->filelen;
		inbuf.pageslen = 0;
		inbuf.pageslen = 0;

		if (!strcmp(proc_name, "audiopd")) {
			fl->spdname = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME;
			VERIFY(err, !fastrpc_mmap_remove_pdr(fl));
		}

		if (!me->staticpd_flags && !(me->legacy_remote_heap)) {
		if (!me->staticpd_flags && !(me->legacy_remote_heap)) {
			inbuf.pageslen = 1;
			inbuf.pageslen = 1;
			mutex_lock(&fl->map_mutex);
			mutex_lock(&fl->map_mutex);
@@ -2202,6 +2272,33 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
	return err;
	return err;
}
}


static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl)
{
	struct fastrpc_apps *me = &gfa;
	int session = 0, err = 0;

	VERIFY(err, !fastrpc_get_adsp_session(
			AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
	if (err)
		goto bail;
	if (me->channel[fl->cid].spd[session].pdrcount !=
		me->channel[fl->cid].spd[session].prevpdrcount) {
		if (fastrpc_mmap_remove_ssr(fl))
			pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
		me->channel[fl->cid].spd[session].prevpdrcount =
				me->channel[fl->cid].spd[session].pdrcount;
	}
	if (!me->channel[fl->cid].spd[session].ispdup) {
		VERIFY(err, 0);
		if (err) {
			err = -ENOTCONN;
			goto bail;
		}
	}
bail:
	return err;
}

static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
			     size_t len, struct fastrpc_mmap **ppmap);
			     size_t len, struct fastrpc_mmap **ppmap);


@@ -3039,6 +3136,64 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
	return NOTIFY_DONE;
	return NOTIFY_DONE;
}
}


static int fastrpc_audio_pdr_notifier_cb(struct notifier_block *pdrnb,
					unsigned long code,
					void *data)
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_static_pd *spd;
	struct notif_data *notifdata = data;

	spd = container_of(pdrnb, struct fastrpc_static_pd, pdrnb);
	if (code == SERVREG_NOTIF_SERVICE_STATE_DOWN_V01) {
		mutex_lock(&me->smd_mutex);
		spd->pdrcount++;
		spd->ispdup = 0;
		pr_info("ADSPRPC: Audio PDR notifier %d %s\n",
					MAJOR(me->dev_no), spd->spdname);
		mutex_unlock(&me->smd_mutex);
		if (!strcmp(spd->spdname,
				AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME))
			me->staticpd_flags = 0;
		fastrpc_notify_pdr_drivers(me, spd->spdname);
	} else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
		if (me->channel[0].remoteheap_ramdump_dev &&
				notifdata->enable_ramdump) {
			me->channel[0].ramdumpenabled = 1;
		}
	} else if (code == SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
		spd->ispdup = 1;
	}

	return NOTIFY_DONE;
}

static int fastrpc_get_service_location_notify(struct notifier_block *nb,
					     unsigned long opcode, void *data)
{
	struct fastrpc_static_pd *spd;
	struct pd_qmi_client_data *pdr = data;
	int curr_state = 0;

	spd = container_of(nb, struct fastrpc_static_pd, get_service_nb);
	if (opcode == LOCATOR_DOWN) {
		pr_err("ADSPRPC: Audio PD restart notifier locator down\n");
		return NOTIFY_DONE;
	}

	if (pdr->total_domains == 1) {
		spd->pdrhandle = service_notif_register_notifier(
				pdr->domain_list[0].name,
				pdr->domain_list[0].instance_id,
				&spd->pdrnb, &curr_state);
		if (IS_ERR(spd->pdrhandle))
			pr_err("ADSPRPC: Unable to register notifier\n");
	} else
		pr_err("ADSPRPC: Service returned invalid domains\n");

	return NOTIFY_DONE;
}

static const struct file_operations fops = {
static const struct file_operations fops = {
	.open = fastrpc_device_open,
	.open = fastrpc_device_open,
	.release = fastrpc_device_release,
	.release = fastrpc_device_release,
@@ -3207,6 +3362,7 @@ static int fastrpc_probe(struct platform_device *pdev)
	struct platform_device *ion_pdev;
	struct platform_device *ion_pdev;
	struct cma *cma;
	struct cma *cma;
	uint32_t val;
	uint32_t val;
	int ret = 0;




	if (of_device_is_compatible(dev->of_node,
	if (of_device_is_compatible(dev->of_node,
@@ -3264,6 +3420,26 @@ static int fastrpc_probe(struct platform_device *pdev)
	}
	}
	me->legacy_remote_heap = of_property_read_bool(dev->of_node,
	me->legacy_remote_heap = of_property_read_bool(dev->of_node,
					"qcom,fastrpc-legacy-remote-heap");
					"qcom,fastrpc-legacy-remote-heap");
	if (of_property_read_bool(dev->of_node,
					"qcom,fastrpc-adsp-audio-pdr")) {
		int session;

		VERIFY(err, !fastrpc_get_adsp_session(
			AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
		if (err)
			goto spdbail;
		me->channel[0].spd[session].get_service_nb.notifier_call =
					fastrpc_get_service_location_notify;
		ret = get_service_location(
				AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
				AUDIO_PDR_ADSP_SERVICE_NAME,
				&me->channel[0].spd[session].get_service_nb);
		if (ret)
			pr_err("ADSPRPC: Get service location failed: %d\n",
								ret);
	}
spdbail:
	err = 0;
	VERIFY(err, !of_platform_populate(pdev->dev.of_node,
	VERIFY(err, !of_platform_populate(pdev->dev.of_node,
					  fastrpc_match_table,
					  fastrpc_match_table,
					  NULL, &pdev->dev));
					  NULL, &pdev->dev));