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

Commit 09fd506f authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Add kobject sysfs ops for the /sys/kernel/gpu directory"

parents 484e5344 88ff0b5e
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "kgsl_mmu.h"
#include "kgsl_pool.h"
#include "kgsl_sync.h"
#include "kgsl_sysfs.h"
#include "kgsl_trace.h"

#ifndef arch_mmap_check
@@ -4733,6 +4734,50 @@ static void _unregister_device(struct kgsl_device *device)
	mutex_unlock(&kgsl_driver.devlock);
}

/* sysfs_ops for the /sys/kernel/gpu kobject */
static ssize_t kgsl_gpu_sysfs_attr_show(struct kobject *kobj,
		struct attribute *__attr, char *buf)
{
	struct kgsl_gpu_sysfs_attr *attr = container_of(__attr,
		struct kgsl_gpu_sysfs_attr, attr);
	struct kgsl_device *device = container_of(kobj,
			struct kgsl_device, gpu_sysfs_kobj);

	if (attr->show)
		return attr->show(device, buf);

	return -EIO;
}

static ssize_t kgsl_gpu_sysfs_attr_store(struct kobject *kobj,
		struct attribute *__attr, const char *buf, size_t count)
{
	struct kgsl_gpu_sysfs_attr *attr = container_of(__attr,
		struct kgsl_gpu_sysfs_attr, attr);
	struct kgsl_device *device = container_of(kobj,
			struct kgsl_device, gpu_sysfs_kobj);

	if (attr->store)
		return attr->store(device, buf, count);

	return -EIO;
}

/* Dummy release function - we have nothing to do here */
static void kgsl_gpu_sysfs_release(struct kobject *kobj)
{
}

static const struct sysfs_ops kgsl_gpu_sysfs_ops = {
	.show = kgsl_gpu_sysfs_attr_show,
	.store = kgsl_gpu_sysfs_attr_store,
};

static struct kobj_type kgsl_gpu_sysfs_ktype = {
	.sysfs_ops = &kgsl_gpu_sysfs_ops,
	.release = kgsl_gpu_sysfs_release,
};

static int _register_device(struct kgsl_device *device)
{
	static u64 dma_mask = DMA_BIT_MASK(64);
@@ -4773,6 +4818,10 @@ static int _register_device(struct kgsl_device *device)

	device->dev->dma_mask = &dma_mask;
	set_dma_ops(device->dev, NULL);

	kobject_init_and_add(&device->gpu_sysfs_kobj, &kgsl_gpu_sysfs_ktype,
		kernel_kobj, "gpu");

	return 0;
}

@@ -4897,7 +4946,8 @@ void kgsl_device_platform_remove(struct kgsl_device *device)

	kgsl_device_snapshot_close(device);

	kobject_put(device->gpu_sysfs_kobj);
	if (device->gpu_sysfs_kobj.state_initialized)
		kobject_del(&device->gpu_sysfs_kobj);

	idr_destroy(&device->context_idr);

