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

Commit 0fea1bb7 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ARM: dts: msm: Add memshare for msm8996"

parents 8e4ebba9 4de16b42
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -2776,6 +2776,31 @@
		};
	};

	qcom,memshare {
		compatible = "qcom,memshare";

		qcom,client_1 {
			compatible = "qcom,memshare-peripheral";
			qcom,peripheral-size = <0x200000>;
			qcom,client-id = <0>;
			label = "modem";
		};

		qcom,client_2 {
			compatible = "qcom,memshare-peripheral";
			qcom,peripheral-size = <0x300000>;
			qcom,client-id = <2>;
			label = "modem";
		};

		qcom,client_3 {
			compatible = "qcom,memshare-peripheral";
			qcom,peripheral-size = <0x0>;
			qcom,client-id = <1>;
			label = "modem";
		};
	};

	qcom,msm-core@70000 {
		compatible = "qcom,apss-core-ea";
		reg = <0x70000 0x1000>;
+64 −10
Original line number Diff line number Diff line
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,8 @@
#include "msm_memshare.h"
#include "heap_mem_ext_v01.h"

#include <soc/qcom/secure_buffer.h>

/* Macros */
#define MEMSHARE_DEV_NAME "memshare"
#define MEMSHARE_CHILD_DEV_NAME "memshare_child"
@@ -144,14 +146,10 @@ static int check_client(int client_id, int proc, int request)

void free_client(int id)
{

	memblock[id].size = 0;
	memblock[id].phy_addr = 0;
	memblock[id].virtual_addr = 0;
	memblock[id].alloted = 0;
	memblock[id].client_id = DHMS_MEM_CLIENT_INVALID;
	memblock[id].guarantee = 0;
	memblock[id].peripheral = -1;
	memblock[id].sequence_id = -1;
	memblock[id].memory_type = MEMORY_CMA;

@@ -191,6 +189,7 @@ void initialize_client(void)
		memblock[i].sequence_id = -1;
		memblock[i].memory_type = MEMORY_CMA;
		memblock[i].free_memory = 0;
		memblock[i].hyp_mapping = 0;
	}
	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
}
@@ -199,6 +198,10 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
					void *_cmd)
{
	int i;
	int ret;
	u32 source_vmlist[2] = {VMID_HLOS, VMID_MSS_MSA};
	int dest_vmids[1] = {VMID_HLOS};
	int dest_perms[1] = {PERM_READ|PERM_WRITE};

	switch (code) {

@@ -222,8 +225,28 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
					DHMS_MEM_PROC_MPSS_V01 &&
					!memblock[i].guarantee &&
					memblock[i].alloted) {
					pr_err("memshare: Freeing memory for client id: %d\n",
					pr_debug("memshare: Freeing memory for client id: %d\n",
						memblock[i].client_id);
					ret = hyp_assign_phys(
							memblock[i].phy_addr,
							memblock[i].size,
							source_vmlist,
							2, dest_vmids,
							dest_perms, 1);
					if (ret &&
						memblock[i].hyp_mapping == 1) {
						/*
						 * This is an error case as hyp
						 * mapping was successful
						 * earlier but during unmap
						 * it lead to failure.
						 */
						pr_err("memshare: %s, failed to unmap the region\n",
							__func__);
						memblock[i].hyp_mapping = 1;
					} else {
						memblock[i].hyp_mapping = 0;
					}
					dma_free_attrs(memsh_drv->dev,
						memblock[i].size,
						memblock[i].virtual_addr,
@@ -248,6 +271,32 @@ static struct notifier_block nb = {
	.notifier_call = modem_notifier_cb,
};

static void shared_hyp_mapping(int client_id)
{
	int ret;
	u32 source_vmlist[1] = {VMID_HLOS};
	int dest_vmids[2] = {VMID_HLOS, VMID_MSS_MSA};
	int dest_perms[2] = {PERM_READ|PERM_WRITE,
				PERM_READ|PERM_WRITE};

	if (client_id == DHMS_MEM_CLIENT_INVALID) {
		pr_err("memshare: %s, Invalid Client\n", __func__);
		return;
	}

	ret = hyp_assign_phys(memblock[client_id].phy_addr,
			memblock[client_id].size,
			source_vmlist, 1, dest_vmids,
			dest_perms, 2);

	if (ret != 0) {
		pr_err("memshare: hyp_assign_phys failed size=%u err=%d\n",
				memblock[client_id].size, ret);
		return;
	}
	memblock[client_id].hyp_mapping = 1;
}

static int handle_alloc_req(void *req_h, void *req, void *conn_h)
{
	struct mem_alloc_req_msg_v01 *alloc_req;
@@ -341,9 +390,15 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h)
	memblock[client_id].sequence_id = alloc_req->sequence_id;

	fill_alloc_response(alloc_resp, client_id, &resp);

	/*
	 * Perform the Hypervisor mapping in order to avoid XPU viloation
	 * to the allocated region for Modem Clients
	 */
	if (!memblock[client_id].hyp_mapping &&
		memblock[client_id].alloted)
		shared_hyp_mapping(client_id);
	mutex_unlock(&memsh_drv->mem_share);
	pr_debug("alloc_resp.num_bytes :%d, alloc_resp.handle :%lx, alloc_resp.mem_req_result :%lx\n",
	pr_debug("memshare: alloc_resp.num_bytes :%d, alloc_resp.handle :%lx, alloc_resp.mem_req_result :%lx\n",
			  alloc_resp->dhms_mem_alloc_addr_info[0].num_bytes,
			  (unsigned long int)
			  alloc_resp->dhms_mem_alloc_addr_info[0].phy_addr,
@@ -355,7 +410,6 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h)
	if (rc < 0)
		pr_err("In %s, Error sending the alloc request: %d\n",
							__func__, rc);

	return rc;
}

@@ -405,7 +459,7 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h)
	memset(&free_resp, 0, sizeof(struct mem_free_generic_resp_msg_v01));
	free_resp.resp.error = QMI_ERR_INTERNAL_V01;
	free_resp.resp.result = QMI_RESULT_FAILURE_V01;
	pr_debug("Client id: %d proc id: %d\n", free_req->client_id,
	pr_debug("memshare: Client id: %d proc id: %d\n", free_req->client_id,
				free_req->proc_id);
	client_id = check_client(free_req->client_id, free_req->proc_id, FREE);
	if (client_id == DHMS_MEM_CLIENT_INVALID) {
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -49,6 +49,8 @@ struct mem_blocks {
	void *virtual_addr;
	/* Release memory only when XPU is released*/
	uint8_t free_memory;
	/* Need Hypervisor mapping*/
	uint8_t hyp_mapping;
};

int memshare_alloc(struct device *dev,