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

Commit a3adae63 authored by Pranav Patel's avatar Pranav Patel
Browse files

msm: kgsl: Add GPU minimum bandwidth vote state



The GPU is usually clock gated when idle i.e NAP state.
Introduce a new state after NAP which lowers the GPU
bandwidth vote to minimum non-zero value so that memory
related components can run at a lower frequency corner,
if possible when GPU is idle.

Change-Id: Iee568e8c3039b35d6b58d7fc0fe72880eee2cace
Signed-off-by: default avatarPranav Patel <pranavp@codeaurora.org>
parent 4141c875
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1077,6 +1077,8 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
	/* Default timeout is 80 ms across all targets */
	device->pwrctrl.interval_timeout = msecs_to_jiffies(80);

	device->pwrctrl.minbw_timeout = 10;

	/* Set default bus control to true on all targets */
	device->pwrctrl.bus_control = true;

+2 −2
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ ssize_t adreno_coresight_show_register(struct device *dev,
		 */

		if (device->state == KGSL_STATE_ACTIVE ||
			device->state == KGSL_STATE_NAP) {
				kgsl_state_is_nap_or_minbw(device)) {
			if (!adreno_active_count_get(adreno_dev)) {
				if (!is_cx)
					kgsl_regread(device, cattr->reg->offset,
@@ -115,7 +115,7 @@ ssize_t adreno_coresight_store_register(struct device *dev,

	/* Program the hardware if it is not power collapsed */
	if (device->state == KGSL_STATE_ACTIVE ||
		device->state == KGSL_STATE_NAP) {
			kgsl_state_is_nap_or_minbw(device)) {
		if (!adreno_active_count_get(adreno_dev)) {
			if (!is_cx)
				kgsl_regwrite(device, cattr->reg->offset,
+12 −4
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@ static u32 _ab_buslevel_update(struct kgsl_pwrctrl *pwr,
}


int kgsl_bus_update(struct kgsl_device *device, bool on)
int kgsl_bus_update(struct kgsl_device *device,
			 enum kgsl_bus_vote vote_state)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	/* FIXME: this might be wrong? */
@@ -40,17 +41,24 @@ int kgsl_bus_update(struct kgsl_device *device, bool on)
	u32 ab;

	/* the bus should be ON to update the active frequency */
	if (on && !(test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)))
	if ((vote_state != KGSL_BUS_VOTE_OFF) &&
		!(test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)))
		return 0;
	/*
	 * If the bus should remain on calculate our request and submit it,
	 * otherwise request bus level 0, off.
	 */
	if (on) {
	if (vote_state == KGSL_BUS_VOTE_ON) {
		buslevel = min_t(int, pwr->pwrlevels[0].bus_max,
				cur + pwr->bus_mod);
		buslevel = max_t(int, buslevel, 1);
	} else {
	} else if (vote_state == KGSL_BUS_VOTE_MINIMUM) {
		/* Request bus level 1, minimum non-zero value */
		buslevel = 1;
		pwr->bus_mod = 0;
		pwr->bus_percent_ab = 0;
		pwr->bus_ab_mbytes = 0;
	} else if (vote_state == KGSL_BUS_VOTE_OFF) {
		/* If the bus is being turned off, reset to default level */
		pwr->bus_mod = 0;
		pwr->bus_percent_ab = 0;
+7 −1
Original line number Diff line number Diff line
@@ -6,12 +6,18 @@
#ifndef _KGSL_BUS_H
#define _KGSL_BUS_H

enum kgsl_bus_vote {
	KGSL_BUS_VOTE_OFF = 0,
	KGSL_BUS_VOTE_ON,
	KGSL_BUS_VOTE_MINIMUM,
};

struct kgsl_device;
struct platform_device;

int kgsl_bus_init(struct kgsl_device *device, struct platform_device *pdev);
void kgsl_bus_close(struct kgsl_device *device);
int kgsl_bus_update(struct kgsl_device *device, bool on);
int kgsl_bus_update(struct kgsl_device *device, enum kgsl_bus_vote vote_state);

u32 *kgsl_bus_get_table(struct platform_device *pdev,
		const char *name, int *count);
+12 −1
Original line number Diff line number Diff line
@@ -25,7 +25,8 @@
 * past its timer) and all system resources are released.  SUSPEND is	*
 * requested by the kernel and will be enforced upon all open devices.	*
 * RESET indicates that GPU or GMU hang happens. KGSL is handling	*
 * snapshot or recover GPU from hang.					*
 * snapshot or recover GPU from hang. MINBW implies that DDR BW vote is	*
 * set to non-zero minimum value.
 */

#define KGSL_STATE_NONE		0x00000000
@@ -35,6 +36,7 @@
#define KGSL_STATE_SUSPEND	0x00000010
#define KGSL_STATE_AWARE	0x00000020
#define KGSL_STATE_SLUMBER	0x00000080
#define KGSL_STATE_MINBW	0x00000100

/**
 * enum kgsl_event_results - result codes passed to an event callback when the
@@ -596,6 +598,15 @@ static inline int kgsl_state_is_awake(struct kgsl_device *device)
		return false;
}

static inline bool kgsl_state_is_nap_or_minbw(struct kgsl_device *device)
{
	if (device->state == KGSL_STATE_NAP ||
		device->state == KGSL_STATE_MINBW)
		return true;

	return false;
}

int kgsl_readtimestamp(struct kgsl_device *device, void *priv,
		enum kgsl_timestamp_type type, unsigned int *timestamp);

Loading