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

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

Merge "drm/msm: register for OPP notifications"

parents 401f8950 c3420135
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@
 * Copyright (C) 2011 Samsung Electronics
 *	MyungJoo Ham <myungjoo.ham@samsung.com>
 *
 * Copyright (c) 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 as
 * published by the Free Software Foundation.
@@ -25,9 +27,6 @@
#define DEVFREQ_GOV_SUSPEND			0x4
#define DEVFREQ_GOV_RESUME			0x5

/* Caution: devfreq->lock must be locked before calling update_devfreq */
extern int update_devfreq(struct devfreq *devfreq);

extern void devfreq_monitor_start(struct devfreq *devfreq);
extern void devfreq_monitor_stop(struct devfreq *devfreq);
extern void devfreq_monitor_suspend(struct devfreq *devfreq);
+51 −3
Original line number Diff line number Diff line
@@ -107,6 +107,44 @@ static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
	return 0;
}

static void msm_devfreq_manage_opp_notifier(struct device *dev,
	struct notifier_block *nb, bool subscribe)
{
	struct srcu_notifier_head *nh;

	rcu_read_lock();
	nh = dev_pm_opp_get_notifier(dev);
	if (IS_ERR(nh)) {
		rcu_read_unlock();
		return;
	}
	rcu_read_unlock();

	if (subscribe)
		srcu_notifier_chain_register(nh, nb);
	else
		srcu_notifier_chain_unregister(nh, nb);
}

static int msm_opp_notify(struct notifier_block *nb, unsigned long type,
		void *in_opp)
{
	struct msm_gpu *gpu = container_of(nb, struct msm_gpu, nb);

	if (type != OPP_EVENT_ENABLE && type != OPP_EVENT_DISABLE)
		return -EINVAL;

	/*
	 * The opp table for the GPU device changed, call update_devfreq()
	 * to adjust the GPU frequency if needed
	 */
	mutex_lock(&gpu->devfreq.devfreq->lock);
	update_devfreq(gpu->devfreq.devfreq);
	mutex_unlock(&gpu->devfreq.devfreq->lock);

	return 0;
}

static struct devfreq_dev_profile msm_devfreq_profile = {
	.polling_ms = 10,
	.target = msm_devfreq_target,
@@ -137,13 +175,22 @@ static void msm_devfreq_init(struct msm_gpu *gpu)
		return;
	}

	gpu->devfreq.cooling_dev = of_devfreq_cooling_register(
		dev->of_node, gpu->devfreq.devfreq);
	gpu->devfreq.cooling_dev = of_devfreq_cooling_register(dev->of_node,
			gpu->devfreq.devfreq);

	if (IS_ERR(gpu->devfreq.cooling_dev)) {
		dev_err(dev, "Couldn't register GPU devfreq cooling device\n");
		gpu->devfreq.cooling_dev = NULL;
		return;
	}

	gpu->nb.notifier_call = msm_opp_notify;

	/*
	 * register for OPP notifcations so we can adjust the
	 * GPU device power levels appropriately
	 */
	msm_devfreq_manage_opp_notifier(dev, &gpu->nb, true);
}

static int enable_pwrrail(struct msm_gpu *gpu)
@@ -1128,6 +1175,7 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
	WARN_ON(!list_empty(&gpu->active_list));

	if (gpu->devfreq.devfreq) {
		msm_devfreq_manage_opp_notifier(&pdev->dev, &gpu->nb, false);
		devfreq_cooling_unregister(gpu->devfreq.cooling_dev);
		devfreq_remove_device(gpu->devfreq.devfreq);
	}
+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/clk.h>
#include <linux/pm_qos.h>
#include <linux/regulator/consumer.h>
#include <linux/notifier.h>

#include "msm_drv.h"
#include "msm_ringbuffer.h"
@@ -156,6 +157,8 @@ struct msm_gpu {
		ktime_t time;
		struct thermal_cooling_device *cooling_dev;
	} devfreq;

	struct notifier_block nb;
};

struct msm_gpu_submitqueue {
+10 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
 * Copyright (C) 2011 Samsung Electronics
 *	MyungJoo Ham <myungjoo.ham@samsung.com>
 *
 * Copyright (c) 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 as
 * published by the Free Software Foundation.
@@ -201,6 +203,14 @@ extern void devm_devfreq_remove_device(struct device *dev,
extern int devfreq_suspend_device(struct devfreq *devfreq);
extern int devfreq_resume_device(struct devfreq *devfreq);

/**
 * update_devfreq() - Reevaluate the device and configure frequency
 * @devfreq:	the devfreq device
 *
 * Note: devfreq->lock must be held
 */
extern int update_devfreq(struct devfreq *devfreq);

/* Helper functions for devfreq user device driver with OPP. */
extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
					   unsigned long *freq, u32 flags);