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

Commit 7c4a7413 authored by Pankaj Gupta's avatar Pankaj Gupta
Browse files

msm: kgsl: Support voting for CPU to GPU config path



Keeping a bus vote for CPU to GPU config path will make
sure that the required clocks are ON during the CPU
access. Keep a higher vote during wakeup to improve
GPU wakeup latency, keep higher vote during snapshot
also to improve register access latency. Keeping lower
vote after wakeup is good enough to make sure it is
running at minimum possible clock and voltage corner.

Change-Id: I9c9c86be6fff487874c94073b26fc2beb2063687
Signed-off-by: default avatarPrakash Kamliya <pkamliya@codeaurora.org>
Signed-off-by: default avatarPankaj Gupta <gpankaj@codeaurora.org>
parent 07c19948
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <linux/of_fdt.h>
#include <linux/module.h>
#include <linux/msm_kgsl.h>
#include <linux/msm-bus.h>
#include <linux/regulator/consumer.h>
#include <linux/nvmem-consumer.h>
#include <soc/qcom/scm.h>
@@ -1942,6 +1943,14 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	/* Clear any GPU faults that might have been left over */
	adreno_clear_gpu_fault(adreno_dev);

	/*
	 * Keep high bus vote to reduce AHB latency
	 * during FW loading and wakeup.
	 */
	if (device->pwrctrl.gpu_cfg)
		msm_bus_scale_client_update_request(device->pwrctrl.gpu_cfg,
			KGSL_GPU_CFG_PATH_HIGH);

	/* Put the GPU in a responsive state */
	status = kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
	if (status)
@@ -2160,6 +2169,15 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
		gmu_core_dev_oob_clear(device, oob_boot_slumber);

	/*
	 * Low vote is enough after wakeup completes, this will make
	 * sure CPU to GPU AHB infrastructure clocks are running at-least
	 * at minimum frequency.
	 */
	if (device->pwrctrl.gpu_cfg)
		msm_bus_scale_client_update_request(device->pwrctrl.gpu_cfg,
			KGSL_GPU_CFG_PATH_LOW);

	return 0;

error_oob_clear:
@@ -2180,6 +2198,9 @@ static int _adreno_start(struct adreno_device *adreno_dev)
		pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma,
				pmqos_active_vote);

	if (device->pwrctrl.gpu_cfg)
		msm_bus_scale_client_update_request(device->pwrctrl.gpu_cfg,
			KGSL_GPU_CFG_PATH_OFF);
	return status;
}

@@ -2288,6 +2309,10 @@ static int adreno_stop(struct kgsl_device *device)
	 */
	adreno_set_active_ctxs_null(adreno_dev);

	if (device->pwrctrl.gpu_cfg)
		msm_bus_scale_client_update_request(device->pwrctrl.gpu_cfg,
			KGSL_GPU_CFG_PATH_OFF);

	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);

	return error;
+13 −0
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/msm-bus.h>

#include "adreno.h"
#include "adreno_cp_parser.h"
#include "adreno_pm4types.h"
@@ -840,6 +842,14 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,

	snapshot_frozen_objsize = 0;

	/*
	 * We read lots of registers during GPU snapshot. Keep
	 * high bus vote to reduce AHB latency.
	 */
	if (device->pwrctrl.gpu_cfg)
		msm_bus_scale_client_update_request(device->pwrctrl.gpu_cfg,
			KGSL_GPU_CFG_PATH_HIGH);

	/* Add GPU specific sections - registers mainly, but other stuff too */
	if (gpudev->snapshot)
		gpudev->snapshot(adreno_dev, snapshot);
@@ -945,6 +955,9 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
			"GPU snapshot froze %zdKb of GPU buffers\n",
			snapshot_frozen_objsize / 1024);

	if (device->pwrctrl.gpu_cfg)
		msm_bus_scale_client_update_request(device->pwrctrl.gpu_cfg,
			KGSL_GPU_CFG_PATH_LOW);
}

