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

Commit 6616a558 authored by Abhijit Kulkarni's avatar Abhijit Kulkarni Committed by Shubhashree Dhar
Browse files

drm/msm: enable support for custom power ioctl



This change adds support of msm_power_ctrl ioctl from msm display
driver. This ioctl is required to enable/disable display power
before/after accessing display core registers by clients.
TZ asynchronously accesses display domain registers without display
driver knowledge.This ioctl provides any such clients capability
to add/remove vote on display core clocks and power rail.

Change-Id: Ibf564ee3ad44884da55bf8a1e62f9d409ecf947b
Signed-off-by: default avatarAbhijit Kulkarni <kabhijit@codeaurora.org>
Signed-off-by: default avatarShubhashree Dhar <dhar@codeaurora.org>
parent c2262757
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#include "msm_gpu.h"
#include "msm_kms.h"
#include "sde_wb.h"
#include "sde_dbg.h"

/*
 * MSM driver version:
@@ -823,6 +824,8 @@ static int msm_open(struct drm_device *dev, struct drm_file *file)
	if (!ctx)
		return -ENOMEM;

	mutex_init(&ctx->power_lock);

	file->driver_priv = ctx;

	if (dev && dev->dev_private) {
@@ -859,6 +862,14 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
		priv->lastctx = NULL;
	mutex_unlock(&dev->struct_mutex);

	mutex_lock(&ctx->power_lock);
	if (ctx->enable_refcnt) {
		SDE_EVT32(ctx->enable_refcnt);
		sde_power_resource_enable(&priv->phandle,
				priv->pclient, false);
	}
	mutex_unlock(&ctx->power_lock);

	kfree(ctx);
}

@@ -1573,6 +1584,62 @@ int msm_ioctl_rmfb2(struct drm_device *dev, void *data,
}
EXPORT_SYMBOL(msm_ioctl_rmfb2);

/**
 * msm_ioctl_power_ctrl - enable/disable power vote on MDSS Hw
 * @dev: drm device for the ioctl
 * @data: data pointer for the ioctl
 * @file_priv: drm file for the ioctl call
 *
 */
static int msm_ioctl_power_ctrl(struct drm_device *dev, void *data,
			struct drm_file *file_priv)
{
	struct msm_file_private *ctx = file_priv->driver_priv;
	struct msm_drm_private *priv;
	struct drm_msm_power_ctrl *power_ctrl = data;
	bool vote_req = false;
	int old_cnt;
	int rc = 0;

	if (unlikely(!power_ctrl)) {
		DRM_ERROR("invalid ioctl data\n");
		return -EINVAL;
	}

	priv = dev->dev_private;

	mutex_lock(&ctx->power_lock);

	old_cnt = ctx->enable_refcnt;
	if (power_ctrl->enable) {
		if (!ctx->enable_refcnt)
			vote_req = true;
		ctx->enable_refcnt++;
	} else if (ctx->enable_refcnt) {
		ctx->enable_refcnt--;
		if (!ctx->enable_refcnt)
			vote_req = true;
	} else {
		pr_err("ignoring, unbalanced disable\n");
	}

	if (vote_req) {
		rc = sde_power_resource_enable(&priv->phandle,
				priv->pclient, power_ctrl->enable);

		if (rc)
			ctx->enable_refcnt = old_cnt;
	}

	pr_debug("pid %d enable %d, refcnt %d, vote_req %d\n",
			current->pid, power_ctrl->enable, ctx->enable_refcnt,
			vote_req);
	SDE_EVT32(current->pid, power_ctrl->enable, ctx->enable_refcnt,
			vote_req);
	mutex_unlock(&ctx->power_lock);
	return rc;
}

static const struct drm_ioctl_desc msm_ioctls[] = {
	DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,    msm_ioctl_get_param,    DRM_AUTH|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,      msm_ioctl_gem_new,      DRM_AUTH|DRM_RENDER_ALLOW),
@@ -1589,6 +1656,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
			  DRM_UNLOCKED|DRM_CONTROL_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_RMFB2, msm_ioctl_rmfb2,
			  DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF_DRV(MSM_POWER_CTRL, msm_ioctl_power_ctrl,
			DRM_RENDER_ALLOW),
};

static const struct vm_operations_struct vm_ops = {
+5 −5
Original line number Diff line number Diff line
@@ -74,11 +74,11 @@ struct msm_gem_vma;
#define TEARDOWN_DEADLOCK_RETRY_MAX 5

struct msm_file_private {
	/* currently we don't do anything useful with this.. but when
	 * per-context address spaces are supported we'd keep track of
	 * the context's page-tables here.
	 */
	int dummy;
	/* update the refcount when user driver calls power_ctrl IOCTL */
	unsigned short enable_refcnt;

	/* protects enable_refcnt */
	struct mutex power_lock;
};

enum msm_mdp_plane_property {
+13 −0
Original line number Diff line number Diff line
@@ -360,6 +360,16 @@ struct drm_msm_event_resp {
	__u8 data[];
};

/**
 * struct drm_msm_power_ctrl: Payload to enable/disable the power vote
 * @enable: enable/disable the power vote
 * @flags:  operation control flags, for future use
 */
struct drm_msm_power_ctrl {
	__u32 enable;
	__u32 flags;
};

#define DRM_MSM_GET_PARAM              0x00
/* placeholder:
#define DRM_MSM_SET_PARAM              0x01
@@ -376,6 +386,7 @@ struct drm_msm_event_resp {
#define DRM_MSM_REGISTER_EVENT         0x41
#define DRM_MSM_DEREGISTER_EVENT       0x42
#define DRM_MSM_RMFB2                  0x43
#define DRM_MSM_POWER_CTRL             0x44

/* sde custom events */
#define DRM_EVENT_HISTOGRAM 0x80000000
@@ -403,6 +414,8 @@ struct drm_msm_event_resp {
			DRM_MSM_DEREGISTER_EVENT), struct drm_msm_event_req)
#define DRM_IOCTL_MSM_RMFB2 DRM_IOW((DRM_COMMAND_BASE + \
			DRM_MSM_RMFB2), unsigned int)
#define DRM_IOCTL_MSM_POWER_CTRL DRM_IOW((DRM_COMMAND_BASE + \
			DRM_MSM_POWER_CTRL), struct drm_msm_power_ctrl)

#if defined(__cplusplus)
}