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

Commit cf45c2a8 authored by Raviteja Tamatam's avatar Raviteja Tamatam Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: add PM QOS for rotator path



Added pm qos request when rotation session is present
for given cpu mask and latency based on dt property.

Change-Id: I42a35220e678e11ba1d63b0128c02df3ba45fab5
Signed-off-by: default avatarRaviteja Tamatam <travitej@codeaurora.org>
parent 2078a866
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -108,6 +108,10 @@ Optional properties
				<rd_lut, wr_lut> indicating the safe lut
				settings for the inline rotator sspp and
				writeback client.
- qcom,mdss-rot-qos-cpu-mask: A u32 value indicating desired PM QoS CPU
				affine mask.
- qcom,mdss-rot-qos-cpu-dma-latency: A u32 value indicating desired PM QoS CPU DMA
				latency in usec.
- qcom,mdss-rot-mode:		This is integer value indicates operation mode
				of the rotator device
- qcom,mdss-sbuf-headroom:	This integer value indicates stream buffer headroom in lines.
@@ -188,6 +192,9 @@ Example:
		qcom,mdss-rot-danger-lut = <0x0 0x0>;
		qcom,mdss-rot-safe-lut = <0x0000ffff 0x0>;

		qcom,mdss-rot-qos-cpu-mask = <0xf>;
		qcom,mdss-rot-qos-cpu-dma-latency = <75>;

		qcom,mdss-inline-rot-qos-lut = <0x0 0x0 0x00112233 0x44556677>;
		qcom,mdss-inline-rot-danger-lut = <0x0 0x0000ffff>;
		qcom,mdss-inline-rot-safe-lut = <0x0 0x0000ff00>;
+12 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012, 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012, 2015-2018, 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
@@ -31,6 +31,7 @@
#include "sde_rotator_util.h"
#include "sde_rotator_trace.h"
#include "sde_rotator_debug.h"
#include "sde_rotator_dev.h"

