gpu: host1x: Add actmon registration interface

Provide the actmon registration interface for host1x clients. The
registration process will create the debugfs for the actmon associated
with the host1x client, and initialize the actmon registers.

Bug 3788919

Signed-off-by: Johnny Liu <johnliu@nvidia.com>
Change-Id: I313bf52a5eda1663e26c2579788a873ca4081459
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2886696
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Johnny Liu
2023-04-12 09:20:00 +00:00
committed by mobile promotions
parent d99906cfaa
commit fa8cf02e87
7 changed files with 559 additions and 4 deletions

View File

@@ -1,11 +1,412 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Tegra host1x activity monitor interfaes
* Tegra host1x activity monitor interfaces
*
* Copyright (c) 2023, NVIDIA Corporation.
* Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/host1x-next.h>
#include "dev.h"
#include "actmon.h"
#include "hw/actmon.h"
static void actmon_writel(struct host1x_actmon *actmon, u32 val, u32 offset)
{
writel(val, actmon->regs+offset);
}
static u32 actmon_readl(struct host1x_actmon *actmon, u32 offset)
{
return readl(actmon->regs+offset);
}
static void actmon_module_writel(struct host1x_actmon_module *module, u32 val, u32 offset)
{
writel(val, module->regs+offset);
}
static u32 actmon_module_readl(struct host1x_actmon_module *module, u32 offset)
{
return readl(module->regs+offset);
}
static void host1x_actmon_update_sample_period(struct host1x_actmon *actmon)
{
unsigned long actmon_mhz;
u32 actmon_clks_per_sample, sample_period, val = 0;
actmon_mhz = actmon->rate / 1000000;
actmon_clks_per_sample = actmon_mhz * actmon->usecs_per_sample;
val |= HOST1X_ACTMON_CTRL_SOURCE(2);
if (actmon_clks_per_sample > 65536) {
val |= HOST1X_ACTMON_CTRL_SAMPLE_TICK(1);
sample_period = actmon_clks_per_sample / 65536;
} else {
val &= ~HOST1X_ACTMON_CTRL_SAMPLE_TICK(1);
sample_period = actmon_clks_per_sample / 256;
}
val &= ~HOST1X_ACTMON_CTRL_SAMPLE_PERIOD_MASK;
val |= HOST1X_ACTMON_CTRL_SAMPLE_PERIOD(sample_period);
actmon_writel(actmon, val, HOST1X_ACTMON_CTRL_REG);
}
static int host1x_actmon_sample_period_get(void *data, u64 *val)
{
struct host1x_actmon *actmon = (struct host1x_actmon *)data;
*val = (u64) actmon->usecs_per_sample;
return 0;
}
static int host1x_actmon_sample_period_set(void *data, u64 val)
{
struct host1x_actmon *actmon = (struct host1x_actmon *)data;
actmon->usecs_per_sample = (u32)val;
host1x_actmon_update_sample_period(actmon);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(host1x_actmon_sample_period_fops,
host1x_actmon_sample_period_get,
host1x_actmon_sample_period_set,
"%lld\n");
static void host1x_actmon_debug_init(struct host1x_actmon *actmon)
{
struct host1x *host = dev_get_drvdata(actmon->client->host->parent);
struct dentry *debugfs = host->actmon_debugfs;
if (!debugfs)
return;
actmon->debugfs = debugfs_create_dir(actmon->name, debugfs);
/* R/W files */
debugfs_create_file("sample_period", 0644, actmon->debugfs, actmon,
&host1x_actmon_sample_period_fops);
}
static int host1x_actmon_module_k_get(void *data, u64 *val)
{
struct host1x_actmon_module *module = (struct host1x_actmon_module *)data;
*val = (u64) module->k;
return 0;
}
static int host1x_actmon_module_k_set(void *data, u64 val)
{
struct host1x_actmon_module *module = (struct host1x_actmon_module *)data;
u32 val32;
module->k = (u32)val;
val32 = actmon_module_readl(module, HOST1X_ACTMON_MODULE_CTRL_REG);
val32 &= ~HOST1X_ACTMON_MODULE_CTRL_K_VAL_MASK;
val32 |= HOST1X_ACTMON_MODULE_CTRL_K_VAL(module->k);
actmon_module_writel(module, val32, HOST1X_ACTMON_MODULE_CTRL_REG);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(host1x_actmon_module_k_fops,
host1x_actmon_module_k_get,
host1x_actmon_module_k_set,
"%lld\n");
static int host1x_actmon_module_consec_upper_num_get(void *data, u64 *val)
{
struct host1x_actmon_module *module = (struct host1x_actmon_module *)data;
*val = (u64) module->consec_upper_num;
return 0;
}
static int host1x_actmon_module_consec_upper_num_set(void *data, u64 val)
{
struct host1x_actmon_module *module = (struct host1x_actmon_module *)data;
u32 val32;
module->consec_upper_num = (u32)val;
val32 = actmon_module_readl(module, HOST1X_ACTMON_MODULE_CTRL_REG);
val32 &= ~HOST1X_ACTMON_MODULE_CTRL_CONSEC_UPPER_NUM_MASK;
val32 |= HOST1X_ACTMON_MODULE_CTRL_CONSEC_UPPER_NUM(module->consec_upper_num);
actmon_module_writel(module, val32, HOST1X_ACTMON_MODULE_CTRL_REG);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(host1x_actmon_module_consec_upper_num_fops,
host1x_actmon_module_consec_upper_num_get,
host1x_actmon_module_consec_upper_num_set,
"%lld\n");
static int host1x_actmon_module_consec_lower_num_get(void *data, u64 *val)
{
struct host1x_actmon_module *module = (struct host1x_actmon_module *)data;
*val = (u64) module->consec_lower_num;
return 0;
}
static int host1x_actmon_module_consec_lower_num_set(void *data, u64 val)
{
struct host1x_actmon_module *module = (struct host1x_actmon_module *)data;
u32 val32;
module->consec_lower_num = (u32)val;
val32 = actmon_module_readl(module, HOST1X_ACTMON_MODULE_CTRL_REG);
val32 &= ~HOST1X_ACTMON_MODULE_CTRL_CONSEC_LOWER_NUM_MASK;
val32 |= HOST1X_ACTMON_MODULE_CTRL_CONSEC_LOWER_NUM(module->consec_lower_num);
actmon_module_writel(module, val32, HOST1X_ACTMON_MODULE_CTRL_REG);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(host1x_actmon_module_consec_lower_num_fops,
host1x_actmon_module_consec_lower_num_get,
host1x_actmon_module_consec_lower_num_set,
"%lld\n");
static int host1x_actmon_module_avg_norm_get(void *data, u64 *val)
{
struct host1x_actmon_module *module = (struct host1x_actmon_module *)data;
struct host1x_actmon *actmon = module->actmon;
struct host1x_client *client = actmon->client;
unsigned long client_freq;
u32 active_clks, client_clks;
active_clks = actmon_module_readl(module, HOST1X_ACTMON_MODULE_AVG_COUNT_REG);
client_freq = client->ops->get_rate(client);
client_clks = ((client_freq / 1000) * actmon->usecs_per_sample) / 1000;
*val = (u64) (active_clks * 1000) / client_clks;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(host1x_actmon_module_avg_norm_fops,
host1x_actmon_module_avg_norm_get, NULL,
"%lld\n");
static void host1x_actmon_module_debug_init(struct host1x_actmon_module *module)
{
struct dentry *debugfs = module->actmon->debugfs;
char dirname[8];
if (!debugfs)
return;
snprintf(dirname, sizeof(dirname), "module%d", module->type);
module->debugfs = debugfs_create_dir(dirname, debugfs);
/* R/W files */
debugfs_create_file("k", 0644, module->debugfs, module,
&host1x_actmon_module_k_fops);
debugfs_create_file("consec_upper_num", 0644, module->debugfs, module,
&host1x_actmon_module_consec_upper_num_fops);
debugfs_create_file("consec_lower_num", 0644, module->debugfs, module,
&host1x_actmon_module_consec_lower_num_fops);
/* R files */
debugfs_create_file("usage", 0444, module->debugfs, module,
&host1x_actmon_module_avg_norm_fops);
}
static void host1x_actmon_init(struct host1x_actmon *actmon)
{
u32 val;
/* Global control register */
host1x_actmon_update_sample_period(actmon);
/* Global interrupt enable register */
val = (1 << actmon->num_modules) - 1;
actmon_writel(actmon, val, HOST1X_ACTMON_INTR_ENB_REG);
}
static void host1x_actmon_deinit(struct host1x_actmon *actmon)
{
actmon_writel(actmon, 0, HOST1X_ACTMON_CTRL_REG);
actmon_writel(actmon, 0, HOST1X_ACTMON_INTR_ENB_REG);
}
static void host1x_actmon_module_init(struct host1x_actmon_module *module)
{
struct host1x_actmon *actmon = module->actmon;
u32 val;
/* Local control register */
val = 0;
val |= HOST1X_ACTMON_MODULE_CTRL_ACTMON_ENB(1);
val |= HOST1X_ACTMON_MODULE_CTRL_ENB_PERIODIC(1);
val |= HOST1X_ACTMON_MODULE_CTRL_K_VAL(module->k);
val |= HOST1X_ACTMON_MODULE_CTRL_CONSEC_UPPER_NUM(module->consec_upper_num);
val |= HOST1X_ACTMON_MODULE_CTRL_CONSEC_LOWER_NUM(module->consec_lower_num);
actmon_module_writel(module, val, HOST1X_ACTMON_MODULE_CTRL_REG);
/* Interrupt enable register */
val = 0;
val |= HOST1X_ACTMON_MODULE_INTR_AVG_BELOW_WORK_ENB(1);
val |= HOST1X_ACTMON_MODULE_INTR_AVG_ABOVE_WORK_ENB(1);
val |= HOST1X_ACTMON_MODULE_INTR_CONSEC_BELOW_WORK_ENB(1);
val |= HOST1X_ACTMON_MODULE_INTR_CONSEC_ABOVE_WORK_ENB(1);
actmon_module_writel(module, val, HOST1X_ACTMON_MODULE_INTR_ENB_REG);
/* Interrupt status register */
actmon_module_writel(module, 0xffffffff, HOST1X_ACTMON_MODULE_INTR_STATUS_REG);
/* Consecutive watermark registers */
actmon_module_writel(module, 0xffffffff, HOST1X_ACTMON_MODULE_UPPER_WMARK_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_LOWER_WMARK_REG);
/* Moving-average watermark registers */
actmon_module_writel(module, 0xffffffff, HOST1X_ACTMON_MODULE_AVG_UPPER_WMARK_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_AVG_LOWER_WMARK_REG);
/* Init average value register */
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_INIT_AVG_REG);
}
static void host1x_actmon_module_deinit(struct host1x_actmon_module *module)
{
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_CTRL_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_INTR_ENB_REG);
actmon_module_writel(module, 0xffffffff, HOST1X_ACTMON_MODULE_INTR_STATUS_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_UPPER_WMARK_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_LOWER_WMARK_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_AVG_UPPER_WMARK_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_AVG_LOWER_WMARK_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_INIT_AVG_REG);
actmon_module_writel(module, 0, HOST1X_ACTMON_MODULE_COUNT_WEIGHT_REG);
}
int host1x_actmon_register(struct host1x_client *client)
{
struct host1x *host = dev_get_drvdata(client->host->parent);
struct host1x_info *info = host->info;
struct host1x_actmon_entry *entry = NULL;
struct host1x_actmon_module *module;
struct host1x_actmon *actmon;
int i, err;
if (!host->actmon_regs || !host->actmon_clk)
return -ENODEV;
for (i = 0; i < info->num_actmon_entries; i++) {
if (info->actmon_table[i].classid == client->class)
entry = &info->actmon_table[i];
}
if (!entry)
return -ENODEV;
actmon = devm_kzalloc(client->dev, sizeof(*actmon), GFP_KERNEL);
if (!actmon)
return -ENOMEM;
actmon->client = client;
actmon->rate = clk_get_rate(host->actmon_clk);
actmon->regs = host->actmon_regs + entry->offset;
actmon->irq = entry->irq;
actmon->name = entry->name;
actmon->num_modules = entry->num_modules;
actmon->usecs_per_sample = 1500;
/* Configure actmon registers */
host1x_actmon_init(actmon);
/* Create debugfs for the actmon */
host1x_actmon_debug_init(actmon);
/* Configure actmon module registers */
for (i = 0; i < actmon->num_modules; i++) {
module = &actmon->modules[i];
module->actmon = actmon;
module->type = i;
module->regs = actmon->regs + (i * HOST1X_ACTMON_MODULE_OFFSET);
module->k = 6;
module->consec_upper_num = 7;
module->consec_lower_num = 7;
host1x_actmon_module_init(module);
/* Create debugfs for the actmon module */
host1x_actmon_module_debug_init(module);
}
client->actmon = actmon;
return 0;
}
EXPORT_SYMBOL(host1x_actmon_register);
int host1x_actmon_unregister(struct host1x_client *client)
{
struct host1x_actmon_module *module;
struct host1x *host = dev_get_drvdata(client->host->parent);
struct host1x_actmon *actmon = client->actmon;
int i;
if (!host->actmon_regs || !host->actmon_clk)
return 0;
if (!actmon)
return 0;
for (i = 0; i < actmon->num_modules; i++) {
module = &actmon->modules[i];
host1x_actmon_module_deinit(module);
debugfs_remove_recursive(module->debugfs);
}
debugfs_remove_recursive(actmon->debugfs);
host1x_actmon_deinit(actmon);
return 0;
}
EXPORT_SYMBOL(host1x_actmon_unregister);
void host1x_actmon_update_client_rate(struct host1x_client *client,
unsigned long rate,
u32 *weight)
{
struct host1x_actmon *actmon = client->actmon;
struct host1x_actmon_module *module;
u32 val;
int i;
if (!actmon) {
*weight = 0;
return;
}
val = (rate / actmon->rate) << 2;
for (i = 0; i < actmon->num_modules; i++) {
module = &actmon->modules[i];
actmon_module_writel(module, val, HOST1X_ACTMON_MODULE_COUNT_WEIGHT_REG);
}
*weight = val;
}
EXPORT_SYMBOL(host1x_actmon_update_client_rate);
int host1x_actmon_read_avg_count(struct host1x_client *client)
{

View File

@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Tegra host1x Actmon
*
* Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#ifndef HOST1X_ACTMON_H
#define HOST1X_ACTMON_H
#include <linux/device.h>
#include <linux/types.h>
enum host1x_actmon_module_type {
HOST1X_ACTMON_MODULE_ACTIVE,
HOST1X_ACTMON_MODULE_STALL,
};
struct host1x_actmon;
struct host1x_actmon_module {
enum host1x_actmon_module_type type;
u32 k;
u32 consec_upper_num;
u32 consec_lower_num;
void __iomem *regs;
struct host1x_actmon *actmon;
struct dentry *debugfs;
};
struct host1x_client;
struct host1x_actmon {
char *name;
unsigned int irq;
unsigned int num_modules;
unsigned long rate;
u32 usecs_per_sample;
void __iomem *regs;
struct host1x_client *client;
struct host1x_actmon_module modules[8];
struct dentry *debugfs;
};
#endif

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com>
*
* Copyright (C) 2011-2013 NVIDIA Corporation
* Copyright (C) 2011-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/debugfs.h>
@@ -196,6 +196,8 @@ static void host1x_debugfs_init(struct host1x *host1x)
/* Store the created entry */
host1x->debugfs = de;
host1x->actmon_debugfs = debugfs_create_dir("actmon", host1x->debugfs);
debugfs_create_file("status", S_IRUGO, de, host1x, &host1x_debug_fops);
debugfs_create_file("status_all", S_IRUGO, de, host1x,
&host1x_debug_all_fops);

View File

@@ -432,6 +432,44 @@ static const struct host1x_sid_entry tegra234_sid_table[] = {
},
};
static const struct host1x_actmon_entry tegra234_actmon_table[] = {
{
.classid = HOST1X_CLASS_NVENC,
.name = "nvenc",
.irq = 2,
.offset = 0x00000,
.num_modules = 1,
},
{
.classid = HOST1X_CLASS_VIC,
.name = "vic",
.irq = 3,
.offset = 0x10000,
.num_modules = 1,
},
{
.classid = HOST1X_CLASS_NVDEC,
.name = "nvdec",
.irq = 4,
.offset = 0x20000,
.num_modules = 1,
},
{
.classid = HOST1X_CLASS_NVJPG,
.name = "nvjpg",
.irq = 5,
.offset = 0x30000,
.num_modules = 1,
},
{
.classid = HOST1X_CLASS_NVJPG1,
.name = "nvjpg1",
.irq = 6,
.offset = 0x40000,
.num_modules = 1,
},
};
static const struct host1x_info host1x08_info = {
.nb_channels = 63,
.nb_pts = 1024,
@@ -445,6 +483,8 @@ static const struct host1x_info host1x08_info = {
.has_common = true,
.num_sid_entries = ARRAY_SIZE(tegra234_sid_table),
.sid_table = tegra234_sid_table,
.num_actmon_entries = ARRAY_SIZE(tegra234_actmon_table),
.actmon_table = tegra234_actmon_table,
.streamid_vm_table = { 0x1004, 128 },
.classid_vm_table = { 0x1404, 25 },
.mmio_vm_table = { 0x1504, 25 },

View File

@@ -83,6 +83,14 @@ struct host1x_intr_ops {
int (*free_syncpt_irq)(struct host1x *host);
};
struct host1x_actmon_entry {
int classid;
const char *name;
unsigned int irq;
unsigned int offset;
unsigned int num_modules;
};
struct host1x_sid_entry {
unsigned int base;
unsigned int offset;
@@ -107,6 +115,8 @@ struct host1x_info {
bool has_common; /* has common registers separate from hypervisor */
unsigned int num_sid_entries;
const struct host1x_sid_entry *sid_table;
unsigned int num_actmon_entries;
const struct host1x_actmon_entry *actmon_table;
struct host1x_table_desc streamid_vm_table;
struct host1x_table_desc classid_vm_table;
struct host1x_table_desc mmio_vm_table;
@@ -170,6 +180,7 @@ struct host1x {
struct host1x_memory_context_list context_list;
struct dentry *debugfs;
struct dentry *actmon_debugfs;
struct mutex devices_lock;
struct list_head devices;

View File

@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Tegra host1x Actmon Register Offsets
*
* Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#ifndef __HOST1X_ACTMON_HARDWARE_H
#define __HOST1X_ACTMON_HARDWARE_H
#define HOST1X_ACTMON_MODULE_OFFSET 0x80
#define HOST1X_ACTMON_CTRL_REG 0x0
#define HOST1X_ACTMON_INTR_ENB_REG 0x4
#define HOST1X_ACTMON_MODULE_INIT_AVG_REG 0x14
#define HOST1X_ACTMON_MODULE_CTRL_REG 0x80
#define HOST1X_ACTMON_MODULE_INTR_ENB_REG 0x84
#define HOST1X_ACTMON_MODULE_INTR_STATUS_REG 0x88
#define HOST1X_ACTMON_MODULE_UPPER_WMARK_REG 0x8c
#define HOST1X_ACTMON_MODULE_LOWER_WMARK_REG 0x90
#define HOST1X_ACTMON_MODULE_AVG_UPPER_WMARK_REG 0x94
#define HOST1X_ACTMON_MODULE_AVG_LOWER_WMARK_REG 0x98
#define HOST1X_ACTMON_MODULE_AVG_COUNT_REG 0xa4
#define HOST1X_ACTMON_MODULE_COUNT_WEIGHT_REG 0xa8
#define HOST1X_ACTMON_CTRL_SOURCE(v) ((v & 0x3) << 8)
#define HOST1X_ACTMON_CTRL_SAMPLE_TICK(v) ((v & 0x1) << 10)
#define HOST1X_ACTMON_CTRL_SAMPLE_PERIOD(v) ((v & 0xff) << 0)
#define HOST1X_ACTMON_MODULE_CTRL_ACTMON_ENB(v) ((v & 0x1) << 31)
#define HOST1X_ACTMON_MODULE_CTRL_CONSEC_UPPER_NUM(v) ((v & 0x7) << 26)
#define HOST1X_ACTMON_MODULE_CTRL_CONSEC_LOWER_NUM(v) ((v & 0x7) << 21)
#define HOST1X_ACTMON_MODULE_CTRL_ENB_PERIODIC(v) ((v & 0x1) << 13)
#define HOST1X_ACTMON_MODULE_CTRL_K_VAL(v) ((v & 0x7) << 10)
#define HOST1X_ACTMON_MODULE_INTR_CONSEC_ABOVE_WORK_ENB(v) ((v & 0x1) << 31)
#define HOST1X_ACTMON_MODULE_INTR_CONSEC_BELOW_WORK_ENB(v) ((v & 0x1) << 30)
#define HOST1X_ACTMON_MODULE_INTR_AVG_ABOVE_WORK_ENB(v) ((v & 0x1) << 29)
#define HOST1X_ACTMON_MODULE_INTR_AVG_BELOW_WORK_ENB(v) ((v & 0x1) << 28)
#define HOST1X_ACTMON_CTRL_SAMPLE_PERIOD_MASK 0xff
#define HOST1X_ACTMON_MODULE_CTRL_CONSEC_UPPER_NUM_MASK (0x7 << 26)
#define HOST1X_ACTMON_MODULE_CTRL_CONSEC_LOWER_NUM_MASK (0x7 << 21)
#define HOST1X_ACTMON_MODULE_CTRL_K_VAL_MASK (0x7 << 10)
#endif

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2009-2013, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2009-2023, NVIDIA Corporation. All rights reserved.
*/
#ifndef __LINUX_HOST1X_H
@@ -68,6 +68,7 @@ static inline void host1x_bo_cache_destroy(struct host1x_bo_cache *cache)
* @late_exit: host1x client late tear down code
* @suspend: host1x client suspend code
* @resume: host1x client resume code
* @get_rate: host1x client get clock rate code
*/
struct host1x_client_ops {
int (*early_init)(struct host1x_client *client);
@@ -76,8 +77,11 @@ struct host1x_client_ops {
int (*late_exit)(struct host1x_client *client);
int (*suspend)(struct host1x_client *client);
int (*resume)(struct host1x_client *client);
unsigned long (*get_rate)(struct host1x_client *client);
};
struct host1x_actmon;
/**
* struct host1x_client - host1x client structure
* @list: list node for the host1x client
@@ -93,6 +97,7 @@ struct host1x_client_ops {
* @usecount: reference count for this structure
* @lock: mutex for mutually exclusive concurrency
* @cache: host1x buffer object cache
* @actmon: unit actmon for this client
*/
struct host1x_client {
struct list_head list;
@@ -113,6 +118,8 @@ struct host1x_client {
struct mutex lock;
struct host1x_bo_cache cache;
struct host1x_actmon *actmon;
};
/*
@@ -507,5 +514,10 @@ static inline void host1x_memory_context_put(struct host1x_memory_context *cd)
#endif
int host1x_actmon_read_avg_count(struct host1x_client *client);
int host1x_actmon_register(struct host1x_client *client);
int host1x_actmon_unregister(struct host1x_client *client);
void host1x_actmon_update_client_rate(struct host1x_client *client,
unsigned long rate,
u32 *weight);
#endif