mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: Add sysfs node for taking static PG config
- Add sysfs node for GPC, TPC and FBP mask values - Add the following nodes: gpc_pg_mask tpc_pg_mask fbp_pg_mask to allow userspace to pass static pg config values Bug 200768322 JIRA NVGPU-6433 Change-Id: I072cd2cad65bfb389c2164f1450ac1ab5bcad064 Signed-off-by: Divya <dsinghatwari@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2594803 Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -836,6 +836,58 @@ static ssize_t force_idle_read(struct device *dev,
|
|||||||
static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store);
|
static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NVGPU_STATIC_POWERGATE
|
||||||
|
static ssize_t gpc_pg_mask_read(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
|
||||||
|
return snprintf(buf, NVGPU_CPU_PAGE_SIZE, "%d", g->gpc_pg_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t gpc_pg_mask_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||||
|
unsigned long val = 0;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
nvgpu_mutex_acquire(&g->static_pg_lock);
|
||||||
|
|
||||||
|
if (kstrtoul(buf, 10, &val) < 0) {
|
||||||
|
nvgpu_err(g, "invalid value");
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvgpu_is_powered_on(g)) {
|
||||||
|
nvgpu_err(g, "gpu already powered on");
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val == g->gpc_pg_mask) {
|
||||||
|
nvgpu_info(g, "no value change, same mask already set");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platform->set_gpc_pg_mask != NULL) {
|
||||||
|
err = platform->set_gpc_pg_mask(dev, val);
|
||||||
|
if (err != 0) {
|
||||||
|
nvgpu_err(g, "GPC-PG mask is invalid");
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(gpc_pg_mask, ROOTRW, gpc_pg_mask_read, gpc_pg_mask_store);
|
||||||
|
#endif
|
||||||
|
|
||||||
static ssize_t gpc_fs_mask_show(struct device *dev,
|
static ssize_t gpc_fs_mask_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
@@ -857,6 +909,58 @@ static ssize_t gpc_fs_mask_show(struct device *dev,
|
|||||||
|
|
||||||
static DEVICE_ATTR_RO(gpc_fs_mask);
|
static DEVICE_ATTR_RO(gpc_fs_mask);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NVGPU_STATIC_POWERGATE
|
||||||
|
static ssize_t fbp_pg_mask_read(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
|
||||||
|
return snprintf(buf, NVGPU_CPU_PAGE_SIZE, "%d", g->fbp_pg_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t fbp_pg_mask_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||||
|
unsigned long val = 0;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
nvgpu_mutex_acquire(&g->static_pg_lock);
|
||||||
|
|
||||||
|
if (kstrtoul(buf, 10, &val) < 0) {
|
||||||
|
nvgpu_err(g, "invalid user given FBP-PG mask");
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvgpu_is_powered_on(g)) {
|
||||||
|
nvgpu_err(g, "gpu is already powered on");
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val == g->fbp_pg_mask) {
|
||||||
|
nvgpu_info(g, "no value change, same mask already set");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platform->set_fbp_pg_mask != NULL) {
|
||||||
|
err = platform->set_fbp_pg_mask(dev, val);
|
||||||
|
if (err != 0) {
|
||||||
|
nvgpu_err(g, "FBP-PG mask is invalid");
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(fbp_pg_mask, ROOTRW, fbp_pg_mask_read, fbp_pg_mask_store);
|
||||||
|
#endif
|
||||||
|
|
||||||
static ssize_t fbp_fs_mask_show(struct device *dev,
|
static ssize_t fbp_fs_mask_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
@@ -879,35 +983,29 @@ static ssize_t fbp_fs_mask_show(struct device *dev,
|
|||||||
static DEVICE_ATTR_RO(fbp_fs_mask);
|
static DEVICE_ATTR_RO(fbp_fs_mask);
|
||||||
|
|
||||||
#ifdef CONFIG_NVGPU_STATIC_POWERGATE
|
#ifdef CONFIG_NVGPU_STATIC_POWERGATE
|
||||||
static bool is_tpc_mask_valid(struct gk20a *g, u32 tpc_mask)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
bool valid = false;
|
|
||||||
|
|
||||||
for (i = 0U; i < MAX_PG_TPC_CONFIGS; i++) {
|
|
||||||
if (tpc_mask == g->valid_tpc_pg_mask[i]) {
|
|
||||||
valid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t tpc_pg_mask_read(struct device *dev,
|
static ssize_t tpc_pg_mask_read(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct gk20a *g = get_gk20a(dev);
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
u32 i;
|
||||||
|
/* hold the combined tpc pg mask */
|
||||||
|
u32 combined_tpc_pg_mask = 0x0U;
|
||||||
|
|
||||||
return snprintf(buf, NVGPU_CPU_PAGE_SIZE, "%d\n",
|
for (i = 0U; i < MAX_PG_GPC; i++) {
|
||||||
g->tpc_pg_mask[PG_GPC0]);
|
combined_tpc_pg_mask = combined_tpc_pg_mask |
|
||||||
|
(g->tpc_pg_mask[i] << 4*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return snprintf(buf, NVGPU_CPU_PAGE_SIZE, "%d", combined_tpc_pg_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t tpc_pg_mask_store(struct device *dev,
|
static ssize_t tpc_pg_mask_store(struct device *dev,
|
||||||
struct device_attribute *attr, const char *buf, size_t count)
|
struct device_attribute *attr, const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct gk20a *g = get_gk20a(dev);
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||||
unsigned long val = 0;
|
unsigned long val = 0;
|
||||||
struct nvgpu_gr_obj_ctx_golden_image *gr_golden_image = NULL;
|
int err = 0;
|
||||||
|
|
||||||
nvgpu_mutex_acquire(&g->static_pg_lock);
|
nvgpu_mutex_acquire(&g->static_pg_lock);
|
||||||
|
|
||||||
@@ -917,35 +1015,21 @@ static ssize_t tpc_pg_mask_store(struct device *dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val == g->tpc_pg_mask[PG_GPC0]) {
|
if (nvgpu_is_powered_on(g)) {
|
||||||
nvgpu_info(g, "no value change, same mask already set");
|
nvgpu_err(g, "gpu is already powered on");
|
||||||
goto exit;
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
err = -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g->gr != NULL) {
|
if (platform->set_tpc_pg_mask != NULL) {
|
||||||
gr_golden_image = nvgpu_gr_get_golden_image_ptr(g);
|
err = platform->set_tpc_pg_mask(dev, val);
|
||||||
|
if (err != 0) {
|
||||||
|
nvgpu_err(g, "TPC-PG mask is invalid");
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gr_golden_image &&
|
|
||||||
nvgpu_gr_obj_ctx_get_golden_image_size(gr_golden_image)
|
|
||||||
!= 0) {
|
|
||||||
nvgpu_err(g, "golden image size already initialized");
|
|
||||||
nvgpu_mutex_release(&g->static_pg_lock);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
/* checking that the value from userspace is within
|
|
||||||
* the possible valid TPC configurations.
|
|
||||||
*/
|
|
||||||
if (is_tpc_mask_valid(g, (u32)val)) {
|
|
||||||
g->tpc_pg_mask[PG_GPC0] = val;
|
|
||||||
} else {
|
|
||||||
nvgpu_err(g, "TPC-PG mask is invalid");
|
|
||||||
nvgpu_mutex_release(&g->static_pg_lock);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
exit:
|
|
||||||
nvgpu_mutex_release(&g->static_pg_lock);
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1238,7 +1322,9 @@ void nvgpu_remove_sysfs(struct device *dev)
|
|||||||
device_remove_file(dev, &dev_attr_tpc_fs_mask);
|
device_remove_file(dev, &dev_attr_tpc_fs_mask);
|
||||||
device_remove_file(dev, &dev_attr_tpc_pg_mask);
|
device_remove_file(dev, &dev_attr_tpc_pg_mask);
|
||||||
device_remove_file(dev, &dev_attr_gpc_fs_mask);
|
device_remove_file(dev, &dev_attr_gpc_fs_mask);
|
||||||
|
device_remove_file(dev, &dev_attr_gpc_pg_mask);
|
||||||
device_remove_file(dev, &dev_attr_fbp_fs_mask);
|
device_remove_file(dev, &dev_attr_fbp_fs_mask);
|
||||||
|
device_remove_file(dev, &dev_attr_fbp_pg_mask);
|
||||||
device_remove_file(dev, &dev_attr_tsg_timeslice_min_us);
|
device_remove_file(dev, &dev_attr_tsg_timeslice_min_us);
|
||||||
device_remove_file(dev, &dev_attr_tsg_timeslice_max_us);
|
device_remove_file(dev, &dev_attr_tsg_timeslice_max_us);
|
||||||
|
|
||||||
@@ -1303,7 +1389,9 @@ int nvgpu_create_sysfs(struct device *dev)
|
|||||||
error |= device_create_file(dev, &dev_attr_tpc_fs_mask);
|
error |= device_create_file(dev, &dev_attr_tpc_fs_mask);
|
||||||
error |= device_create_file(dev, &dev_attr_tpc_pg_mask);
|
error |= device_create_file(dev, &dev_attr_tpc_pg_mask);
|
||||||
error |= device_create_file(dev, &dev_attr_gpc_fs_mask);
|
error |= device_create_file(dev, &dev_attr_gpc_fs_mask);
|
||||||
|
error |= device_create_file(dev, &dev_attr_gpc_pg_mask);
|
||||||
error |= device_create_file(dev, &dev_attr_fbp_fs_mask);
|
error |= device_create_file(dev, &dev_attr_fbp_fs_mask);
|
||||||
|
error |= device_create_file(dev, &dev_attr_fbp_pg_mask);
|
||||||
error |= device_create_file(dev, &dev_attr_tsg_timeslice_min_us);
|
error |= device_create_file(dev, &dev_attr_tsg_timeslice_min_us);
|
||||||
error |= device_create_file(dev, &dev_attr_tsg_timeslice_max_us);
|
error |= device_create_file(dev, &dev_attr_tsg_timeslice_max_us);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user