static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
{
@@ -707,6 +708,16 @@ static int sde_mdp_parse_dt_misc(struct platform_device *pdev,

	sde_mdp_parse_inline_rot_lut_setting(pdev, mdata);

	rc = of_property_read_u32(pdev->dev.of_node,
		"qcom,mdss-rot-qos-cpu-mask", &data);
	mdata->rot_pm_qos_cpu_mask = (!rc ? data : 0);

	rc = of_property_read_u32(pdev->dev.of_node,
		 "qcom,mdss-rot-qos-cpu-dma-latency", &data);
	mdata->rot_pm_qos_cpu_dma_latency = (!rc ? data : 0);

	sde_rotator_pm_qos_add(mdata);

	mdata->mdp_base = mdata->sde_io.base + SDE_MDP_OFFSET;

	return 0;
+6 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "sde_rotator_io_util.h"
#include "sde_rotator_smmu.h"
#include "sde_rotator_formats.h"
#include <linux/pm_qos.h>

/* HW Revisions for different targets */
#define SDE_GET_MAJOR_REV(rev)	((rev) >> 28)
@@ -243,6 +244,11 @@ struct sde_rot_data_type {
	u32 *vbif_nrt_qos;
	u32 npriority_lvl;

	struct pm_qos_request pm_qos_rot_cpu_req;
	u32 rot_pm_qos_cpu_count;
	u32 rot_pm_qos_cpu_mask;
	u32 rot_pm_qos_cpu_dma_latency;

	u32 vbif_memtype_count;
	u32 *vbif_memtype;

+110 −0
Original line number Diff line number Diff line
@@ -55,8 +55,15 @@
#define SDE_ROTATOR_DEGREE_180		180
#define SDE_ROTATOR_DEGREE_90		90

/* Inline rotator qos request */
#define SDE_ROTATOR_ADD_REQUEST		1
#define SDE_ROTATOR_REMOVE_REQUEST		0


static void sde_rotator_submit_handler(struct kthread_work *work);
static void sde_rotator_retire_handler(struct kthread_work *work);
static void sde_rotator_pm_qos_request(struct sde_rotator_device *rot_dev,
					 bool add_request);
#ifdef CONFIG_COMPAT
static long sde_rotator_compat_ioctl32(struct file *file,
	unsigned int cmd, unsigned long arg);
@@ -995,6 +1002,8 @@ struct sde_rotator_ctx *sde_rotator_ctx_open(
		SDEDEV_DBG(ctx->rot_dev->dev, "timeline is not available\n");

	sde_rot_mgr_lock(rot_dev->mgr);
	sde_rotator_pm_qos_request(rot_dev,
				 SDE_ROTATOR_ADD_REQUEST);
	ret = sde_rotator_session_open(rot_dev->mgr, &ctx->private,
			ctx->session_id, &ctx->work_queue);
	if (ret < 0) {
@@ -1104,6 +1113,8 @@ static int sde_rotator_ctx_release(struct sde_rotator_ctx *ctx,
	}
	SDEDEV_DBG(rot_dev->dev, "release session s:%d\n", session_id);
	sde_rot_mgr_lock(rot_dev->mgr);
	sde_rotator_pm_qos_request(rot_dev,
			SDE_ROTATOR_REMOVE_REQUEST);
	sde_rotator_session_close(rot_dev->mgr, ctx->private, session_id);
	sde_rot_mgr_unlock(rot_dev->mgr);
	SDEDEV_DBG(rot_dev->dev, "release retire work s:%d\n", session_id);
@@ -1213,6 +1224,104 @@ static bool sde_rotator_is_request_retired(struct sde_rotator_request *request)
	return retire_delta >= 0;
}

static void sde_rotator_pm_qos_remove(struct sde_rot_data_type *rot_mdata)
{
	struct pm_qos_request *req;
	u32 cpu_mask;

	if (!rot_mdata) {
		SDEROT_DBG("invalid rot device or context\n");
		return;
	}

	cpu_mask = rot_mdata->rot_pm_qos_cpu_mask;

	if (!cpu_mask)
		return;

	req = &rot_mdata->pm_qos_rot_cpu_req;
	pm_qos_remove_request(req);
}

void sde_rotator_pm_qos_add(struct sde_rot_data_type *rot_mdata)
{
	struct pm_qos_request *req;
	u32 cpu_mask;
	int cpu;

	if (!rot_mdata) {
		SDEROT_DBG("invalid rot device or context\n");
		return;
	}

	cpu_mask = rot_mdata->rot_pm_qos_cpu_mask;

	if (!cpu_mask)
		return;

	req = &rot_mdata->pm_qos_rot_cpu_req;
	req->type = PM_QOS_REQ_AFFINE_CORES;
	cpumask_empty(&req->cpus_affine);
	for_each_possible_cpu(cpu) {
		if ((1 << cpu) & cpu_mask)
			cpumask_set_cpu(cpu, &req->cpus_affine);
	}
	pm_qos_add_request(req, PM_QOS_CPU_DMA_LATENCY,
		PM_QOS_DEFAULT_VALUE);

	SDEROT_DBG("rotator pmqos add mask %x latency %x\n",
		rot_mdata->rot_pm_qos_cpu_mask,
		rot_mdata->rot_pm_qos_cpu_dma_latency);
}

static void sde_rotator_pm_qos_request(struct sde_rotator_device *rot_dev,
					 bool add_request)
{
	u32 cpu_mask;
	u32 cpu_dma_latency;
	bool changed = false;

	if (!rot_dev) {
		SDEROT_DBG("invalid rot device or context\n");
		return;
	}

	cpu_mask = rot_dev->mdata->rot_pm_qos_cpu_mask;
	cpu_dma_latency = rot_dev->mdata->rot_pm_qos_cpu_dma_latency;

	if (!cpu_mask)
		return;

	if (add_request) {
		if (rot_dev->mdata->rot_pm_qos_cpu_count == 0)
			changed = true;
		rot_dev->mdata->rot_pm_qos_cpu_count++;
	} else {
		if (rot_dev->mdata->rot_pm_qos_cpu_count != 0) {
			rot_dev->mdata->rot_pm_qos_cpu_count--;
			if (rot_dev->mdata->rot_pm_qos_cpu_count == 0)
				changed = true;
		} else {
			SDEROT_DBG("%s: ref_count is not balanced\n",
				__func__);
		}
	}

	if (!changed)
		return;

	SDEROT_EVTLOG(add_request, cpu_mask, cpu_dma_latency);

	if (!add_request) {
		pm_qos_update_request(&rot_dev->mdata->pm_qos_rot_cpu_req,
			PM_QOS_DEFAULT_VALUE);
		return;
	}

	pm_qos_update_request(&rot_dev->mdata->pm_qos_rot_cpu_req,
		cpu_dma_latency);
}

/*
 * sde_rotator_inline_open - open inline rotator session
 * @pdev: Pointer to rotator platform device
@@ -3528,6 +3637,7 @@ static int sde_rotator_remove(struct platform_device *pdev)
		return 0;
	}

	sde_rotator_pm_qos_remove(rot_dev->mdata);
	sde_rotator_destroy_debugfs(rot_dev->debugfs_root);
	video_unregister_device(rot_dev->vdev);
	video_device_release(rot_dev->vdev);
+3 −0
Original line number Diff line number Diff line
@@ -247,4 +247,7 @@ struct sde_rot_mgr *sde_rot_mgr_from_device(struct device *dev)
{
	return ((struct sde_rotator_device *) dev_get_drvdata(dev))->mgr;
}

void sde_rotator_pm_qos_add(struct sde_rot_data_type *rot_mdata);

#endif /* __SDE_ROTATOR_DEV_H__ */