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

Commit 8cf3847e authored by Akhil P Oommen's avatar Akhil P Oommen
Browse files

msm: kgsl: Do GPU bus governor management



Currently, bus governor operations like devfreq update, suspend & resume
are done by the adreno_tz governor. Instead of that, do these bus governor
operations from the driver.

Change-Id: I13bf2405f05668346cbe0519a3d143addf75653f
Signed-off-by: default avatarAkhil P Oommen <akhilpo@codeaurora.org>
parent 3d41a999
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2019, 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
@@ -198,7 +198,7 @@ void kgsl_pwrscale_update(struct kgsl_device *device)
	device->pwrscale.next_governor_call = ktime_add_us(t,
			KGSL_GOVERNOR_CALL_INTERVAL);

	/* to call srcu_notifier_call_chain() from a kernel thread */
	/* to call update_devfreq() from a kernel thread */
	if (device->state != KGSL_STATE_SLUMBER)
		queue_work(device->pwrscale.devfreq_wq,
			&device->pwrscale.devfreq_notify_ws);
@@ -935,7 +935,6 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor)
	struct kgsl_pwrscale *pwrscale;
	struct kgsl_pwrctrl *pwr;
	struct devfreq *devfreq;
	struct devfreq *bus_devfreq;
	struct msm_adreno_extended_profile *gpu_profile;
	struct devfreq_dev_profile *profile;
	struct devfreq_msm_adreno_tz_data *data;
@@ -1039,17 +1038,16 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor)
	if (IS_ERR(pwrscale->cooling_dev))
		pwrscale->cooling_dev = NULL;

	pwrscale->gpu_profile.bus_devfreq = NULL;
	if (data->bus.num) {
		pwrscale->bus_profile.profile.max_state
					= pwr->num_pwrlevels - 1;
		pwrscale->bus_profile.profile.freq_table
					= pwrscale->freq_table;

		bus_devfreq = devfreq_add_device(device->busmondev,
		pwrscale->bus_devfreq = devfreq_add_device(device->busmondev,
			&pwrscale->bus_profile.profile, "gpubw_mon", NULL);
		if (!IS_ERR(bus_devfreq))
			pwrscale->gpu_profile.bus_devfreq = bus_devfreq;
		if (IS_ERR(pwrscale->bus_devfreq))
			pwrscale->bus_devfreq = NULL;
	}

	ret = sysfs_create_link(&device->dev->kobj,
@@ -1109,8 +1107,10 @@ void kgsl_pwrscale_close(struct kgsl_device *device)
	flush_workqueue(pwrscale->devfreq_wq);
	destroy_workqueue(pwrscale->devfreq_wq);
	devfreq_remove_device(device->pwrscale.devfreqptr);
	devfreq_remove_device(pwrscale->bus_devfreq);
	kfree(kgsl_midframe);
	kgsl_midframe = NULL;
	device->pwrscale.bus_devfreq = NULL;
	device->pwrscale.devfreqptr = NULL;
	srcu_cleanup_notifier_head(&device->pwrscale.nh);
	dev_pm_opp_unregister_notifier(&device->pdev->dev, &pwr->nb);
@@ -1123,18 +1123,18 @@ static void do_devfreq_suspend(struct work_struct *work)
{
	struct kgsl_pwrscale *pwrscale = container_of(work,
			struct kgsl_pwrscale, devfreq_suspend_ws);
	struct devfreq *devfreq = pwrscale->devfreqptr;

	devfreq_suspend_device(devfreq);
	devfreq_suspend_device(pwrscale->devfreqptr);
	devfreq_suspend_device(pwrscale->bus_devfreq);
}

static void do_devfreq_resume(struct work_struct *work)
{
	struct kgsl_pwrscale *pwrscale = container_of(work,
			struct kgsl_pwrscale, devfreq_resume_ws);
	struct devfreq *devfreq = pwrscale->devfreqptr;

	devfreq_resume_device(devfreq);
	devfreq_resume_device(pwrscale->devfreqptr);
	devfreq_resume_device(pwrscale->bus_devfreq);
}

static void do_devfreq_notify(struct work_struct *work)
@@ -1142,8 +1142,15 @@ static void do_devfreq_notify(struct work_struct *work)
	struct kgsl_pwrscale *pwrscale = container_of(work,
			struct kgsl_pwrscale, devfreq_notify_ws);
	struct devfreq *devfreq = pwrscale->devfreqptr;
	struct devfreq *bus_devfreq = pwrscale->bus_devfreq;

	srcu_notifier_call_chain(&pwrscale->nh,
				 ADRENO_DEVFREQ_NOTIFY_RETIRE,
				 devfreq);
	mutex_lock(&devfreq->lock);
	update_devfreq(devfreq);
	mutex_unlock(&devfreq->lock);

	if (bus_devfreq) {
		mutex_lock(&bus_devfreq->lock);
		update_devfreq(bus_devfreq);
		mutex_unlock(&bus_devfreq->lock);
	}
}
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2019, 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
@@ -71,6 +71,7 @@ struct kgsl_pwr_history {
/**
 * struct kgsl_pwrscale - Power scaling settings for a KGSL device
 * @devfreqptr - Pointer to the devfreq device
 * @bus_devfreq - Pointer to the bus devfreq device
 * @gpu_profile - GPU profile data for the devfreq device
 * @bus_profile - Bus specific data for the bus devfreq device
 * @freq_table - GPU frequencies for the DCVS algorithm
@@ -99,6 +100,7 @@ struct kgsl_pwr_history {
 */
struct kgsl_pwrscale {
	struct devfreq *devfreqptr;
	struct devfreq *bus_devfreq;
	struct msm_adreno_extended_profile gpu_profile;
	struct msm_busmon_extended_profile bus_profile;
	unsigned long freq_table[KGSL_MAX_PWRLEVELS];