+1 −1
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ struct kgsl_device {

	/* Number of active contexts seen globally for this device */
	int active_context_count;
	struct kobject *gpu_sysfs_kobj;
	struct kobject gpu_sysfs_kobj;
	struct clk *l3_clk;
	unsigned int l3_freq[MAX_L3_LEVELS];
	unsigned int num_l3_pwrlevels;
+103 −44
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2010-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/of_device.h>
@@ -12,6 +12,7 @@
#include "kgsl_device.h"
#include "kgsl_bus.h"
#include "kgsl_pwrscale.h"
#include "kgsl_sysfs.h"
#include "kgsl_trace.h"

#define UPDATE_BUSY_VAL		1000000
@@ -824,10 +825,8 @@ static ssize_t popp_show(struct device *dev,
	return scnprintf(buf, PAGE_SIZE, "0\n");
}

static ssize_t gpu_model_show(struct device *dev,
			struct device_attribute *attr, char *buf)
static ssize_t _gpu_model_show(struct kgsl_device *device, char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);
	char model_str[32] = {0};

	device->ftbl->gpu_model(device, model_str, sizeof(model_str));
@@ -835,12 +834,18 @@ static ssize_t gpu_model_show(struct device *dev,
	return scnprintf(buf, PAGE_SIZE, "%s\n", model_str);
}

static ssize_t gpu_busy_percentage_show(struct device *dev,
					struct device_attribute *attr,
static ssize_t gpu_model_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _gpu_model_show(device, buf);
}

static ssize_t _gpu_busy_show(struct kgsl_device *device,
					char *buf)
{
	int ret;
	struct kgsl_device *device = dev_get_drvdata(dev);
	struct kgsl_clk_stats *stats = &device->pwrctrl.clk_stats;
	unsigned int busy_percent = 0;

@@ -857,22 +862,37 @@ static ssize_t gpu_busy_percentage_show(struct device *dev,
	return ret;
}

static ssize_t min_clock_mhz_show(struct device *dev,
static ssize_t gpu_busy_percentage_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _gpu_busy_show(device, buf);
}

static ssize_t _min_clock_mhz_show(struct kgsl_device *device,
					char *buf)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	return scnprintf(buf, PAGE_SIZE, "%d\n",
			pwr->pwrlevels[pwr->min_pwrlevel].gpu_freq / 1000000);
}

static ssize_t min_clock_mhz_store(struct device *dev,

static ssize_t min_clock_mhz_show(struct device *dev,
					struct device_attribute *attr,
				const char *buf, size_t count)
					char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _min_clock_mhz_show(device, buf);
}

static ssize_t _min_clock_mhz_store(struct kgsl_device *device,
				const char *buf, size_t count)
{
	int level, ret;
	unsigned int freq;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
@@ -890,21 +910,34 @@ static ssize_t min_clock_mhz_store(struct device *dev,
	return count;
}

static ssize_t max_clock_mhz_show(struct device *dev,
				struct device_attribute *attr, char *buf)
static ssize_t min_clock_mhz_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _min_clock_mhz_store(device, buf, count);
}

static ssize_t _max_clock_mhz_show(struct kgsl_device *device, char *buf)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	return scnprintf(buf, PAGE_SIZE, "%d\n",
		pwr->pwrlevels[pwr->thermal_pwrlevel].gpu_freq / 1000000);
}

static ssize_t max_clock_mhz_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
static ssize_t max_clock_mhz_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _max_clock_mhz_show(device, buf);
}

static ssize_t _max_clock_mhz_store(struct kgsl_device *device,
				const char *buf, size_t count)
{
	u32 freq;
	int ret, level;

@@ -924,20 +957,32 @@ static ssize_t max_clock_mhz_store(struct device *dev,
	return count;
}

static ssize_t clock_mhz_show(struct device *dev,
				struct device_attribute *attr, char *buf)
static ssize_t max_clock_mhz_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _max_clock_mhz_store(device, buf, count);
}

static ssize_t _clock_mhz_show(struct kgsl_device *device, char *buf)
{
	return scnprintf(buf, PAGE_SIZE, "%ld\n",
			kgsl_pwrctrl_active_freq(&device->pwrctrl) / 1000000);
}

static ssize_t freq_table_mhz_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
static ssize_t clock_mhz_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _clock_mhz_show(device, buf);
}

static ssize_t _freq_table_mhz_show(struct kgsl_device *device,
					char *buf)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	int index, num_chars = 0;

@@ -955,11 +1000,18 @@ static ssize_t freq_table_mhz_show(struct device *dev,
	return num_chars;
}

static ssize_t temp_show(struct device *dev,
static ssize_t freq_table_mhz_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _freq_table_mhz_show(device, buf);
}

static ssize_t _gpu_tmu_show(struct kgsl_device *device,
					char *buf)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct thermal_zone_device *thermal_dev;
	int ret, temperature = 0;
@@ -979,6 +1031,15 @@ static ssize_t temp_show(struct device *dev,
			temperature);
}

static ssize_t temp_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct kgsl_device *device = dev_get_drvdata(dev);

	return _gpu_tmu_show(device, buf);
}

static ssize_t pwrscale_store(struct device *dev,
			struct device_attribute *attr,
			const char *buf, size_t count)
@@ -1069,23 +1130,24 @@ static const struct attribute *pwrctrl_attr_list[] = {
	NULL,
};

static DEVICE_ATTR(gpu_busy, 0200, gpu_busy_percentage_show, NULL);
static DEVICE_ATTR(gpu_min_clock, 0644, min_clock_mhz_show,
		min_clock_mhz_store);
static DEVICE_ATTR(gpu_max_clock, 0644, max_clock_mhz_show,
		max_clock_mhz_store);
