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

Commit e8b77a58 authored by Kalyan Thota's avatar Kalyan Thota
Browse files

msm: mdss: share MDP smmu device mappings with other mdss clients



Rotator and MDP share same stream ID on sdm600 target,
hence share the smmu device with rotator device to map/unmap
its buffers.

The change will also handle different secure usecase concurrencies
like, mdp running in secure and rotator in non-secure and vice versa.

Change-Id: I3ff118baed3984d63e9a9fe94289d99523c7b3e9
Signed-off-by: default avatarKalyan Thota <kalyant@codeaurora.org>
parent 741fc8ee
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -78,8 +78,6 @@ u32 sde_apply_comp_ratio_factor(u32 quota,
#define RES_UHD		(3840*2160)
#define RES_WQXGA		(2560*1600)
#define XIN_HALT_TIMEOUT_US	0x4000
#define MDSS_MDP_HW_REV_320	0x30020000  /* sdm660 */
#define MDSS_MDP_HW_REV_330	0x30030000  /* sdm630 */

static int sde_mdp_wait_for_xin_halt(u32 xin_id)
{
+7 −2
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@
#include "sde_rotator_smmu.h"
#include "sde_rotator_formats.h"

#define MDSS_MDP_HW_REV_320	0x30020000  /* sdm660 */
#define MDSS_MDP_HW_REV_330	0x30030000  /* sdm630 */

struct sde_mult_factor {
	uint32_t numer;
	uint32_t denom;
@@ -164,7 +167,9 @@ struct sde_rot_data_type {

	int iommu_attached;
	int iommu_ref_cnt;

	int (*iommu_ctrl)(int enable);
	int (*secure_session_ctrl)(int enable);
	int (*wait_for_transition)(int state, int request);
	struct sde_rot_vbif_debug_bus *nrt_vbif_dbg_bus;
	u32 nrt_vbif_dbg_bus_size;

@@ -173,7 +178,7 @@ struct sde_rot_data_type {

	void *sde_rot_hw;
	int sec_cam_en;

	bool callback_request;
	struct ion_client *iclient;
};

+34 −1
Original line number Diff line number Diff line
@@ -530,7 +530,7 @@ static int sde_rotator_import_buffer(struct sde_layer_buffer *buffer,
	return ret;
}

static int sde_rotator_secure_session_ctrl(bool enable)
static int _sde_rotator_secure_session_ctrl(bool enable)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
	uint32_t sid_info;
@@ -603,6 +603,39 @@ static int sde_rotator_secure_session_ctrl(bool enable)
	return resp;
}

static int sde_rotator_secure_session_ctrl(bool enable)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
	int ret = -EINVAL;

	/**
	  * wait_for_transition and secure_session_control are filled by client
	  * callback.
	  */
	if (mdata->wait_for_transition && mdata->secure_session_ctrl &&
		mdata->callback_request) {
		ret = mdata->wait_for_transition(mdata->sec_cam_en, enable);
		if (ret) {
			SDEROT_ERR("failed Secure wait for transition %d\n",
				   ret);
		} else {
			if (mdata->sec_cam_en ^ enable) {
				mdata->sec_cam_en = enable;
				ret = mdata->secure_session_ctrl(enable);
				if (ret)
					mdata->sec_cam_en = 0;
		    }
		}
	} else if (!mdata->callback_request) {
		ret = _sde_rotator_secure_session_ctrl(enable);
	}

	if (ret)
		SDEROT_ERR("failed %d sde_rotator_secure_session %d\n",
			   ret, mdata->callback_request);

	return ret;
}

static int sde_rotator_map_and_check_data(struct sde_rot_entry *entry)
{
+62 −7
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, 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
@@ -45,6 +45,15 @@ struct sde_smmu_domain {
	unsigned long size;
};

int sde_smmu_set_dma_direction(int dir)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();

	return ((mdata->mdss_version == MDSS_MDP_HW_REV_320) ||
	(mdata->mdss_version == MDSS_MDP_HW_REV_330)) ?
		DMA_BIDIRECTIONAL : dir;
}

static inline bool sde_smmu_is_valid_domain_type(
		struct sde_rot_data_type *mdata, int domain_type)
{
@@ -335,8 +344,8 @@ int sde_smmu_map_dma_buf(struct dma_buf *dma_buf,
		return -EINVAL;
	}

	rc = msm_dma_map_sg_lazy(sde_smmu->dev, table->sgl, table->nents, dir,
		dma_buf);
	rc = msm_dma_map_sg_lazy(sde_smmu->dev, table->sgl, table->nents,
		sde_smmu_set_dma_direction(dir), dma_buf);
	if (rc != table->nents) {
		SDEROT_ERR("dma map sg failed\n");
		return -ENOMEM;
@@ -357,13 +366,46 @@ void sde_smmu_unmap_dma_buf(struct sg_table *table, int domain,
		return;
	}

	msm_dma_unmap_sg(sde_smmu->dev, table->sgl, table->nents, dir,
		 dma_buf);
	msm_dma_unmap_sg(sde_smmu->dev, table->sgl, table->nents,
		sde_smmu_set_dma_direction(dir), dma_buf);
}

static DEFINE_MUTEX(sde_smmu_ref_cnt_lock);

static void sde_smmu_callback(struct mdss_smmu_intf *smmu)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();

	if (!smmu)
		return;

	/* Copy mmu device info into sde private structure */
	mdata->iommu_ctrl = smmu->iommu_ctrl;
	mdata->wait_for_transition = smmu->wait_for_transition;
	mdata->secure_session_ctrl = smmu->secure_session_ctrl;
	if (smmu->is_secure) {
		mdata->sde_smmu[SDE_IOMMU_DOMAIN_ROT_SECURE].dev = smmu->dev;
		mdata->sde_smmu[SDE_IOMMU_DOMAIN_ROT_SECURE].domain =
			SDE_IOMMU_DOMAIN_ROT_SECURE;
	} else {
		mdata->sde_smmu[SDE_IOMMU_DOMAIN_ROT_UNSECURE].dev = smmu->dev;
		mdata->sde_smmu[SDE_IOMMU_DOMAIN_ROT_UNSECURE].domain =
			SDE_IOMMU_DOMAIN_ROT_UNSECURE;
	}

	SDEROT_INFO("sde_smmu_callback registered domain: %d\n",
		    smmu->is_secure);
}

int sde_smmu_ctrl(int enable)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();

	return ((mdata->iommu_ctrl) ?
		mdata->iommu_ctrl(enable) : -EINVAL);
}

static int _sde_smmu_ctrl(int enable)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
	int rc = 0;
@@ -442,13 +484,24 @@ int sde_smmu_secure_ctrl(int enable)
void sde_smmu_device_create(struct device *dev)
{
	struct device_node *parent, *child;
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
	bool child_rot_sec = false;
	bool child_rot_nsec = false;

	parent = dev->of_node;
	for_each_child_of_node(parent, child) {
		if (of_device_is_compatible(child, SMMU_SDE_ROT_SEC))
		if (of_device_is_compatible(child, SMMU_SDE_ROT_SEC)) {
			of_platform_device_create(child, NULL, dev);
		else if (of_device_is_compatible(child, SMMU_SDE_ROT_UNSEC))
			child_rot_sec = true;
		} else if (of_device_is_compatible(child, SMMU_SDE_ROT_UNSEC)) {
			of_platform_device_create(child, NULL, dev);
			child_rot_nsec = true;
		}
	}

	if (!child_rot_sec || !child_rot_nsec) {
		mdss_smmu_request_mappings(sde_smmu_callback);
		mdata->callback_request = true;
	}
}

@@ -616,6 +669,8 @@ int sde_smmu_probe(struct platform_device *pdev)
	sde_smmu_enable_power(sde_smmu, false);

	sde_smmu->dev = dev;
	mdata->iommu_ctrl = _sde_smmu_ctrl;

	SDEROT_INFO(
		"iommu v2 domain[%d] mapping and clk register successful!\n",
			smmu_domain.domain);
+3 −6
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, 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
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/device.h>
#include <linux/dma-buf.h>
#include <linux/mdss_smmu_ext.h>

#include "sde_rotator_io_util.h"

@@ -28,11 +29,6 @@ enum sde_iommu_domain_type {

int sde_smmu_init(struct device *dev);

static inline int sde_smmu_dma_data_direction(int dir)
{
	return dir;
}

int sde_smmu_ctrl(int enable);

struct dma_buf_attachment *sde_smmu_dma_buf_attach(
@@ -47,4 +43,5 @@ void sde_smmu_unmap_dma_buf(struct sg_table *table, int domain,

int sde_smmu_secure_ctrl(int enable);

int sde_smmu_set_dma_direction(int dir);
#endif /* SDE_ROTATOR_SMMU_H */
Loading