/*
+32 −1
Original line number Diff line number Diff line
@@ -1959,6 +1959,14 @@ static inline void _close_pcl(struct kgsl_pwrctrl *pwr)
	pwr->pcl = 0;
}

static void _close_gpu_cfg(struct kgsl_pwrctrl *pwr)
{
	if (pwr->gpu_cfg)
		msm_bus_scale_unregister_client(pwr->gpu_cfg);

	pwr->gpu_cfg = 0;
}

static inline void _close_regulators(struct kgsl_pwrctrl *pwr)
{
	int i;
@@ -2032,7 +2040,9 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	int i, k, m, n = 0, result, freq;
	struct platform_device *pdev = device->pdev;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct device_node *gpu_cfg_node;
	struct msm_bus_scale_pdata *bus_scale_table;
	struct msm_bus_scale_pdata *gpu_cfg_table;
	struct device_node *gpubw_dev_node = NULL;
	struct platform_device *p2dev;

@@ -2109,6 +2119,23 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)

	pm_runtime_enable(&pdev->dev);

	gpu_cfg_node =
		of_find_node_by_name(device->pdev->dev.of_node,
			"qcom,cpu-to-gpu-cfg-path");
	if (gpu_cfg_node) {
		gpu_cfg_table =
			msm_bus_pdata_from_node(device->pdev, gpu_cfg_node);
		if (gpu_cfg_table)
			pwr->gpu_cfg =
				msm_bus_scale_register_client(gpu_cfg_table);

		if (!pwr->gpu_cfg) {
			result = -EINVAL;
			goto error_disable_pm;
		}
	}


	/* Check if gpu bandwidth vote device is defined in dts */
	if (pwr->bus_control)
		/* Check if gpu bandwidth vote device is defined in dts */
@@ -2133,7 +2160,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
		pwr->pcl = msm_bus_scale_register_client(bus_scale_table);
		if (pwr->pcl == 0) {
			result = -EINVAL;
			goto error_disable_pm;
			goto error_cleanup_gpu_cfg;
		}
	}

@@ -2201,6 +2228,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)

error_cleanup_pcl:
	_close_pcl(pwr);
error_cleanup_gpu_cfg:
	_close_gpu_cfg(pwr);
error_disable_pm:
	pm_runtime_disable(&pdev->dev);
error_cleanup_regulators:
@@ -2225,6 +2254,8 @@ void kgsl_pwrctrl_close(struct kgsl_device *device)

	_close_pcl(pwr);

	_close_gpu_cfg(pwr);

	pm_runtime_disable(&device->pdev->dev);

	_close_regulators(pwr);
+6 −0
Original line number Diff line number Diff line
@@ -18,6 +18,10 @@

#define KGSL_PWR_ON	0xFFFF

#define KGSL_GPU_CFG_PATH_OFF	0
#define KGSL_GPU_CFG_PATH_LOW	1
#define KGSL_GPU_CFG_PATH_HIGH	2

#define KGSL_MAX_CLKS 17
#define KGSL_MAX_REGULATORS 2

@@ -133,6 +137,7 @@ struct kgsl_regulator {
 * @clock_times - Each GPU frequency's accumulated active time in us
 * @regulators - array of pointers to kgsl_regulator structs
 * @pcl - bus scale identifier
 * @gpu_cfg - CPU to GPU AHB path bus scale identifier
 * @irq_name - resource name for the IRQ
 * @clk_stats - structure of clock statistics
 * @l2pc_cpus_mask - mask to avoid L2PC on masked CPUs
@@ -190,6 +195,7 @@ struct kgsl_pwrctrl {
	u64 clock_times[KGSL_MAX_PWRLEVELS];
	struct kgsl_regulator regulators[KGSL_MAX_REGULATORS];
	uint32_t pcl;
	uint32_t gpu_cfg;
	const char *irq_name;
	struct kgsl_clk_stats clk_stats;
	unsigned int l2pc_cpus_mask;