static DEVICE_ATTR(gpu_clock, 0200, clock_mhz_show, NULL);
static DEVICE_ATTR(gpu_freq_table, 0200, freq_table_mhz_show, NULL);
static DEVICE_ATTR(gpu_tmu, 0200, temp_show, NULL);

static const struct attribute *pwrctrl_gpu_attr_list[] = {
	&dev_attr_gpu_model.attr,
	&dev_attr_gpu_busy.attr,
	&dev_attr_gpu_min_clock.attr,
	&dev_attr_gpu_max_clock.attr,
	&dev_attr_gpu_clock.attr,
	&dev_attr_gpu_freq_table.attr,
	&dev_attr_gpu_tmu.attr,
static GPU_SYSFS_ATTR(gpu_model, 0200, _gpu_model_show, NULL);
static GPU_SYSFS_ATTR(gpu_busy, 0200, _gpu_busy_show, NULL);
static GPU_SYSFS_ATTR(gpu_min_clock, 0644, _min_clock_mhz_show,
		_min_clock_mhz_store);
static GPU_SYSFS_ATTR(gpu_max_clock, 0644, _max_clock_mhz_show,
		_max_clock_mhz_store);
static GPU_SYSFS_ATTR(gpu_clock, 0200, _clock_mhz_show, NULL);
static GPU_SYSFS_ATTR(gpu_freq_table, 0200, _freq_table_mhz_show, NULL);
static GPU_SYSFS_ATTR(gpu_tmu, 0200, _gpu_tmu_show, NULL);

static const struct attribute *gpu_sysfs_attr_list[] = {
	&gpu_sysfs_attr_gpu_model.attr,
	&gpu_sysfs_attr_gpu_busy.attr,
	&gpu_sysfs_attr_gpu_min_clock.attr,
	&gpu_sysfs_attr_gpu_max_clock.attr,
	&gpu_sysfs_attr_gpu_clock.attr,
	&gpu_sysfs_attr_gpu_freq_table.attr,
	&gpu_sysfs_attr_gpu_tmu.attr,
	NULL,
};

@@ -1097,13 +1159,10 @@ int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device)
	if (ret)
		return ret;

	device->gpu_sysfs_kobj = kobject_create_and_add("gpu", kernel_kobj);

	if (!device->gpu_sysfs_kobj)
	if (!device->gpu_sysfs_kobj.state_in_sysfs)
		return 0;

	return sysfs_create_files(device->gpu_sysfs_kobj,
		pwrctrl_gpu_attr_list);
	return sysfs_create_files(&device->gpu_sysfs_kobj, gpu_sysfs_attr_list);
}

/*
+2 −2
Original line number Diff line number Diff line
@@ -886,10 +886,10 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
			KGSL_GOVERNOR_CALL_INTERVAL);

	/* Add links to the devfreq sysfs nodes */
	kgsl_gpu_sysfs_add_link(device->gpu_sysfs_kobj,
	kgsl_gpu_sysfs_add_link(&device->gpu_sysfs_kobj,
			 &pwrscale->devfreqptr->dev.kobj, "governor",
			"gpu_governor");
	kgsl_gpu_sysfs_add_link(device->gpu_sysfs_kobj,
	kgsl_gpu_sysfs_add_link(&device->gpu_sysfs_kobj,
			 &pwrscale->devfreqptr->dev.kobj,
			"available_governors", "gpu_available_governor");

+31 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 */
#ifndef _KGSL_SYSFS_H_
#define _KGSL_SYSFS_H_

struct kgsl_device;

/**
 * struct kgsl_gpu_sysfs_attr - Attribute definition for sysfs objects in the
 * /sys/kernel/gpu kobject
 */
struct kgsl_gpu_sysfs_attr {
	/** @attr: Attribute for the sysfs node */
	struct attribute attr;
	/** @show: Show function for the node */
	ssize_t (*show)(struct kgsl_device *device, char *buf);
	/** @store: Store function for the node */
	ssize_t (*store)(struct kgsl_device *device, const char *buf,
			size_t count);
};

#define GPU_SYSFS_ATTR(_name, _mode, _show, _store)		\
struct kgsl_gpu_sysfs_attr gpu_sysfs_attr_##_name = {		\
	.attr = { .name = __stringify(_name), .mode = _mode },	\
	.show = _show,						\
	.store = _store,					\
}

#endif